- Platform information:
- Hardware: Raspberry Pi 3 B+
- OS: Raspbian last version
- openHAB version: last version
- Issue of the topic: please be detailed explaining your issue
Hi, my name is Josep Mencion and I’m doing a research school project on home automation.
I have a Raspberry Pi and an Arduino MEGA 2560 with an Ethernet Shield which connects to the Raspberry Pi 1883 MQTT broker.
I send temperature, humidity and luminosity data to the broker.
All seems to work, but the Arduino MEGA doesn’t send the data for more than 2 days. I explain: without any explanation, the Arduino disconnects from the broker and stops sending the data.
I attatch here my Arduino code, thanks a lot:
#include <Ethernet.h>
#include <PubSubClient.h>
#include <DHT.h>
#include <Servo.h>
byte mac[] = { 0xDE, 0xED, 0xBF, 0xAF, 0xFF, 0xED };
IPAddress dnServer(1, 1, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress ip(192, 168, 1, 210);
IPAddress mqtt_server(192,168,1,220);
EthernetClient ethClient;
PubSubClient client(ethClient);
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
const int LDRPin = A15;
const int DHTPin = 49;
const int PIRPin= 33;
const int ECHOPin = 43;
const int TRIGGERPin = 42;
const int BUZZPin = 39;
const int MQPin = 21;
const int LEDPin = 31;
const int WATERPin = 20;
const int RELAYPin = 35;
const int ACS712Pin = A11;
const int SERVOPin = 37;
DHT dht(DHTPin, DHTTYPE);
Servo servoPorta;
unsigned long prevMillis1 = 0;
unsigned long prevMillis2 = 0;
unsigned long time_now_1 = 0;
unsigned long time_now_2 = 0;
float lum = 0;
char lumStr[3];
char humStr[3];
char tempStr[3];
int pirState = 2;
int trigger = 0;
int hcsrState = 2;
volatile int mqState = 2;
int servoState = 2;
volatile int waterState =2;
int pos = 85;
int lightState;
int relayState;
int sensibility = 185; // use 185 for 5A Module
double voltage = 0;
double vRMS = 0;
double ampRMS = 0;
long duration;
long distanceCm;
char waterStr;
void reconnect(){
while (!client.connected()) {
Serial.println("Intentant connectar-se...");
if (client.connect("Arduino_Client")) {
Serial.println("Connectat");
}else{
Serial.print(F("Error de connexió, rc="));
Serial.print(client.state());
Serial.println(F(" Reintentar en 3 segons"));
delay(3000);
}
}
}
unsigned long timerLlum = 0; // timer per emagatzemar temps quan llum baixa de x per cent de lluminositat
unsigned long delayLlum = 7200000; // temps que el llum estara ences un cop detecti que lluminositat baixa
void lightRead(){
Serial.println ("lightRead");
int inputLDR = analogRead(LDRPin);
lum = map(inputLDR, 0, 1023, 0, 100);//Mapegem el resultat a un valor en 0 i 100
dtostrf(lum, 2, 1, lumStr);
client.publish("pidomohome/luminosity", lumStr);
}
void dhtRead(){
Serial.println ("dhtRead");
dht.begin();
float t = dht.readTemperature();
dtostrf(t, 2, 1, tempStr);
client.publish("pidomohome/temperature", tempStr);
float h = dht.readHumidity();
dtostrf(h, 2, 1, humStr);
if (isnan(h) || isnan(t)) {
Serial.println("Error de lectura del sensor DHT-22");
return;
}
client.publish("pidomohome/humidity", humStr);
}
//Llegir PIR
void pirRead(){
if(millis() > time_now_2 + 1000){//Esperem 1 segon entre lectures
time_now_2 = millis();
int state = digitalRead(PIRPin);
if (state == HIGH){
client.publish("pidomohome/movement", "OPEN");
Serial.print("Hi ha moviment!!! \n");
pirState = 1;
}
if (pirState == 1){
digitalWrite(LEDPin , HIGH);
}
if (state == LOW){
pirState = 0;
digitalWrite(LEDPin , LOW);
client.publish("pidomohome/movement", "CLOSED");
}
}
}
unsigned long startHCSR = millis();
void hcsr04Read(){
if (millis()-startHCSR > 2000) {//Esperem 2 segons entre lectures
startHCSR = millis ();
digitalWrite(TRIGGERPin, LOW);//LOW durant 4us per generar pols net
delayMicroseconds(4);
digitalWrite(TRIGGERPin, HIGH);//Generem trigger de 10us
delayMicroseconds(10);
digitalWrite(TRIGGERPin, LOW);
duration = pulseIn(ECHOPin, HIGH);//Medim temps entre polsos en microsegons
distanceCm = (duration * 10 / 292 / 2);// Transformem de distància a cm
Serial.print("La distància és de ");
Serial.print(distanceCm);
Serial.print("cm \n");
if (distanceCm > 11 and hcsrState !=1){
client.publish("pidomohome/door", "OPEN");
hcsrState = 1;
}
if (hcsrState == 1){
tone(BUZZPin, 500);
digitalWrite(LEDPin , HIGH);
}
if (distanceCm <= 11 and hcsrState ==1){
client.publish("pidomohome/door", "CLOSED");
hcsrState = 0;
noTone(BUZZPin);
digitalWrite(LEDPin , LOW);
}
}
}
void mqRead(){
bool gas = digitalRead(MQPin);
if(gas and mqState != 1) {
client.publish("pidomohome/fire", "OPEN");
mqState = 1; // info published
tone(BUZZPin, 400);
digitalWrite(LEDPin , HIGH);
Serial.println ("Gas! Alarm");
}
if (!gas and mqState != 0) {
client.publish("pidomohome/fire", "CLOSED");
mqState = 0; // info published
noTone(BUZZPin);
digitalWrite(LEDPin , LOW);
Serial.println ("Gas OK");
}
}
void waterRead(){
bool inputW = digitalRead(WATERPin);
if(inputW and waterState != 1) {
client.publish("pidomohome/flood", "OPEN");
waterState = 1; // info published
tone(BUZZPin, 500);
digitalWrite(LEDPin , HIGH);
Serial.println ("Water! Alarm");
}
if (!inputW and waterState != 0) {
client.publish("pidomohome/flood", "CLOSED");
waterState = 0; // info published
noTone(BUZZPin);
digitalWrite(LEDPin , LOW);
Serial.println ("Water OK");
}
}
float getVPP(){
float result;
int readValue;
int maxValue = 0;
int minValue = 1024;
uint32_t startACS = millis();
while((millis()-startACS) < 1000) {
readValue = analogRead(ACS712Pin);
if (readValue > maxValue) {
maxValue = readValue;
}
if (readValue < minValue) {
minValue = readValue;}
}
result = ((maxValue - minValue) * 5.0)/1024.0;
return result;
}
getVPP
void light(){
Serial.println ("light");
voltage = getVPP();
vRMS = (voltage / 2.0) * 0.707;
ampRMS = (vRMS * 1000) / sensibility;
if (ampRMS>0.05 and lightState==0){
lightState=1;
client.publish("pidomohome/light", "ON");
}
if (ampRMS<0.05 and lightState==1){
lightState=0;
client.publish("pidomohome/light", "OFF");
}
}
void callback(char* topic, byte* payload, unsigned int length) {
if (strcmp ("pidomohome/trigger", topic) == 0) {
for (int i=0;i<length;i++) {
char receivedChar = (char)payload[i];
//Serial.println (receivedChar);
if (receivedChar == 'N'){
trigger = 1;
Serial.println ("trigger activate");
}
if (receivedChar == 'F'){
trigger = 0;
Serial.println ("trigger de-activate");
}
}
}
if (strcmp ("pidomohome/servo", topic) == 0) {
for (int i=0;i<length;i++) {
char receivedChar = (char)payload[i];
if (receivedChar == 'N' and servoState!= 1 and pos == 85){
for (pos = 85; pos <= 165; pos += 1) {
servoPorta.write(pos);
}
servoState = 1;
pos = 165;
}
if (receivedChar == 'F' and servoState ==1 and pos == 165){
for (pos = 165; pos >= 85; pos -= 1) {
servoPorta.write(pos);
}
servoState = 0;
pos = 85;
}
}
}
if (strcmp ("pidomohome/light", topic) == 0){
for (int i=0;i<length;i++) {
char receivedChar = (char)payload[i];
relayState = digitalRead(RELAYPin);
if (receivedChar == 'F') {
Serial.println ("light OFF");
digitalWrite(RELAYPin, LOW);
}
if (receivedChar == 'N') {
Serial.println ("light ON");
digitalWrite(RELAYPin, HIGH);
}
}
}
}
void setup() {
Serial.begin(9600);
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
servoPorta.attach(SERVOPin);
pinMode(LDRPin, INPUT);
pinMode(DHTPin, INPUT);
pinMode(PIRPin, INPUT);
pinMode(ACS712Pin, INPUT);
pinMode(TRIGGERPin, OUTPUT);
pinMode(LEDPin, OUTPUT);
pinMode(ECHOPin, INPUT);
pinMode(BUZZPin, OUTPUT);
pinMode(RELAYPin, OUTPUT);
pinMode(MQPin, INPUT_PULLUP);
pinMode(WATERPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(WATERPin), waterRead, CHANGE);
attachInterrupt(digitalPinToInterrupt(MQPin), mqRead, CHANGE);
// while (true) {
// testRele();
// }
}
void testRele() {
Serial.println ("Test rele");
digitalWrite(RELAYPin, HIGH);
delay (1000);
digitalWrite(RELAYPin, LOW);
delay (1000);
}
bool mqttConnectedFlag = false;
void loop() {
if (!client.connected()) {
if (mqttConnectedFlag) mqttConnectedFlag = false; // Reset flag MQTT connection
Serial.print("Connecting ...\n");
Ethernet.begin(mac, ip, gateway, subnet);
reconnect();
client.subscribe("pidomohome/#");
}else{
unsigned long time_now_1 = millis();
if (time_now_1 - prevMillis1 >= 5000){
Serial.print("Timer1\n");
if (!mqttConnectedFlag) { // Sends gas and water information when Arduino connects to the broker
mqRead ();
waterRead ();
mqttConnectedFlag = true;
}
lightRead();
dhtRead();
pirRead();
light(); // on/off
prevMillis1 = millis();
}
if(trigger == 1){
unsigned long time_now_2 = millis();
if (time_now_2 - prevMillis2 >= 5000){
Serial.print("Timer2\n");
hcsr04Read();
prevMillis2 = millis ();
}
}
client.loop();
}
delay(100);
}
Thank you very much,
Best,
Josep