Elektronika

Sterownik Akwarium (esp8266)

Powstał jako pierwszy. Umożliwia załączenie i wyłączenie filtrów i oświetlenia w akwarium. Sterowanie ręczne jak i automatyczne o wyznaczonych godzinach.

Urządzenie to składa się z zasilacza 5V, podwójnego przełącznika SSR, czujnika temperatury DS18B20 oraz ESP8266. Całość zmieściła się w obudowie od potrójnego gniazda natynkowego, dwa pozostały aktywne a w trzecim jest elektronika.

[foto]

Kod napisałem na podstawie modyfikacji kilku innych rozwiązań i scaliłem to na własne potrzeby. Kod zwiera automatyczny reset po utracie połączenia WiFI lub brokera MQTT.

[code lang=”cpp”]
#include <EEPROM.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 1
#define RELAY1 0
#define RELAY2 2
#define LED 3

#define MQTT_CLIENT „Akwarium”
#define MQTT_SERVER „192.168.15.235”
#define MQTT_PORT 1883
#define MQTT_TOPIC „/akwa/relay”
#define MQTT_USER „mqtt_u”
#define MQTT_PASS „mqtt_p”

#define WIFI_SSID „WiFi_SSID”
#define WIFI_PASS „WiFi_PASS”

#define VERSION „———————— Akwarium v1.01p ————————”

bool rememberRelayState = true; // Czy pamietac ustawienia w eeprom
bool sendStatusR1 = false;
bool sendStatusR2 = false;
bool requestRestart = false;
float tmp_p, tmp_s, tmp_o;
int licz = 1;

char bufor[10];
int kUpdFreq = 1; // Co ile minut sprawdzac polaczenie
int kRetries = 10; // Licznik wznawiania polaczenia wifi
int lastRELAY1State;
int lastRELAY2State;

unsigned long TTasks;
unsigned long TTasks1;
unsigned long count = 0;
long czas_temp = 10000; //co ile ma być odczyt z czujników w milisekundach
int licznik = 60; //co ile odczytów wysyłamy MQTT

bool serial = false;

String message=””;

WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

void callback(char* topic, byte* payload, unsigned int length) {

if(serial){Serial.print(„COLLECT ->\tTopic:\t[„);
Serial.print(topic);
Serial.print(„]\tMsg: [„);}

for (int i=0;i<length;i++) { message += (char)payload[i]; }
if(serial){Serial.print(message);}
if(message == „F-off”){digitalWrite(RELAY1, HIGH);sendStatusR1 = true;}
if(message == „F-on”){digitalWrite(RELAY1,LOW);sendStatusR1 = true;}
if(message == „S-off”){digitalWrite(RELAY2, HIGH);sendStatusR2 = true;}
if(message == „S-on”){digitalWrite(RELAY2,LOW);sendStatusR2 = true;}

if(serial){Serial.print(„]\tLength=”);
Serial.println(length);}
message=””;
}

void setup() {
pinMode(LED, OUTPUT);
pinMode(RELAY1, OUTPUT);
pinMode(RELAY2, OUTPUT);
digitalWrite(LED, LOW);
digitalWrite(RELAY1, HIGH);
digitalWrite(RELAY2, HIGH);
if(serial){Serial.begin(115200);}
EEPROM.begin(8);
lastRELAY1State = EEPROM.read(0);
lastRELAY2State = EEPROM.read(1);
if (rememberRelayState && lastRELAY1State == 1) {
digitalWrite(RELAY1, LOW);
}
if (rememberRelayState && lastRELAY2State == 1) {
digitalWrite(RELAY2, LOW);
}
sendStatusR1 = true;
sendStatusR2 = true;
sensors.begin();
sensors.setWaitForConversion(false); // makes it async
sensors.requestTemperatures();
mqttClient.setCallback(callback);
mqttClient.setServer(MQTT_SERVER, MQTT_PORT);
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASS);
if(serial){Serial.println(VERSION);
Serial.print(„\nUnit ID: „);
Serial.print(„esp8266-„);
Serial.print(ESP.getChipId(), HEX);
Serial.print(„Send temperature every: „);
Serial.print((czas_temp*licznik)/60000);
Serial.print(” minutes”);
Serial.print(„\nConnecting to „); Serial.print(WIFI_SSID); Serial.print(” Wifi”); }
while ((WiFi.status() != WL_CONNECTED) && kRetries –) {
delay(500);
if(serial){Serial.print(” .”);}
}
if (WiFi.status() == WL_CONNECTED) {
if(serial){Serial.println(” DONE”);
Serial.print(„IP Address is: „); Serial.println(WiFi.localIP());
Serial.print(„Connecting to „);Serial.print(MQTT_SERVER);Serial.print(” Broker . .”);}
delay(500);
while (!mqttClient.connect(MQTT_CLIENT, MQTT_USER, MQTT_PASS)) {
if(serial){Serial.print(” .”);}
delay(1000);
}
if(mqttClient.connected()) {
if(serial){Serial.println(” DONE”);
Serial.println(„\n—————————- Logs —————————-„);
Serial.println();}
mqttClient.subscribe(MQTT_TOPIC);
blinkLED(LED, 300, 4);
}
else {
if(serial){Serial.println(” FAILED!”);
Serial.println(„\n—————————————————————-„);
Serial.println();}
}
}
else {
if(serial){Serial.println(” WiFi FAILED!”);
Serial.println(„\n—————————————————————-„);
Serial.println();}
}
}

void loop() {
mqttClient.loop();
timedTasks();
checkStatus();
}

void blinkLED(int pin, int duration, int n) {
for(int i=0; i<n; i++) {
digitalWrite(pin, HIGH);
delay(duration);
digitalWrite(pin, LOW);
delay(duration);
}
}

void checkConnection() {
if (WiFi.status() == WL_CONNECTED) {
if (mqttClient.connected()) {
if(serial){Serial.println(„mqtt broker connection . . . . . . . . . . OK”);}
}
else {
if(serial){Serial.println(„mqtt broker connection . . . . . . . . . . LOST”);}
requestRestart = true;
}
}
else {
if(serial){Serial.println(„WiFi connection . . . . . . . . . . LOST”);}
requestRestart = true;
}
}

void checkStatus() {
if (sendStatusR1) {
if(digitalRead(RELAY1) == LOW) {
if (rememberRelayState) {
EEPROM.write(0, 1);
}
mqttClient.publish(MQTT_TOPIC”/F/stat”, „F-on”, false);
if(serial){Serial.println(„SEND ->\t\tTopic:\t[„MQTT_TOPIC”/F/stat]\tMsg: [F-on]\tRelay F: ON”);}
} else {
if (rememberRelayState) {
EEPROM.write(0, 0);
}
mqttClient.publish(MQTT_TOPIC”/F/stat”, „F-off”, false);
if(serial){Serial.println(„SEND ->\t\tTopic:\t[„MQTT_TOPIC”/F/stat]\tMsg: [F-off]\tRelay F: OFF”);}
}
if (rememberRelayState) {
EEPROM.commit();
}
blinkLED(LED, 50, 2);
sendStatusR1 = false;
}
if (sendStatusR2) {
if(digitalRead(RELAY2) == LOW) {
if (rememberRelayState) {
EEPROM.write(1, 1);
}
mqttClient.publish(MQTT_TOPIC”/S/stat”, „S-on”, false);
if(serial){Serial.println(„SEND ->\t\tTopic:\t[„MQTT_TOPIC”/S/stat]\tMsg: [S-on]\tRelay S: ON”);}
} else {
if (rememberRelayState) {
EEPROM.write(1, 0);
}
mqttClient.publish(MQTT_TOPIC”/S/stat”, „S-off”, false);
if(serial){Serial.println(„SEND ->\t\tTopic:\t[„MQTT_TOPIC”/S/stat]\tMsg: [S-off]\tRelay F: OFF”);}
}
if (rememberRelayState) {
EEPROM.commit();
}
blinkLED(LED, 50, 2);
sendStatusR2 = false;
}
if (requestRestart) {
blinkLED(LED, 30, 15);
ESP.restart();
}
}

void checktemp() {
tmp_p = sensors.getTempCByIndex(0);
//tmp_p = 23.88;
tmp_s = (tmp_s + tmp_p);

// Serial.println(„Licznik:\t”licz”/”licznik”Temperature:\t”tmp_p);
licz++;
if(licz > licznik){
tmp_s = tmp_s / (licz-1);
if(serial){Serial.print(„READING ->\tAverage temperature:\t”);
Serial.println(tmp_s);}

if(tmp_s != tmp_o){
tmp_o = tmp_s;
dtostrf(tmp_o , 0, 1, bufor);
if(serial){Serial.print(„SEND ->\t\tTopic:\t[„MQTT_TOPIC”/temp]\tMsg: [„);
Serial.print(bufor);
Serial.println(„]”); }
mqttClient.publish(MQTT_TOPIC”/temp”, bufor, false);
blinkLED(LED, 50, 2);
}
tmp_s = 0;
licz = 1;
}
sensors.requestTemperatures();
}

void timedTasks() {
if ((millis() > TTasks + (kUpdFreq*60000)) || (millis() < TTasks)) {
TTasks = millis();
checkConnection();
blinkLED(LED, 100, 1);
}

if ((millis() > TTasks1 + czas_temp) || (millis() < TTasks1)) {
TTasks1 = millis();
checktemp();
blinkLED(LED, 10, 1);
}
}
[/code]

Tak wygląda sterowanie ręczne po stronie HA

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *