Observed behavior:
The relay switches on and off approx once per second after a random amount of time(usually 1-2 hours).
Circuit:
Arduino, Raspberry pi on same 5V buck converter from 12V power supply
Relays on separate 5V wall wart
Relays are opto-coupled, board from amazon
https://www.amazon.com/dp/B072K5NQQW/?coliid=I2FL01CS6YEZEW&colid=UBVRGM199GXE&psc=1&ref_=lv_ov_lig_dp_it
Relay switch 120V AC fridge load
The raspberry pi controls arduino via serial.
of format <1,1,255,255>
where <relay 1(unused), relay 2(fridge), pwm 1, pwm 2>
Arduino code:
It uses a non-blocking serial parser I found somewhere.
#include <DallasTemperature.h>
#include <OneWire.h>
#include <DHT.h>
int fridgePin = 4;
int heaterPin = 2;
int humidPin = 3;
int heaterFanPin = 6;
int tempsPin = 7;
//Related to Temp and hum sensors
int DHT1Pin = 10;
int DHT2Pin = 9;
#define DHTTYPE DHT22
DHT dht1(DHT1Pin, DHTTYPE);
DHT dht2(DHT2Pin, DHTTYPE);
float dht1Hum = 0;
float dht1Temp = 0;
float dht2Hum = 0;
float dht2Temp = 0;
// Related to temp probes
#define ONE_WIRE_BUS 7
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float T1 = 0;
float T2 = 0;
float T3 = 0;
bool fridgeState = LOW;
bool heaterState = LOW;
int humidityPower = 0;
int heaterFanSpeed = 0;
///// Related to Serial Comm
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars]; // temporary array for use when parsing
// variables to hold the parsed data
char messageFromPC[numChars] = {0};
String s = String(0);
boolean newData = false;
/////
void setup() {
// put your setup code here, to run once:
pinMode(fridgePin, OUTPUT);
pinMode(heaterPin, OUTPUT);
pinMode(humidPin, OUTPUT);
pinMode(heaterFanPin, OUTPUT);
dht1.begin();
dht2.begin();
sensors.begin();
Serial.begin(115200);
//Serial.println("This demo expects 3 pieces of data - text, an integer and a floating point value");
//Serial.println("Enter data in this style <HelloWorld, 12, 24.7> ");
//Serial.println();
}
void loop() {
// put your main code here, to run repeatedly:
analogWrite(heaterFanPin, heaterFanSpeed);
//digitalWrite(heaterFanPin, HIGH);
analogWrite(humidPin, humidityPower);
digitalWrite(fridgePin, fridgeState);
digitalWrite(heaterPin, heaterState);
recvWithStartEndMarkers();
if (newData == true) {
strcpy(tempChars, receivedChars);
// this temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with \0
parseData();
//showParsedData();
newData = false;
}
dht1Hum = dht1.readHumidity();
dht1Temp = dht1.readTemperature();
dht2Hum = dht2.readHumidity();
dht2Temp = dht2.readTemperature();
sensors.requestTemperatures();
T1 = sensors.getTempCByIndex(0);
T2 = sensors.getTempCByIndex(1);
T3 = sensors.getTempCByIndex(2);
// Serial.print(T1);
// Serial.print(" ");
// Serial.print(T2);
// Serial.print(" ");`
// Serial.println(T3);
// Serial.print(dht1Hum);
// Serial.print(" ");
// Serial.println(dht1Temp);
// Serial.print(dht2Hum);
// Serial.print(" ");
// Serial.println(dht2Temp);
s = "<" + String(dht1Hum) + "," + String(dht2Hum) + "," + String(dht1Temp) + "," + String(dht2Temp) + "," + String(T1) + "," + String(T2) + "," + String(T3) + ">";
Serial.println(s);
}
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
//============
void parseData() { // split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
//strtokIndx = strtok(tempChars, ","); // get the first part
//pullRequested = atoi(strtokIndx);
strtokIndx = strtok(tempChars, ",");
heaterState = atoi(strtokIndx);
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
fridgeState = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ",");
heaterFanSpeed = atoi(strtokIndx);// convert this part to an integer
strtokIndx = strtok(NULL, ",");
humidityPower = atoi(strtokIndx);// convert this part to an integer
}
//============
void showParsedData() {
Serial.print("heater state ");
Serial.println(heaterState);
Serial.print("fridgeState ");
Serial.println(fridgeState);
Serial.print("heaterFanSpeed ");
Serial.println(heaterFanSpeed);
Serial.print("humidityPower ");
Serial.println(humidityPower);
}
I send the arduino the control string <1,1,255,255> every time the arduino has finished reporting its data from the sensors.
I first thought the relays were killing the arduino repeatedly, which would turn the relays off, then arduino on and relay on, then arduino off and relay off, etc. etc.
So I placed the relay coils on a separate 5V source, since it was previosly on the same 5V buck converter as the raspi and the arduino.