Расмотрим пример работы для считывания беспроводных модулей на базе nRF24L01 и nRF24LE1 используя Arduino

Необходимые библиотеки можно найти на страничках Ethernet модуля и nRF24L01.

Команда для отправки данных на радиомодули:

http://IP_adress/command?chselect=1&val1=11&val2=2&val3=0

Что значит отправить данные val1..val3 на клиента номер 1. Переменная chselect (номер радиомодуля) должна быть всегда первой в строке запроса.

В отличии от nRF24L01+USB массив для отправки может быть больше.

Параметры радиоканала указанные в функции setup должны быть такие же как на клиентах !!

Посмотреть состояние данных можно на страничке http://IP_adress/state

Данный код можно интегрировать в уже действующий контроллер умного дома на базе Ethernet шилда W5100 .

Обновление  23.10.2014 !! Переделан алгоритм режимов прием/передача. Сейчас шлюз все время слушает, а передает клиентам только если есть что !

Разработан шлюз на базе ESP8266 , который "из коробки" работает с несколькими LO1 или LE1 клиентами. Данные с датчиков можно легко принять и отправить.

Код шлюза:

#include <Ethernet.h>
#include <SPI.h>
#include <Arduino.h>
#include "WebServer.h"
#include "nRF24L01.h"
#include "RF24.h"

#define ch_len 32
byte nfserver[4]; // массив для отправки

// вариант структуры номер 1
typedef struct{
  uint8_t identifier;// номер передатчика.МЕНЯТЬ НЕЛЬЗЯ

  int Analog;
  uint8_t test_data;
//  int Error_Message; // счетчик ошибок
  long count;// счетчик передач для контроля качества канала
#if nofloat
int temperature_Sensor; //передаём температуру.
int Humidity_Sensor;// передаём влажность
#else
 float temperature_Sensor;// передаём температуру.
 float Humidity_Sensor;// передаём влажность
#endif
}
nf1;
// вариант структуры номер 2
typedef struct{
  uint8_t identifier;// номер передатчика.МЕНЯТЬ НЕЛЬЗЯ
  int Analog;
//  int Error_Message; // счетчик ошибок
  long count;// счетчик передач для контроля качества канала
}
nf3;
// задаем каждому клиенту структуру:
nf1 clientnf1; 
nf1 clientnf2;
nf3 clientnf3;


RF24 radio(46,53); // для Arduino MEGA
// RF24 radio(9,8); // Для остальных
//--
// настройка IP адрес ,шлюз,DNS:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xE4, 0xDE, 0x33 }; // MAC-адрес нашего устройства
byte ip[] = { 192, 168, 10, 170 };
byte subnet[] = { 255, 255, 255, 0 };
byte gateway[] = { 192, 168, 10,1 };
byte dns_server[] = { 192, 168, 1, 1};
// ip-адрес удалённого сервера
byte rserver[] = { 192, 168, 1, 154 };

#define VERSION_STRING "0.1"

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);
int maxLength=25; // Максимальная длинна строки запроса

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

WebServer webserver(PREFIX, 80);

#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;

command_t const gCommandTable[COMMAND_TABLE_SIZE] = { // таблица команд

  {"cmdnrf",     cmdnrf, },
  {"cmdnrfoff",     cmdnrfoff, },
  {"cmdnrfon",     cmdnrfon, },
  {"chselect",chselect, },
  {"val1",     val1, },
  {"val2",     val2, },
  {"val3",     val3, },
//  {"val4",     val4, },

//  {NULL,      NULL }
};
//------Заполнение массива для отправки--------
void chselect(WebServer &server) {nfserver[0]=gParamValue;} // сохраняем в массив номер клиента
void val1    (WebServer &server) {nfserver[1]=gParamValue;} // id команды
void val2    (WebServer &server) {nfserver[2]=gParamValue;} // данные команды 1
void val3    (WebServer &server) {nfserver[3]=gParamValue;} // данные команды 2
//void val4    (WebServer &server) {nfserver[4]=gParamValue;} // данные команды ещё..


 //**********************************************************************/
void cliProcessCommand(WebServer &server)
{
  int bCommandFound = false;
  int idx;

  gParamValue = strtol(gParamBuffer, NULL, 0);  // Convert the parameter to an integer value. If the parameter is empty, gParamValue becomes 0.
  for (idx = 0; gCommandTable[idx].name != NULL; idx++) {  // Search for the command in the command table until it is found or the end of the table is reached. If the command is found, break out of the loop.
    if (strcmp(gCommandTable[idx].name, gCommandBuffer) == 0) {
      bCommandFound = true;
      break;
    }
  }

  if (bCommandFound == true) {  // Если команда найдена (в массиве команд), то выполняем ее. Если нет - игнорируем
    (*gCommandTable[idx].function)(server);
  }
  else { // Command not found
    server.print("ERROR: Command not found");
  }
}
/*******************************************************************/
/* Загрузка массива для отправки */
void sendcmd (byte ch,byte data1,byte data2,byte data3,byte data4){
/* порядок команд: номер канала,дата1(10 - управление выходами),дата2 (номер выхода) ,дата3 (состояние 1 или 0) */
  
nfserver[0]=ch;
nfserver[1]=data1;
nfserver[2]=data2;
nfserver[3]=data3;
nfserver[4]=data4; 
}

/***************************************************************************************/
/* Обработчики команд */
bool stpin1=0;
bool stpin2=0;

void cmdnrf(WebServer &server) { // пример последовательного вкл/выкл

if (gParamValue==1) {
stpin1=!stpin1;
sendcmd(1,10,0,stpin1,0);
}

if (gParamValue==2) {
stpin2=!stpin2;
sendcmd(2,10,6,stpin2,0);
}


}

void cmdnrfon(WebServer &server) { // команда на включение

if (gParamValue==1) sendcmd(1,10,0,1,0);
if (gParamValue==2) sendcmd(2,10,6,1,0);
}

void cmdnrfoff(WebServer &server) { // команда на выключение

if (gParamValue==1) sendcmd(1,10,0,0,0);
if (gParamValue==2) sendcmd(2,10,6,0,0);
}
/**********************************************************************************************************************
* Разбор запроса
**/
void parsedRequest(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
  URLPARAM_RESULT rc;
  char name[NAMELEN];
  int  name_len;
  char value[VALUELEN];
  int value_len;

  server.httpSuccess();  // this line sends the standard "we're all OK" headers back to the browser

  /* if we're handling a GET or POST, we can output our data here.
     For a HEAD request, we just stop after outputting headers. */
  if (type == WebServer::HEAD)
    return;

  if (strlen(url_tail))
    {
    while (strlen(url_tail)) // Разбор URI на составные части (выборка параметров)
      {
      rc = server.nextURLparam(&url_tail, name, NAMELEN, value, VALUELEN);
      if (rc == URLPARAM_EOS) {
  //      server.printP(Params_end);
      }
       else // Получили параметр (name) и его значение (value)
        {
        // Выполняем команды
        strcpy (gCommandBuffer, name); // параметры (значение)
        strcpy (gParamBuffer, value); // команда
        cliProcessCommand(server);
        }
      }
    }


}

// страница с данными с радиомодулей, можно убрать наименование у переменных,
//а просто разделить через точку с запятой

void stateRequest(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{

// 1 клиент
server.print("identifier:");
server.print(clientnf1.identifier);

server.print(" Analog:");
server.print(clientnf1.Analog);

server.print(" test_data:");
server.print(clientnf1.test_data);

server.print(" count:");
server.print(clientnf1.count);

//server.print(" Error_Message:");
//server.print(clientnf1.Error_Message);

server.print(" temp:");
server.print(clientnf1.temperature_Sensor);

server.print(" Humidity:");
server.println(clientnf1.Humidity_Sensor);

// 2 клиент
server.print("identifier:");
server.print(clientnf2.identifier);

server.print(" Analog:");
server.print(clientnf2.Analog);

server.print(" test_data:");
server.print(clientnf2.test_data);

server.print(" count:");
server.print(clientnf2.count);

//server.print(" Error_Message:");
//server.print(clientnf2.Error_Message);

server.print(" temp:");
server.print(clientnf2.temperature_Sensor);

server.print(" Humidity:");
server.print(clientnf2.Humidity_Sensor);
}

/*******************************************************************************************************
* Главная страница
**/
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);
  
  server.print("<hr><a href='/state'>nRF devices</a>");
  server.print("<hr>Version info: ");
  server.printP(version_info);
 
}

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

  webserver.setDefaultCommand(&infoRequest); // дефолтная страница вывода (информация о контроллере)
  webserver.addCommand("command", &parsedRequest); // команды
  webserver.addCommand("state", &stateRequest); // выдать состояния всех устройств

  webserver.begin();
  
  radio.begin();
  // выбор скорости
//  radio.setDataRate(RF24_250KBPS);
   radio.setDataRate(RF24_1MBPS);
// radio.setDataRate(RF24_2MBPS);
   
  radio.setPALevel(RF24_PA_MAX);
  radio.setChannel(100); //тут установка канала
  radio.setCRCLength(RF24_CRC_16);

// radio.setAutoAck(false); // выключить аппаратное потверждение
// radio.enableDynamicPayloads(); // разрешить Dynamic Payloads
// radio.enableAckPayload();  // разрешить AckPayload

radio.setRetries(15,15);

  radio.openWritingPipe(0xF0F0F0F0E1LL);
  radio.openReadingPipe(1,0xF0F0F0F0D2LL);
  radio.startListening();
}

void loop() {
  
  char buff[64];
  int len = 64;
  webserver.processConnection(buff, &len);  // process incoming connections one at a time forever
  

   byte pipe = 0;
   
   if ( radio.available(&pipe) ) {
  
   char tempdata[ch_len];   
    
    bool done = false;
        
    while (!done)
    {
    
done = radio.read( &tempdata, ch_len );

// смотрим первый байт где находится номер клиента и копируем в структуру для этого клиента.
switch(tempdata[0]){
case 1  :
memcpy(&clientnf1,tempdata, sizeof(clientnf1));
    break;
    
case 2   :
memcpy(&clientnf2,tempdata, sizeof(clientnf2));
    break;
    
case 3   :
memcpy(&clientnf3,tempdata, sizeof(clientnf3));
    break;
    
  }

    }

if (nfserver[0]==tempdata[0]){ // если нам ответил тот клиент,которому отправили команду, то отправляем ему данные
  
   radio.stopListening();
   
   radio.write( &nfserver, sizeof(nfserver) ); 
   
   radio.startListening();
   nfserver[0]=0; // обнуляем номер клиента.
}
  }
  
}

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