Облако тегов

Глобус

Навигация

Вход на сайт

  • Войти с Twitter

Беспроводные датчики температуры для narodmon.ru (Arduino pro mini + nRF24L01)

В прошлой статье я рассказал как подключить свои погодные датчики к сервису narodmon.ru (Подключение Arduino Pro Mini + Enc28j60 + DHT11 + DS18B20 к сервису narodmon.ru) и обещал написать о возможности подключения  датчиков  по радиоканалу.

Для этого нам понадобится

1. Прошлая сборка Arduino Pro Mini + Enc28j60 (уже без датчиков ). Это будет станция, принимающая показания по радио и передаюющая их в интернет.

2. Еще одна Arduino  Pro Mini 3.3v для чтения показания температуры  и предачи по радио на принимающую станцию.

 

3.  Датчик  температуры  для улицы DS18B20:

4. Два радиомодуля  nRF24L01 :

Один радиомодуль подключим к приемнику, второй к передатчику. Как собран приемник можно посмотреть в предыдущей статье Enc28j60 + DHT11 + DS18B20 к сервису narodmon.ru. Датчик   температуры  по тому же примеру подключим через резистор к выходу 4 передатчика.

Для соединения  nRF24L01  и Arduino Pro Mini воспользуемся следующей таблицой:

 Arduino  Pro Mini nRF24L01
2 IRQ
7 CE
8 CS
11 MOSI
12 MISO
13 SCK
GND GND
VCC VCC 3.3v

 

 

 

 

 

 

 

Для наглядности, две картинки с распиновкой:

Arduino   Pro  \ Mini :

 

 nRF24L01 :

Три момента:

1. Радиомодуль питается от 3 вольт, поэтому я использовал версию Arduino Pro Mini с питанием от 3.3 вольт. Если у вас ардуина пятивольтовая и не имеет встроенного регулятора на 3.3 вольта, необходимо подключать радиомодуль к VCC через регулятор. Остальные пины, можно подключать напрямую, так как судя по даташиту на радиомодуль, его сигнальные пины толерантны к напряжению 5 вольт.

2. Пины SC и CE пожно подключить и к другим свободным цифровым пинам Arduino Pro MIni. Их значения потом определяются в скетче. Для моего случа будет написано

radio.begin(7,8);

3. Пин IRQ подключать не обязательно. Я его подключил к пину 2, на котором у  Arduino  Pro Mini есть обработчик прерываний. Его будем использовать для пробуждения радиомодуля из режима сна, в который будем погружать его для экономии питания.

Подсоединим по этой схеме радиомодули к принимающей и отправляющей ардуинам.

 

Теперь скетчи.

Для работы c радиомодулями nRF24L01 есть библиотека NRF24 и ее расширение для построения связанных mesh сетей без ограничения на количество устройств NRF24Network. Воспользуемся второй библиотекой.
Для работы с ethernet модулем библиотеку возьмите из предыдущей статьи.

Ремарка, из прошлой статьи:

Обратите внимание, что необходимо указать уникальный MAC адрес сетевого интерфейса, по нему сервис narodmon.ru будет идентифицировать ваше устройство и ip адрес и порт сайта narodmon.ru). По правилам narodmon.ru запрещается публиковать реквизиты на сторонних ресурсах. Посмотреть их можно тут:  В скетче адрес изменен.

Если при подключении радио, использовались другие пины CE и CS, укажите это в обоих скетчах в строке:

RF24 radio(7,8);

 

Теперь скетчи. Помимо них требуются библиотеки и еще неколько файлов. Поэтому скачать лучше сразу архивы в конце статьи.

Скетч погодного  датчика  (передающий модуль):

/*
 Copyright (C) 2011 James Coliz, Jr. <maniacbug@ymail.com>

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 version 2 as published by the Free Software Foundation.
 */
 
 
#include <OneWire.h>
#include <DallasTemperature.h>

#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#include "nodeconfig.h"
#include "sleep.h"

#define ONE_WIRE_BUS 5                             // Data wire is plugged into digital pin 3 on the Arduino
#define NumberOfDevices 8                          // Set maximum number of devices in order to dimension

OneWire oneWire(ONE_WIRE_BUS);                     // Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);               // Pass our oneWire reference to Dallas Temperature.
byte allAddress [NumberOfDevices][8];              // Device Addresses are 8-element byte arrays.
char sn[NumberOfDevices][35];
byte totalDevices;                                 // Declare variable to store number of One Wire devices
                                                   // that are actually discovered.
byte discoverOneWireDevices() {
  byte j=0;                                        // search for one wire devices and
                                                   // copy to device address arrays.
  while ((j < NumberOfDevices) && (oneWire.search(allAddress[j]))) {        
    j++;
  }
   return j                      ;                 // return total number of devices found.
}

typedef struct{
  char Type[3];
  float Value;         // значение 4bytes
  boolean Status;      // статус - 0-ошибка (false), 1-ок (true) 1byte
  char Note[24];       // комментарий
}ModuleInfo;

ModuleInfo mi[NumberOfDevices+2];

#define home_net_channel 95
RF24 radio(7,8);
RF24Network network(radio);

// Our node address
uint16_t this_node;

// Sleep constants.  In this example, the watchdog timer wakes up
// every 1s, and every 4th wakeup we power up the radio and send
// a reading.  In real use, these numbers which be much higher.
// Try wdt_8s and 7 cycles for one reading per minute.> 1
const wdt_prescalar_e wdt_prescalar = wdt_8s;
const short sleep_cycles_per_transmission = 32;

void setup(void)
{
  Serial.begin(57600);
  sensors.begin();
  totalDevices = discoverOneWireDevices();

  for (byte i=0; i < totalDevices; i++)
  {
    sn[i][0]=0;
    for(int k=7;k>=0;k--)
    {
          char msg[3];
          sprintf(msg,"%02X",allAddress[i][k]);
          strcat(sn[i],msg);
          //DSstring[i]+=msg;
    };
          
    sensors.setResolution(allAddress[i], 10);      // and set the a to d conversion resolution of each.
  }
  this_node=1;
 
  if ( this_node > 0 )
  Sleep.begin(wdt_prescalar,sleep_cycles_per_transmission);

  SPI.begin();
  radio.begin();
  network.begin(/*channel*/ 95, /*node address*/ this_node);
}

void loop(void)
{
  // Pump the network regularly
  network.update();

  // If we are not the base, send sensor readings to the base
  if ( this_node > 0 )
  {
      sensors.requestTemperatures();
      for (byte i=0; i < totalDevices; i++)
      {
        float tempC = sensors.getTempC(allAddress[i]);
        
        strcpy(mi[i].Type,"T");
        char msg[2];
        sprintf(msg,"%d",i+1);
        strcat(mi[i].Type,msg);
        strcpy(mi[i].Note,sn[i]);

        if (tempC != -127.00)
        {
          mi[i].Value=tempC;
          mi[i].Status=true;
        }
        else
          mi[i].Status=false;
      }
      
      for (byte i=0; i < totalDevices; i++)
      {
        if (mi[i].Status)
        {
          RF24NetworkHeader header(/*to node*/ 0, /*type*/ 'Sensor');
          bool ok = network.write(header,&mi[i],sizeof(mi[i]));
          Serial.print("Sending: Type=");         
          Serial.print(mi[i].Type);
          Serial.print(", Value=");
          Serial.print(mi[i].Value);
          Serial.print(", Status=");
          Serial.print(mi[i].Status);
          Serial.print(", Note=");
          Serial.print(mi[i].Note);
          Serial.print("\n");
        }
        else Serial.println("Error from sensor");
    }

    // Power down the radio.  Note that the radio will get powered back up
    // on the next write() call.
    radio.powerDown();
    // Sleep the MCU.  The watchdog timer will awaken in a short while, and
    // continue execution here.
    Sleep.go();
    // Listen for a new node address
    nodeconfig_listen();
  }
}

 

Скетч погодной станции (принимающий показания модуль и отправляющий их на narodmon.ru)

/*
 Copyright (C) 2011 James Coliz, Jr. <maniacbug@ymail.com>

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 version 2 as published by the Free Software Foundation.
 */

#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#include "nodeconfig.h"
#include <EtherCard.h>

byte Ethernet::buffer[700];
Stash stash;  
static byte mac[] = { 0xE0, 0xCB, 0x11, 0xFF, 0x44, 0x77 }; //В этой строке задайте свой MAC адрес
static byte hisip[] = { 99,99,99,99,8080 };//Здесь надо указать IP адрес сайта narodmon.ru

char macstring[13];

typedef struct{
  char Type[3];
  float Value;         // значение 4bytes
  boolean Status;      // статус - 0-ошибка (false), 1-ок (true) 1byte
  char Note[24];       // комментарий
}ModuleInfo;
ModuleInfo mi;

RF24 radio(7,8);
RF24Network network(radio);
#define home_net_channel 95

// Our node address
uint16_t this_node;

void setup(void)
{
  Serial.begin(57600);
  Serial.println("Start");

  //Base station will allways get node nuber = 0
  this_node = 0;
  //
  // Bring up the RF network
  //
  SPI.begin();
  radio.begin();
  network.begin(/*channel*/ home_net_channel, /*node address*/ this_node);

  for(int k=0;k<sizeof(mac)/sizeof(byte);k++)
  {
        char msg[3];
        sprintf(msg,"%02X",mac[k]);
        strcat(macstring,msg);
  }    
  Serial.print("MAC=");
  Serial.println(macstring);
  if (ether.begin(sizeof Ethernet::buffer, mac, SS) == 0)
    Serial.println( "Failed to access Ethernet controller");

  if (!ether.dhcpSetup())
    Serial.println("DHCP failed");
    
  //overwrite DNS with google's if there are problems with DNS setup
  static byte dnsip[] = {8,8,8,8};
  ether.copyIp(ether.dnsip, dnsip);
 
  ether.printIp("My IP: ", ether.myip);
  ether.printIp("GW IP: ", ether.gwip);
  ether.printIp("DNS IP: ", ether.dnsip);

  ether.copyIp(ether.hisip, hisip);
  ether.printIp("Server: ", ether.hisip);

  while (ether.clientWaitingGw())
    ether.packetLoop(ether.packetReceive());
  Serial.println("Gateway found");
  Serial.println("Ready for recieving data...");

}

void loop(void)
{
  // Pump the network regularly
  network.update();
  ether.packetLoop(ether.packetReceive());

  while ( network.available() )
  {
    // If so, grab it and print it out
    RF24NetworkHeader header;
    network.read(header,&mi,sizeof(mi));
 
    Serial.print("Recieved ID=");
    Serial.print(macstring);
    Serial.print(", Type=");         
    Serial.print(mi.Type);
    Serial.print(", Value=");
    Serial.print(mi.Value);
    Serial.print(", Status=");
    Serial.print(mi.Status);
    Serial.print(", Note=");
    Serial.print(mi.Note);
    Serial.print("\n"  );

    if ((mi.Status) && (tolower(mi.Type[0])=='t'))
    {
      Serial.print("Sending ID=");
      Serial.print(macstring);
      Serial.print("&");
      Serial.print(mi.Note);
      Serial.print("=");
      Serial.print(mi.Value);
      Serial.print("\n");
 
      byte sd = stash.create();

      stash.print("ID=");
      stash.print(macstring);
      
      stash.print("&");
      stash.print(mi.Note);
      stash.print("=");
      stash.print(mi.Value);
      
      stash.save();
 
      // generate the header with payload - note that the stash size is used,
      // and that a "stash descriptor" is passed in as argument using "$H"
      Stash::prepare(PSTR("POST http://narodmon.ru/post.php HTTP/1.0" "\r\n"
                          "Host: narodmon.ru" "\r\n"
                          "Content-Length: $D" "\r\n"
                          "\r\n"
                          "$H"),
                    stash.size(), sd);
 
      // send the packet - this also releases all stash buffers once done
      ether.tcpSend();
    }
  }
  // Listen for a new node address
  nodeconfig_listen();
}

 

 

Полностью файлы скетчей и библиотеки можно скачать в прикрепленных к статье архивах.

 

 

Комментарии

qweqwe

qweqwe

Спасибо огромное, все отлично работает!

Спасибо огромное! Все работает отлично. А вы не планируете додобавить еще датчики, dht, например?

Добавлять сюда не планирую. Сейчас перевел весь свет на zwave. А датчики и сенсоры к нему на Arduino. Тепер инфо на народмон частично шлется из контроллера zwave. Точнее данные берутся с контроллера, а отправляет домашниц сервер. Это отдельная тема. У кого уже есть сеть zwave с контроллером Vera Light, могут интегрировать проекты на ардуино в нее. Это отдельная большая тема. Пишите, кому интересно, расскажу.

А куда пропала статья? Остались только заголовок и файлы для скачки  .

Статья побилась, попробую восстановить!

Спасибо!

Восстановил статью!

Спасибо!

Пока на стадии планирования... Дом из кирпича и довольно таки большой. По этому вопрос: радиус действия передатчика? К примеру блютуз соседние комнаты проблематично.

Не могу сказать как будет в бетонном доме. Посмотрите проект mysensors.com. Там помимо основного модуля собирающего данные, есть relay-модули для увеличения дальности.

Добавить комментарий