Hi, I am using the 16bit GPIO Expander MCP23017.
My project is actually only at the beginning, but a serious error is already occurring. I use a W5500 Ethernet board for the connection to my MQTT Broker. At the moment the procedure is simple, if it is necessary to turn on the heating, a message is sent via the MQTT callback. Besides the current temperature is also sent away via MQTT. Normally this procedure works very well, but if it ran for one or two days and switched several times, the MCP23017 freezes and stays permanently on LOW at the output. If you do a softreset, the output is permanently HIGH. Only by switching off the power supply will it be possible to get the process working again properly.
Is the MCP23017 not suitable for 24/7 continuous operation or is there still an error on my part?
Here is my code:
#include <Ethernet2.h>
#include <PubSubClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include "Adafruit_MCP23017.h"
#define ONE_WIRE_BUS 15 // 1-Wire Pin
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress Temp_PCB { 0x28, 0xEE, 0x01, 0x2D, 0x23, 0x16, 0x01, 0x6C };
DeviceAddress Temp_oben { 0x28, 0xFF, 0xFC, 0xEF, 0xB2, 0x17, 0x04, 0x0C };
DeviceAddress Temp_unten { 0x28, 0xFF, 0xDA, 0xBD, 0xB2, 0x17, 0x04, 0xB7 };
Adafruit_MCP23017 mcp1; //Expander mit standard Adresse
#define RST_PIN 1 // NFC RST PIN
#define CS1_PIN 5 // NFC1 Haustuer
byte mac[] = {...};
const char* mqttServer = "...";
const int mqttPort = ...;
EthernetClient ethClient;
PubSubClient client(ethClient);
unsigned long Temperaturabfrage_letzter_Zeitstempel = 0;
int Temperaturabfrage_Zeitintervall = 60000; // Zeitintervall Temperaturupdate
unsigned long Temperaturabfrage_Gewaechshaus_letzter_Zeitstempel = 0;
int Temperaturabfrage_Gewaechshaus_Zeitintervall = 60000; // Zeitintervall Temperaturupdate für Heizung
void reconnect() {
while (!client.connected()) {
Serial.print("Verbindung zum MQTT Broker wird wiederhergestellt");
if (client.connect("Keller")) {
Serial.println("Mit MQTT Broker verbunden");
client.subscribe("/Werte/Keller/Temperaturabfrage");
client.subscribe("/Werte/Keller/Temperaturabfrage_Gewaechshausheizung");
client.subscribe("/Werte/Keller/Restart");
client.subscribe("/Werte/Keller/Gewaechshaus_Heizung");
client.publish("/Werte/Keller/Update", "1");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" Warte 2 Sekunden");
delay(2000);
}
}
}
void setup() {
Serial.begin(115200); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
Serial.println("Verbindung zum Netzwerk herstellen");
// You can use Ethernet.init(pin) to configure the CS pin
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// no point in carrying on, so do nothing forevermore:
for (;;)
;
}
// print your local IP address:
Serial.print("Aktuelle IP-Adresse: ");
for (byte thisByte = 0; thisByte < 4; thisByte++) {
// print the value of each byte of the IP address:
Serial.print(Ethernet.localIP()[thisByte], DEC);
Serial.print(".");
}
client.setServer(mqttServer, mqttPort);
client.setCallback(callback);
while (!client.connected()) {
Serial.println("Verbindung zu MQTT Broker herstellen");
if (client.connect("Keller")) {
Serial.println("Mit MQTT Broker verbunden");
client.subscribe("/Werte/Keller/Temperaturabfrage");
client.subscribe("/Werte/Keller/Temperaturabfrage_Gewaechshausheizung");
client.subscribe("/Werte/Keller/Restart");
client.subscribe("/Werte/Keller/Gewaechshaus_Heizung");
client.publish("/Werte/Keller/Update", "1");
} else {
Serial.print("failed with state ");
Serial.print(client.state());
delay(2000);
}
}
delay(200);
sensors.begin();
sensors.setResolution(Temp_PCB, 9);
sensors.setResolution(Temp_unten, 9);
sensors.setResolution(Temp_oben, 9);
sensors.requestTemperatures();
Serial.print("Temperatur PCB: ");
Serial.println(sensors.getTempC(Temp_PCB));
Serial.print("Temperatur Gewächshaus unten: ");
Serial.println(sensors.getTempC(Temp_unten));
Serial.print("Temperatur Gewächshaus oben: ");
Serial.println(sensors.getTempC(Temp_oben));
Serial.println("Temperatursensor OK");
delay(200);
mcp1.begin(0);
mcp1.pinMode(0, OUTPUT);
mcp1.digitalWrite(0, LOW);
Serial.println("Expander OK");
Serial.println("Start");
}
void callback(char* topic, byte* payload, unsigned int length) {
if (strcmp(topic, "/Werte/Keller/Temperaturabfrage") == 0) {
Temperaturabfrage_Zeitintervall = 0;
for (int i = 0; i < length; i++) {
char c = payload[i];
if (c >= '0' && c <= '9')
Temperaturabfrage_Zeitintervall = Temperaturabfrage_Zeitintervall * 10 + c - '0';
}
Serial.print("UPDATE Zeitintervall Temperaturabfrage: ");
Serial.println(Temperaturabfrage_Zeitintervall);
}
if (strcmp(topic, "/Werte/Keller/Temperaturabfrage_Gewaechshausheizung") == 0) {
Temperaturabfrage_Gewaechshaus_Zeitintervall = 0;
for (int i = 0; i < length; i++) {
char c = payload[i];
if (c >= '0' && c <= '9')
Temperaturabfrage_Gewaechshaus_Zeitintervall = Temperaturabfrage_Gewaechshaus_Zeitintervall * 10 + c - '0';
}
Serial.print("UPDATE Zeitintervall Temperaturabfrage für Heizung: ");
Serial.println(Temperaturabfrage_Gewaechshaus_Zeitintervall);
}
if (strcmp(topic, "/Werte/Keller/Restart") == 0) {
if (payload[0] == '1') {
Serial.println("Restart");
ESP.restart();
}
}
if (strcmp(topic, "/Werte/Keller/Gewaechshaus_Heizung") == 0) {
if (payload[0] == '1') {
Serial.println("Gewächshaus Heizung: ON");
mcp1.digitalWrite(0, HIGH);
}
if (payload[0] == '0') {
Serial.println("Gewächshaus Heizung: OFF");
mcp1.digitalWrite(0, LOW);
}
}
}
void loop() {
unsigned long currentMillis = millis();
if (!client.connected()) {
reconnect();
}
client.loop();
///////////////////////////////TEMPUPDATE/////////////////////////////////////////
if (currentMillis - Temperaturabfrage_letzter_Zeitstempel >= Temperaturabfrage_Zeitintervall) {
Temperaturabfrage_letzter_Zeitstempel = currentMillis;
sensors.requestTemperatures();
Serial.print("Temperatur PCB: ");
float temp0 = sensors.getTempC(Temp_PCB);
temp0 = ((int)(temp0*10)) / 10.0;
Serial.println(temp0);
client.publish("/Temperatur/Keller/PCB", String(temp0).c_str());
Serial.print("Temperatur Gewächshaus oben: ");
float temp1 = sensors.getTempC(Temp_oben);
temp1 = ((int)(temp1*10)) / 10.0;
Serial.println(temp1);
client.publish("/Temperatur/Keller/Gewaechshaus_oben", String(temp1).c_str());
Serial.print("Temperatur Gewächshaus unten: ");
float temp2 = sensors.getTempC(Temp_unten);
temp2 = ((int)(temp2*10)) / 10.0;
Serial.println(temp2);
client.publish("/Temperatur/Keller/Gewaechshaus_unten", String(temp2).c_str());
}
if (currentMillis - Temperaturabfrage_Gewaechshaus_letzter_Zeitstempel >= Temperaturabfrage_Gewaechshaus_Zeitintervall) {
Temperaturabfrage_Gewaechshaus_letzter_Zeitstempel = currentMillis;
sensors.requestTemperatures();
Serial.print("Temperatur Gewächshaus oben für Heizung: ");
float temp_oben_heizung = sensors.getTempC(Temp_oben);
temp_oben_heizung = ((int)(temp_oben_heizung*10)) / 10.0;
Serial.println(temp_oben_heizung);
client.publish("/Temperatur/Keller/Heizung/Gewaechshaus_oben", String(temp_oben_heizung).c_str());
Serial.print("Temperatur Gewächshaus unten für Heizung: ");
float temp_unten_heizung = sensors.getTempC(Temp_unten);
temp_unten_heizung = ((int)(temp_unten_heizung*10)) / 10.0;
Serial.println(temp_unten_heizung);
client.publish("/Temperatur/Keller/Heizung/Gewaechshaus_unten", String(temp_unten_heizung).c_str());
}
}