Датчик температуры для «народного мониторинга» на ESP8266

Отправка температуры с градусников DS18B20 на сайт народного мониторинга. ниже описание и исходный код из видео, ссылка на видео тут и тут.



На видео был показан модуль собранный на макетной плате, с распаянным стабилизатором LM317 для питания ESP8266. Фото его ниже.

IMG_2963 IMG_2965

 

Но позже я таки сделал печатную плату, с уже более качественным стабилизатором AMS117-3.3 и дополнительными выходами GPIO, чтобы иметь возможность наращивать функционал, подключать дополнительные датчики и тд.

IMG_2855 IMG_2862

Модуль собран без отверстий, на фото видно что разъемы PLS-5 для подключения термометра DS18B20 и колодка для подключения питания, установлены навесным монтажом, тоесть напаяны прям на дорожки платы, их следует устанавливать в отверстия.

Плату в формате .lay можно скачать тут.

Принципиальная схема модуля

esp_narodmon_chem

и свежая версия исходного кода.

// отправка данных на народмон.ру с градусника ds18b20
// для ESP8266, ver0.3

// изменена работа с градусниками, теперь работа с 18b20 при помощи библиотеки DallasTemperature
// добавленна работа с несколькоими градусниками, данные отправляются со всех подключенных 18b20
// из основного цикла убран delay

// но как и прошлая версия, оно немного глючит. 

#include <ESP8266WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>  // https://github.com/milesburton/Arduino-Temperature-Control-Library
#include <Ticker.h>


OneWire  ds(2);  // on pin 2 (a 4.7K resistor is necessary)
DallasTemperature sensors(&ds);

Ticker flipper;


const char* ssid     = "SSID";
const char* password = "PASS";

const char* host = "narodmon.ru";
const int httpPort = 8283;
 
const int interval = 10*60; // 10 минут

int tm = interval;
int deviceCount = 0;
  
void flip(){
  tm--;
//  Serial.println(tm);
}

void setup() {
  Serial.begin(115200);
  delay(10);
  sensors.begin();
  delay(10);
  deviceCount = sensors.getDeviceCount();  // узнаем количество подключенных градусников
//  sensors.getAddress(Address18b20, 0);
  sensors.setResolution(10);               // устанавливаем разрешение градусника 9, 10, 11, или 12 bit
  sensors.requestTemperatures();           // забераем температуру с градусника  
  
  Send();                                  // при включении отправляем данные
  flipper.attach(1, flip);                 // запускаем таймер
}

/// функция отправляет данные на народмон.ру
void Send() { 

     // Подключаемся к wifi
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println();                       // отправляем в Serial данные о подключении
  Serial.println("WiFi connected");  
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.print("MAC address: ");
  Serial.println(WiFi.macAddress());
  Serial.println();
  
  // подключаемся к серверу 
  Serial.print("connecting to ");
  Serial.println(host);
  
  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
     return;
  }
  
  // отправляем данные  
  Serial.println("Sending..."); 
      // заголовок
  client.print("#");
  client.print(WiFi.macAddress()); // отправляем МАС нашей ESP8266
  client.print("#");
  client.print("ESP8266"); // название устройства
//  client.print("#");
//  client.print("45.031660#39.004750"); // координаты местонахождения датчика
  client.println();

      // в цикле отправляем данные с подключенных градусников.
   for (int i = 0; i <= deviceCount - 1; i++){ 
      DeviceAddress Address18b20;
      sensors.getAddress(Address18b20, i);
      float temp = sensors.getTempC(Address18b20);
      
      client.print("#"); 
      for(int i = 0; i < 8; i++) client.print(Address18b20[i], HEX); // номер 18b20  
      client.print("#");
      client.println(temp); 
   }  
   
   client.println("##");
    
  delay(10);

  // читаем ответ с и отправляем его в сериал
  // вообще на ответ нужно както реагировать
  Serial.print("Requesting: ");  
  while(client.available()){
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }
  
  client.stop();
  Serial.println();
  Serial.println();
  Serial.println("Closing connection");

  WiFi.disconnect(); // отключаемся от сети
  Serial.println("Disconnect WiFi.");

    
}

void loop() {
 if (tm == 0){                      // если таймер отработал
    flipper.detach();                 // выключаем
    tm = interval;                    // сбрасываем переменную таймера
    sensors.requestTemperatures();    // забераем температуру с градусника 
    delay(10);   
    Send();                           // отправляем
    flipper.attach(1, flip);          // включаем прерывание по таймеру
  }  
  
 
}

Первая версия исходного кода тут

 


Отправка данных на народмон.ру и cloudmqtt с модуля BMP180\HTU21\BH1750

Тут
// отправка данных на народмон.ру и cloudmqtt с модуля BMP180\HTU21\BH1750
// для ESP8266 

#include <ESP8266WiFi.h>
#include <Wire.h> 
#include "SparkFunHTU21D.h"
#include <SFE_BMP180.h>
#include <BH1750.h>
#include <PubSubClient.h>
#include <Ticker.h>
 

 
const char* ssid     = "WLAN1";
const char* password = "1231234123";

#define mqtt_server "m11.cloudmqtt.com"             // mqtt брокер
#define mqtt_login "123"                        
#define mqtt_password "123"                 
#define mqtt_port 1883                             // порт подключения к mqtt, у cloudmqtt порт отличный от 1883
 

const char* host = "narodmon.ru";
const int httpPort = 8283;
 
const int interval = 10*60; // 10 минут
//const int interval = 10; // 10 минут

int tm = interval;
int deviceCount = 0;

Ticker flipper;
HTU21D HTU21;
SFE_BMP180 BMP180;
BH1750 lightMeter;
WiFiClient  client; 
PubSubClient mqttclient(client);

float getBMP180(){
 char status;
  double T,P,p0,a;
 
  status = BMP180.startTemperature();
  if (status != 0)  {
    delay(status);
    status = BMP180.getTemperature(T);    
    if (status != 0)    {     
      status = BMP180.startPressure(3);
      if (status != 0)
      {
        // Wait for the measurement to complete:
        delay(status);
        status = BMP180.getPressure(P,T);
        if (status != 0)
        {
          // Print out the measurement:
          return P/1.333; 
        }
        else Serial.println("error retrieving pressure measurement\n");
      }
      else Serial.println("error starting pressure measurement\n");
    }
    else Serial.println("error retrieving temperature measurement\n");
  }
  else Serial.println("error starting temperature measurement\n");  
  
}

  
void flip(){
  tm--;
   Serial.println(tm);
   
}

void setup() {
  Serial.begin(115200);
  delay(10);
  Wire.begin(2, 0);
  HTU21.begin();
  BMP180.begin();
  lightMeter.begin(); 
  
  setup_wifi();
  mqttclient.setServer(mqtt_server, mqtt_port); 
  SendMQTT();                                  // при включении отправляем данные
//  SendNarodmon(); 
  WiFi.disconnect();
  flipper.attach(1, flip);                 // запускаем таймер
}

/// функция отправляет данные на народмон.ру
void SendNarodmon() { 

  float HTU21humd = HTU21.readHumidity();
  float HTU21temp = HTU21.readTemperature();
  float BMP180Pressure = getBMP180();
  int BH1750lux = lightMeter.readLightLevel();
  
  // подключаемся к серверу 
  Serial.print("connecting to ");
  Serial.println(host);
  
  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
     return;
  }
  
  // отправляем данные  
  Serial.println("Narodmon sending..."); 
      // заголовок
  client.print("#");
  client.print(WiFi.macAddress()); // отправляем МАС нашей ESP8266
  client.print("#");
  
  client.print("ESP8266"); // название устройства 
  client.println();

    //  отправляем данные с подключенных градусников.  
  client.print("#HTU21temp#"); 
  client.println(HTU21temp);
  client.print("#HTU21humd#"); 
  client.println(HTU21humd);
  client.print("#BMP180Pressure#"); 
  client.println(BMP180Pressure);
  client.print("#BH1750Light#"); 
  client.println(BH1750lux);  
  
   
 client.println("##");
    
  delay(10);

  // читаем ответ с и отправляем его в сериал
  // вообще на ответ нужно както реагировать
  Serial.print("Requesting: ");  
  while(client.available()){
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }
  
  client.stop();
  Serial.println();
  Serial.println();
  Serial.println("Closing connection");
  
}

void SendMQTT() {  
  char msgT[7];   
  char msgH[7];   
  char msgP[7]; 
  char msgL[7];                                         
    
  float HTU21temp = HTU21.readTemperature();
  float HTU21humd = HTU21.readHumidity(); 
  float BMP180Pressure = getBMP180();    
  int BH1750lux = lightMeter.readLightLevel();
  

  dtostrf(HTU21temp, 6, 2, msgT);
  dtostrf(HTU21humd, 6, 2, msgH);
  dtostrf(BMP180Pressure, 6, 2, msgP);
  snprintf(msgL, sizeof(msgL), "%02d", BH1750lux);  
          
  if (!mqttclient.connected()) {                      
    Serial.print("Attempting MQTT connection...");
                                                      // создаем случайный идентификатор клиента
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
                                                      // подключаемся, в client.connect передаем ID, логин и пасс
    if (mqttclient.connect(clientId.c_str(), mqtt_login, mqtt_password)) {
      Serial.println("connected");                    // если подключились 
      mqttclient.publish("Temperature", msgT); 
      mqttclient.publish("Humidity", msgH); 
      mqttclient.publish("Pressure", msgP); 
      mqttclient.publish("LightLevel", msgL); 
      Serial.println("MQTT Send OK");    
    
    } else {                                          // иначе ругаемся в монитор порта  
      Serial.println("MQTT connection failed");
      delay(5000);
    }
  }
 
}

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
 if (tm == 0){                      // если таймер отработал
    flipper.detach();                 // выключаем
    tm = interval;                    // сбрасываем переменную таймера
    setup_wifi(); 
                                      // отправляем
    SendMQTT();
    SendNarodmon();                                
    WiFi.disconnect(); // отключаемся от сети
    Serial.println("Disconnect WiFi.");
    
    flipper.attach(1, flip);          // включаем прерывание по таймеру

    
  }  
  
 
}