По тому ж принципу що і в попередній системі, інформацію необхідно передавати MQTT-брокеру на сервері Amazon звідки NODE-RED буде брати дані для побудови графіків та подальшої обробки.
Так як показники вологості не є необхідними, в даному завданні для вимірювання ідеальними будуть DS18B20 так як дозволять подключити декілька датчиків на один пін ESP8266-01.
Отже нам необхідно:
1. ESP8266-01 - 1шт.
2. DS18B20 - 3шт.
3. USB-TTL конвертер BTE13-009 (процес підключення та прошивки описувати не буду, про це детально писав тут https://www.sast.in.ua/2017/01/esp-link.html)
4. Живлення отримаю від камери спостередження, а так як це 12в то для перетворення на 3.3в нам знадобиться щось серйозніше ніж модуль AMS1117-3.3, тому в нагоді став DC-DC понижуючий конвертер LM2596 з 4.5-40В до 3-35В
5. Корпус, зєднувальні дроти, макетна плата та ін.
Трішки модифікую скетч з попередньої роботи, додавши функцію роботи з OneWire та DS18B20, видаливши зайве та трышки оптимізувавши:
// esp8266 + ds18b20 + mqtt
#include <PubSubClient.h>
#include <ESP8266WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>
const char* ssid;
const char* ssid1 = "******";
const char* ssid2 = "******";
const char* password = "**********";
char* topict01 = "/sast/spf02/t01";
char* topict02 = "/sast/spf02/t02";
char* topict03 = "/sast/spf02/t03";
char* server = "***********";
char* hellotopic = "hello_topic";
#define ONE_WIRE_BUS 2 // DS18B20 pin
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
#define REPORT_INTERVAL 600 // in sec
int conprobe = 0;
String clientName;
WiFiClient wifiClient;
PubSubClient client(server, 1883, wifiClient);
float oldT01 ;
float oldT02 ;
float oldT03 ;
DeviceAddress sensor1 = {0x28, 0xFF, 0x90, 0x86, 0xC2, 0x15, 0x1, 0x7E};
DeviceAddress sensor2 = {0x28, 0xFF, 0xC3, 0x2F, 0xC2, 0x15, 0x2, 0x7D};
DeviceAddress sensor3 = {0x28, 0xFF, 0x5D, 0x3F, 0xC2, 0x15, 0x2, 0x50};
void setup() {
Serial.begin(115200);
Serial.println("DS18B20 test!");
delay(20);
ssid = ssid1;
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
conprobe = conprobe + 1;
if (conprobe == 15) {
if (ssid == ssid1) {ssid = ssid2;} else {ssid = ssid1;}
Serial.println("");
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
conprobe = 0;
}
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
clientName = "SAST-SPF02";
Serial.print("Connecting to ");
Serial.print(server);
Serial.print(" as ");
Serial.println(clientName);
if (client.connect((char*) clientName.c_str())) {
Serial.println("Connected to MQTT broker");
Serial.println("Topic is: ");
Serial.println(topict01);
Serial.println(topict02);
Serial.println(topict03);
if (client.publish(hellotopic, "hello from ESP8266")) {
Serial.println("Publish ok");
}
else {
Serial.println("Publish failed");
}
}
else {
Serial.println("MQTT connect failed");
Serial.println("Will reset and try again...");
abort();
}
oldT01 = -1;
oldT02 = -1;
oldT03 = -1;
}
void loop() {
float t01;
float t02;
float t03;
do {
DS18B20.requestTemperatures();
t01 = DS18B20.getTempC(sensor1);
t02 = DS18B20.getTempC(sensor2);
t03 = DS18B20.getTempC(sensor3);
Serial.println("Temperature: ");
Serial.println(t01);
Serial.println(t02);
Serial.println(t03);
} while (t01 == 85.0 || t01 == (-127.0));
String payloadt01 = "";
String payloadt02 = "";
String payloadt03 = "";
payloadt01 += t01;
payloadt02 += t02;
payloadt03 += t03;
if (t01 != oldT01 || t02 != oldT02 ||t03 != oldT03)
{
sendTemperature(payloadt01, payloadt02, payloadt03);
oldT01 = t01;
oldT02 = t02;
oldT03 = t03;
}
int cnt = REPORT_INTERVAL;
while (cnt--)
delay(1000);
}
void sendTemperature(String payloadt01,String payloadt02,String payloadt03) {
if (!client.connected()) {
if (client.connect((char*) clientName.c_str())) {
Serial.println("Connected to MQTT broker again");
Serial.println("Topic is: ");
Serial.println(topict01);
Serial.println(topict02);
Serial.println(topict03);
}
else {
Serial.println("MQTT connect failed");
Serial.println("Will reset and try again...");
abort();
}
}
if (client.connected()) {
Serial.println("Sending payload: ");
Serial.println(payloadt01);
Serial.println(payloadt02);
Serial.println(payloadt03);
if (client.publish(topict01, (char*) payloadt01.c_str())) {
Serial.println("Publish T01 ok");
}
else {
Serial.println("Publish T01 failed");
}
if (client.publish(topict02, (char*) payloadt02.c_str())) {
Serial.println("Publish T02 ok");
}
else {
Serial.println("Publish T02 failed");
}
if (client.publish(topict03, (char*) payloadt03.c_str())) {
Serial.println("Publish T03 ok");
}
else {
Serial.println("Publish T03 failed");
}
}
}
Так як все налаштовую вдома, а працювати буде на складі, додав дві мережі пошук яких відбувається по черзі і в залежності яка доступна - до тої і приєднується.
Також важливим моментом є визначення фізичних адрес датчиків DS18B20 (в скетчі вказані ті що у мене, їх необхідно замінити). Щоб отримати адреси DS18B20 зручно використатит скетч що входить в стандартні приклади Arduino IDE:
#include <OneWire.h>
// OneWire DS18S20, DS18B20, DS1822 Temperature Example
//
// http://www.pjrc.com/teensy/td_libs_OneWire.html
//
// The DallasTemperature library can do all this work for you!
// http://milesburton.com/Dallas_Temperature_Control_Library
OneWire ds(10); // on pin 10 (a 4.7K resistor is necessary)
void setup(void) {
Serial.begin(9600);
}
void loop(void) {
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius, fahrenheit;
if ( !ds.search(addr)) {
Serial.println("No more addresses.");
Serial.println();
ds.reset_search();
delay(250);
return;
}
Serial.print("ROM =");
for( i = 0; i < 8; i++) {
Serial.write(' ');
Serial.print(addr[i], HEX);
}
if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return;
}
Serial.println();
// the first ROM byte indicates which chip
switch (addr[0]) {
case 0x10:
Serial.println(" Chip = DS18S20"); // or old DS1820
type_s = 1;
break;
case 0x28:
Serial.println(" Chip = DS18B20");
type_s = 0;
break;
case 0x22:
Serial.println(" Chip = DS1822");
type_s = 0;
break;
default:
Serial.println("Device is not a DS18x20 family device.");
return;
}
ds.reset();
ds.select(addr);
ds.write(0x44, 1); // start conversion, with parasite power on at the end
delay(1000); // maybe 750ms is enough, maybe not
// we might do a ds.depower() here, but the reset will take care of it.
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
Serial.print(" Data = ");
Serial.print(present, HEX);
Serial.print(" ");
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
Serial.print(data[i], HEX);
Serial.print(" ");
}
Serial.print(" CRC=");
Serial.print(OneWire::crc8(data, 8), HEX);
Serial.println();
// Convert the data to actual temperature
// because the result is a 16 bit signed integer, it should
// be stored to an "int16_t" type, which is always 16 bits
// even when compiled on a 32 bit processor.
int16_t raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) {
// "count remain" gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
// at lower res, the low bits are undefined, so let's zero them
if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
//// default is 12 bit resolution, 750 ms conversion time
}
celsius = (float)raw / 16.0;
fahrenheit = celsius * 1.8 + 32.0;
Serial.print(" Temperature = ");
Serial.print(celsius);
Serial.print(" Celsius, ");
Serial.print(fahrenheit);
Serial.println(" Fahrenheit");
}
Отримані з даного скетчу адреси зберігаємо і підставляємо в основний код в поля:
DeviceAddress sensor1 = {0x28, 0xFF, 0x90, 0x86, 0xC2, 0x15, 0x1, 0x7E};
DeviceAddress sensor2 = {0x28, 0xFF, 0xC3, 0x2F, 0xC2, 0x15, 0x2, 0x7D};
DeviceAddress sensor3 = {0x28, 0xFF, 0x5D, 0x3F, 0xC2, 0x15, 0x2, 0x50};
Перевіряємо що отримали на на нашому MQTT-брокері, і якщо все зроблено вірно - з інтервалом 10хв на сервер буде відправлятися температура з кожного датчика.
І після незначних налаштувань NODE-RED - отримуємо зручний інструмент моніторингу.
Фото встановлених датчиків в робочому просторі додам коли відправлю систему на постійне місце перебування.....
Немає коментарів:
Дописати коментар