attiny13 radio2

Иногда в системах умного дома применяя беспроводные технологии не имеет смысла использовать сложные и дорогие модули, например те же NRF24LE1 или NRF24L01+М/К, если необходима только односторонняя связь, например для передачи показаний датчиков влажности или/и температуры- в этом случае можно использовать очень простые решения на базе дешевого микроконтроллера attiny13 и  радиомодуля 433 или 315 мгц.

Ниже будет рассказан пример использования датчиков, которые описаны в конструкторе прошивки и статье алгоритма беспроводных датчиков.

 

Ethernet сервер-приёмник на базе Arduino

 
#include <RCSwitch.h>
#include <Ethernet.h>
#include <SPI.h>
#include <Arduino.h>
#include "WebServer.h"

RCSwitch mySwitch = RCSwitch();
unsigned long valueold;


char buf[60]; //буфер для отправки данных. 

byte ip[] = { 192, 168, 1, 10 }; // локальный адрес
byte rserver[] = { 192, 168, 1, 20 };  // ip-адрес удалённого сервера


byte mac[] = { 0xDE, 0xAD, 0xBE, 0x54, 0xDE, 0x33 }; // MAC-адрес нашего устройства
byte subnet[] = { 255, 255, 255, 0 };
byte gateway[] = { 192, 168, 1,1 };
byte dns_server[] = { 192, 168, 1, 1};

#define VERSION_STRING "Radio server"

P(Page_info) = "<html><head><title>controller " VERSION_STRING "</title></head><body>\n";
P(location_info) = "server room";
P(version_info) = VERSION_STRING ". Compile date: " __DATE__ " " __TIME__;

String url = String(25);


#define MAX_COMMAND_LEN             (10)
#define MAX_PARAMETER_LEN           (10)
#define COMMAND_TABLE_SIZE          (8)
#define PREFIX ""

WebServer webserver(PREFIX, 80);
EthernetClient client;


#define NAMELEN 32
#define VALUELEN 32

char gCommandBuffer[MAX_COMMAND_LEN + 1];
char gParamBuffer[MAX_PARAMETER_LEN + 1];
long gParamValue;

typedef struct {
  char const    *name;
  void          (*function)(WebServer &server);
} command_t;


void infoRequest(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
  server.printP(Page_info);
  server.print("IP:");
  server.print(Ethernet.localIP());
  server.print("<br>Location:");
  server.printP(location_info);
}

void setup() {
  Ethernet.begin(mac, ip, dns_server, gateway, subnet); // Инициализируем Ethernet Shield

  webserver.setDefaultCommand(&infoRequest); // дефолтная страница
  webserver.begin();
  mySwitch.enableReceive(0); // включаем прием на 2 выводе (прерывание 0)
}

bool ledA=0,ledB=0,ledC=0,ledD=0;
long statesend = 0; 

void loop() {
  
  char buff[64];
  int len = 64;
  webserver.processConnection(buff, &len);  // process incoming connections one at a time forever
  
unsigned long currentMillis = millis(); // текущий счетчик

  if (mySwitch.available()) {
unsigned long valuesend = mySwitch.getReceivedValue();

#if 0 // прием команд с радиопультов, выключено ! При использовании не забудьте про установку пина режим на выход..
if ((unsigned int)valuesend==21952){ // A

if (currentMillis-statesend>1000){
   statesend=currentMillis;
    ledA=!ledA;
    sendstate(5,ledA);
}
  
} else 
if ((unsigned int)valuesend==21808){ // B

if (currentMillis-statesend>1000){
   statesend=currentMillis;
    ledB=!ledB;
    sendstate(6,ledB);
}
  
} else 
if ((unsigned int)valuesend==21772){ // C

if (currentMillis-statesend>1000){
   statesend=currentMillis;
    ledC=!ledC;
    sendstate(7,ledC);
}
} else 
if ((unsigned int)valuesend==21763){ // D

if (currentMillis-statesend>1000){
   statesend=currentMillis;
    ledD=!ledD;
    sendstate(8,ledD);
}
  
} else
#endif
 
 // отправка принятых данных с беспроводных датчиков и отправка их на сервер.
  if (valuesend != 0 && valueold !=valuesend) 
 {
   valueold=valuesend;
        if (client.connect(rserver, 80)) {
       sprintf (buf,"GET /server.php?mode=rcskey&n=%hu HTTP/1.0",valuesend);
       
   client.println(buf);
       client.println("Host: local.ru");
    client.println();
  }  //else Serial.println("connection failed");
client.stop();
    
    
  }
  mySwitch.resetAvailable();
  }

}

void sendstate (int pin,int mode){ // управление нагрузками с пульта с отправкой статуса на сервер
  digitalWrite(pin,mode);
  
              if (client.connect(rserver, 80)) {
      sprintf(buf, "GET /server.php?mode=key&n=%i&s=%i  HTTP/1.0", pin, mode);
     client.println(buf);  
       client.println("Host: local.ru"); 
    client.println();
  } 
    client.stop();
}

 

 

 

Данный код принимает сигналы с беспроводных датчиков, а так же с радиопультов.
Приемник должен быть подключен к 2 выводу ардуины.
Можно аналогично реализовать и без ethernet, используя последовательный порт.

Обработка принятых данных на сервере

При приеме данных с беспроводных датчиков они пересылаются на компьютер, на котором должен быть запущен веб сервер с поддержкой PHP. Arduina обращается к скрипту server.php, который обрабатывает и заносит данные с датчиков в базу данных.

 

CREATE TABLE IF NOT EXISTS `logsensors` (
`sensor` varchar(16) NOT NULL,
`val` varchar(12) NOT NULL,
`dtm` varchar(20) NOT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=1029966 ;

CREATE TABLE IF NOT EXISTS `sensors` (
`idd` varchar(16) NOT NULL, -- ид датчика
`name` varchar(35) NOT NULL, -- имя датчика
`type` varchar(3) NOT NULL, -- тип данных:
`val` varchar(12) NOT NULL, --текущие данные датчика
`dtm` varchar(20) NOT NULL, --дата и время
`enable` int(1) NOT NULL, -- датчик разрешен
`logenable` int(1) NOT NULL, -- разрешить логи сенсоров
`hidden` varchar(3) NOT NULL,
`period` int(2) NOT NULL DEFAULT '5', -- период записи в базу в минутах
`radiost` int(1) NOT NULL -- статус датчика:1-не работает(таймаут),0 - работает
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;

INSERT INTO `sensors` (`idd`, `name`, `type`, `val`, `dtm`, `enable`, `logenable`, `hidden`, `period`, `key`, `radiost`) VALUES
( '11000', 'С/У радио', 'T', '22.3', '2014-09-09 13:20:15', 1, 1, 0, 5, 0, 1),
( '12000', 'Кухня', 'T', '20', '2014-09-09 13:21:16', 1, 1, 0, 5, 0, 1);

 
 
<?php
// не забудьте задать параметры подключения к БД.
$link = mysql_connect($dbhost, $dbuser, $dbpassword);
mysql_select_db($dbname, $link);

$dtm=date('Y-m-d H:i:s');

$mode = $_GET['mode'];

if ($mode=="key") { // команда от радиопульта

$state=$_GET['s'];
$pin=$_GET['n'];
mysql_query ("UPDATE  `kkeys` SET `state` = '$state'  WHERE  `idd` = '$pin'");

}else  if ($mode=="rcskey") { // команды от беспроводных датчиков

$receivedCode=$_GET['n'];

$m = mysql_query ("SELECT * FROM sensors  WHERE mode LIKE '1'");

for ($c=0;$c<mysql_num_rows($m); $c++) {
$fe = mysql_fetch_array($m);

if ($fe[idd]<=$receivedCode && $fe[idd]+1024>$receivedCode) {

if ($fe[type]=="H") $tdata=($receivedCode-$fe[idd])/10; // прием влажности
else if ($fe[type]=="T") $tdata=($receivedCode-$fe[idd]-500)/10; // прием температуры
else $tdata=$receivedCode-$fe[idd]; // прием просто число, например от аналогового датчика

mysql_query ("UPDATE  `sensors` SET `val` = '$tdata',`dtm` = '$dtm',`radiost` = '1'  WHERE  `idd` = '$fe[idd]'");

							     }

				      }
			}
 

Для того чтобы записывать статистику температуры необходимо скрипт ниже вписать в планировщик на каждые 5 минут:

 

 
<?php
// не забудьте задать параметры подключения к БД.
$link = mysql_connect($dbhost, $dbuser, $dbpassword);
mysql_select_db($dbname, $link);

$m = mysql_query ("SELECT * FROM sensors  WHERE mode LIKE '1' AND logenable LIKE '1' AND radiost LIKE '1'");

for ($c=0;$c<mysql_num_rows($m); $c++) {
$p = mysql_fetch_array($m);

$res=date('i')/$p[period];
// заносим в БД ,только если датчик обновлялся за последний период времени.
if (round($res)==$res) mysql_query("insert into logsensors (sensor,val,dtm) values('$p[idd]','$p[val]','$p[dtm]')");

mysql_query ("UPDATE  `sensors` SET `radiost` = '0'  WHERE  `idd` = '$p[idd]'");
}
 

 

Периодичность записи в базу статистики зависит от времени, установленное в столбце period в таблице sensors.

Исходные коды выше предоставлены в качестве примеров, на самом же деле дома работает система с бОльшими функциями, в которой так же имеются и проводные датчики и прочее… Веб интерфейс управления «умным домом» у меня свой, но показывать там пока не чего -его даже сложно назвать «умным домом». Данные примеры можно интегрировать в систему MajorDoMo или же написать свою.

В данный момент у меня в работе 2 беспроводных датчика температуры, которые передают так же данные с входа АЦП( в будущем АЦП будет использоваться для датчика протечки). Датчики, а так же пульт работают на частоте 315мгц.

Преимущества и недостатки

Преимущества данного решения:
-Дешево. Примерно 3 $ за всю схему на базе DS18B20 (по ценам ebay). 
-Схема очень простая.
-Достаточно продолжительная работа от батарей.
-Можно использовать этот же канал для управления через радиопульт.

Недостатки:
-Нет шифрования, а зачем ?..
-Дальность не такая уж большая, но достаточна, если у вас не дворец..

Home`s Smart © 2013-2016. г.Киров.
Цитирование материалов возможно только со ссылкой на сайт. Использование фотоматериалов только с разрешения авторов.