Управление светом на 433 Мгц при помощи OpenMQTTGate

Захотелось научиться управлять светом с мобильника или Telegram. Для этой цели были закуплены выключатели света с 433Мгц приемником на ali.

https://ru.aliexpress.com/item/32814191331.html?spm=a2g0s.9042311.0.0.41ca33ed1Ox8Tq

Также, были приобретены самые дешевые приемник и передатчик 433MГц

https://ru.aliexpress.com/item/32840951211.html?spm=a2g0s.9042311.0.0.735533edZFhEhL

 

Из закромов был извлечён модуль esp8266 NodeMCU

32.PNG

Идея такова: Приемник и передатчик 433 подключаются к ESP. ESP используется как WIFI шлюз 433toMQTT. MQTT брокер Mosquitto уже установлен на Raspberry и является связующим звеном между логикой умного дома в Node red и шлюзом.

В качестве прошивки для ESP использован OpenMQTTGateway

34.PNG

 

Прошивка тут

ESP8266_OpenMQTTGateway_V092_RF.zip

Описание и схема подключений тут. Данная схема у меня не заработала, почему то на пине VIN  было всего 1.8В. Я подключил передатчик на VV, а приемник на 3.3В.

https://github.com/1technophile/OpenMQTTGateway/wiki/ESP8266-RF-Send-and-Receive

 

33

 

 

Нюансы:

  1. При первичной настройке шлюз поднимает точку доступа, пароль «your_password»
  2. При первичной настройке надо указать ssid и пароль к домашней wifi сети и данные mqtt сервера. При настройке mqtt сервера надо быть аккуратным, потому что изменить их после не получится, придется стирать всю память esp и заливать прошивку по новому (возможно это не так, все поднималось на бегу).

35.PNG

3. После настройки нужно открыть консоль raspberry и подписаться на все топики mosquitto, чтобы узнать точное название топиков, которые создает шлюз. Названия могут отличаться

sudo mosquitto_sub -t +/# -v -u имя_для_авторизации -P пароль_для_авторизации

если  увидели такие статусы, то все настроено правильно

home/OpenMQTTGateway_ESP8266_RF/LWT Online
home/OpenMQTTGateway_ESP8266_RF/version Х.ХХ

После того, как убедились, что все работает, можно перейти к настройке Node Red. У разработчика шлюза уже был готовый флоу.

https://github.com/1technophile/OpenMQTTGateway/wiki/NodeRED-integration

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

 

 

Метеостанция на ESP8266

Каждый ардуиновец сделал свою метеостанцию — это непреложная истина. Ну и я мимо не прошел. Идея такова: создать устройство мониторинга за температурой, влажностью и уровнем СО2 с локальным интерфейсом и выводом информации в интернет. Вывод в глобальную паутину реализован через встроенный в ESP вебсервер.

Состав устройства такой:

  1. Китайский Wemos D1 на базе ESP-12;
  2. Газоанализатор СО2  MH-Z19 PWM;
  3. Датчик давления, температуры и влажности BME280 I2C;
  4. Дисплей TFT 1’8 SPI.

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

Цитируя интернет :

«ESP8266 имеет 15 полноценных GPIO выходов. 6 из которых заняты микросхемой flash памяти. При этом GPIO 0,1,2,3,15 имеют системные функции и имеют ограничения при использовании — не рекомендуется их использовать для сухого контакта, кнопок, прерываний (хотя в некоторых случаях работать будет). Для штатной работы модуля ESP8266 GPIO 0 и 2  не должны быть подтянуты к минусу при старте модуля. GPIO 15 для старта должен подтянут к минусу через резистор 10кОм. GPIO 1 соотвествует вывод TXD. GPIO 3 — RXD.

Так же ESP8266 имеет отдельный GPIO16 , который управляется через RTC регистры, этот GPIO имеет ограничения при использовании и в прошивке используется только для режима OUTPUT (выход). Подключение датчиков к этому выводу невозможно. GPIO16 используется для пробуждения модуля при использовании спящего режима, если подключить его к выводу RESET.»

pin2

pin1

Схема подключения дисплея такая:

TFT   ESP

LED      VIN

SCK    14

SDA   MOSI/13

A0     16

reset reset

cs    15

gnd   gnd

tft

Схема подключения Bme280:

BME        ESP

SDA —-> D4

SCL —->  D5

Vcc —-> 5V

GND——>GND

Схема подключения MH-Z19:

BME        ESP

PWM—-> A0

VIN —-> 5V

GND——>GND

Таким образом, при использовании в устройстве одновременно I2C и SPI, Ввиду недостачи дискретных входов, для чтения pwm датчика СО использован аналоговый вход. Программно определяется длительность импульса ШИМ и рассчитывается ppm.

Cкетч Arduino IDE:

//#include 

#include 
#include 
#include 
#include 
#include 
#include  // Core graphics library
#include  // Hardware-specific library

#define pwmPin A0 //D4
//#define LedPin 1
#define TFT_CS 15 //D8
#define TFT_RST -1 //RST
#define TFT_DC 16 //D6
//#define BME_CS 16
//#define TFT_SCLK 13 // set these to be whatever pins you like!
//#define TFT_MOSI 11 // set these to be whatever pins you like!
//#define SEALEVELPRESSURE_HPA (1013.25)

int prevVal = 0;
long th, tl, h, l, front_time, cut_time, ppm, ppm1;
long tt = millis();;
int myVal;
long oldtime = 0;
long newtime = 0;
const char* ssid = "Greyser";
const char* password = "08112014wed";

//const char* ssid = "HT37Pro";
//const char* password = "120883aaA";

Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI

unsigned long delayTime;
bool blank_line;
bool front;

WiFiServer server(80);
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

void setup() {
//Ota.ota();
Serial.begin(9600);
pinMode(pwmPin, INPUT);
//pinMode(LedPin, OUTPUT);
Serial.println(F("BME280 test"));

bool status;
front = 0;
// default settings
// (you can also pass in a Wire library object like &Wire2)
status = bme.begin();
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}

Serial.println("-- Default Test --");
delayTime = 1000;

Serial.println();
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.println("WiFi connected");

// Start the server
server.begin();
Serial.println("Server started");

// Print the IP address
Serial.println(WiFi.localIP());

tft.initR(INITR_BLACKTAB);
tft.fillScreen(ST7735_BLACK);
tft.setTextColor(ST7735_RED);
tft.setTextSize(1);
tft.setCursor(0, 0);
// tft_output();
//CO_calc();
}

void loop() {
//Если обнаружили изменение
newtime = millis() - oldtime;

myVal = analogRead(pwmPin);
if (myVal > 200) {
// digitalWrite(LedPin, HIGH);
if (myVal != prevVal) {
//h = tt;
//tl = h - l;
prevVal = myVal;
front = 1;
front_time = millis();
}
} else {
// digitalWrite(LedPin, LOW);
if ((myVal != prevVal) and (front = 1)) {
//l = tt;
//th = l - h;
prevVal = myVal;
//ppm1 = 5000 * (th - 2) / (th + tl - 4);
//delay(500);
front = 0;
cut_time = millis();
}
}
ppm = (cut_time - front_time) * 5;

Serial.print("Temperature = ");
Serial.print(bme.readTemperature());
Serial.println(" *C");

Serial.print("Pressure = ");

Serial.print(bme.readPressure() / 100.0F / 1.33322);
Serial.println(" mmHg");

//Serial.print("Approx. Altitude = ");
//Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
//Serial.println(" m");

Serial.print("Humidity = ");
Serial.print(bme.readHumidity());
Serial.println(" %");
if (200 < ppm and ppm < 2000)
{ Serial.println("PPMmy = " + String(ppm) + " analogRead = " + myVal);
}
Serial.println("lag = " + String(newtime));
Serial.println();
WiFiClient client = server.available(); // Получаем данные, посылаемые клиентом
while (client.connected()) { // Пока есть соединение с клиентом
if (client.available()) { // Если клиент активен
// Если клиент активен
char c = client.read(); // Считываем посылаемую информацию в переменную "с"
if (c == '\n' && blank_line) { // Вывод HTML страницы
client.println("HTTP/1.1 200 OK"); // Стандартный заголовок HTTP
client.println("Content-Type: text/html");
client.println("Connection: close"); // Соединение будет закрыто после завершения ответа
client.println("Refresh: 10"); // Автоматическое обновление каждые 10 сек
client.println();
client.println(""); // Веб-страница создается с использованием HTML
client.println(""); // Открытие тега HTML
client.println("");
client.print("METEO STATION"); // Название страницы
client.println("");
client.println("");
client.println("

ESP8266 — Temperature

«); client.println(»

Temperature = «); client.print(bme.readTemperature()); client.println(» *C»); client.println(); client.print(«Pressure = «); client.print(bme.readPressure() / 100.0F / 1.33322); client.println(» mmHg»); client.println(); //client.print(«Approx. Altitude = «); //client.print(bme.readAltitude(SEALEVELPRESSURE_HPA)); // client.println(» m»); //client.println(); client.print(«Humidity = «); client.print(bme.readHumidity()); client.println(» %»); client.println(«PPM = » + String(ppm)); client.println(«»); client.println(«»); // Закрытие тега HTML break; // Выход } if (c == ‘\n’) { // Если «с» равен символу новой строки blank_line = true; // Тогда начинаем новую строку } else if (c != ‘\r’) { // Если «с» не равен символу возврата курсора на начало строки blank_line = false; // Тогда получаем символ на текущей строке } } } //delay(1000); tft.fillScreen(ST7735_BLACK); tft.setCursor(0, 0); tft.print(«METEO STATION»); // Название страницы tft.println(«ESP8266»); tft.println(«Server started»); // Print the IP address tft.println(WiFi.localIP()); tft.println(«Temperature = «); tft.print(bme.readTemperature()); tft.println(» *C»); tft.println(); tft.print(«Pressure = «); tft.print(bme.readPressure() / 100.0F / 1.33322); tft.println(» mmHg»); tft.println(); //tft.print(«Approx. Altitude = «); // tft.print(bme.readAltitude(SEALEVELPRESSURE_HPA)); // tft.println(» m»); // tft.println(); tft.print(«Humidity = «); tft.print(bme.readHumidity()); tft.println(» %»); if (200 < ppm and ppm < 2000) { tft.println(«PPMmy = » + String(ppm) + » analogRead = » + myVal); } tft.println(front); tft.println(«lag = » + String(newtime)); oldtime = millis(); } //void CO_calc() { //} //void tft_output() { //}