ESP8266 & ARDUINO

Sterownik Akwarium

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 BS18B20 oraz ESP8266. Całość zmieściła się w obudowie od potrójnego gniazda natynkowego, dwa pozostały aktywne a w trzecim jest elektronika.

[dodać tu 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.

#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);
}
}

Tak wygląda sterowanie ręczne po stronie HA

Leave a Reply

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.