Hello everyone,
In the last days I'm confronting with a problem in my code that I can't solve. Before I start explaining, I'm new to coding and arduino, or any controllers. I've spend some weeks, learning and adding parts to a code that I try to make it work.
Brief explanation of what I want to do: I have Home Assistant on a old PC, that speak to an esp32 via MQTT, exp32 needs to relay information's from and to an arduino due, that need to grab sensors data and controlling relays.
This is a "cutout" from my main code, for debug purpose, also it's made from an example found here serial-input-basics-updated. And this must receive commands from esp32, process them and execute, turn relay, corresponding to relay pin, on or off. As shown in the screenshot, commands from esp32 via MQTT are coming as it should, so I think the problem is laying in this code.
[code]
// Example 3 - Receive with start- and end-markers
#define NUM_ELEMENTS(x) (sizeof(x) / sizeof((x)[0]))
// Serial
const byte numChars = 32;
char receivedChars[numChars];
boolean newData = false;
int relayPins [2][8] {
{53, 52, 51, 50, 49, 48, 47, 46}, // 8 Chan Relay Board: [1] = Cooling box fan, [2] = Valve, [3] = Valve, [4] = Mixing jars, [5] = Presure pomp(water to plants);
{45, 44, 43, 42} // 4 Chan Relay Board: [1] = Presure pomp, [2] = In res mix pomp, [3] = UV pomp, [4] = UV lamp(+2000 over 'UV pomp');
};
void setup() {
Serial.begin(9600);
Serial3.begin(9600);
Serial.println("<Due is ready!>");
delay(500);
for (int i = 0; i <= 1; i++) {
for (int j = 0; j <= NUM_ELEMENTS(relayPins[i]); j++) {
pinMode(relayPins[i][j], OUTPUT);
digitalWrite(relayPins[i][j], HIGH);
}
}
}
void loop() {
recvWithStartEndMarkers();
processSerialData();
showNewData();
}
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial3.available() > 0 && newData == false) {
rc = Serial3.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 showNewData() {
if (newData == true) {
Serial.println(receivedChars);
newData = false;
}
}
void processSerialData() {
while (newData == true) {
char cmdChar = receivedChars[0];
switch (cmdChar) {
case 'R': // Message starts with "R" = relays. Format is "Relay:<BOARD#>:<RELAY#>:<STATUS>". Example: "Relay:0:4:1"
{
int boardNumber;
int relayNumber;
int relayPower;
char* strtokIndx;
char buff[20];
strtokIndx = strtok(receivedChars, ":"); // Skip the first segment which is the 'R' character
strtokIndx = strtok(NULL, ":"); // Get the board number
boardNumber = atoi(strtokIndx);
strtokIndx = strtok(NULL, ":"); // Get the relay number
relayNumber = atoi(strtokIndx);
strtokIndx = strtok(NULL, ":"); // Get the relay power state
relayPower = atoi(strtokIndx);
triggerRelay(boardNumber, relayNumber, relayPower);
sprintf(buff, "<Relay FB:%d:%d:%d>", boardNumber, relayNumber, relayPower);
Serial3.println(buff);
Serial.println(buff);
break;
}
}
}
newData = false;
}
void triggerRelay(int boardNumber, int relayNumber, int relayTrigger) {
char buff[50];
sprintf(buff, "Triggering board:%d, relay:%d, state: %d", boardNumber, relayNumber, relayTrigger);
Serial.println(buff);
if (relayTrigger == 1) {
digitalWrite(relayPins[boardNumber][relayNumber], LOW); // Turn relay ON
}
else if (relayTrigger == 0) {
digitalWrite(relayPins[boardNumber][relayNumber], HIGH); // Turn relay OFF
}
}
[/code]
After some debugs, it seems playing with delay and removing both "for", from the setup(), give different outcomes.
Adding delay make the text <Due is ready!> to appear in serial monitor but nothing is showing up from esp32, no commands, nothing. First 2 lines from the screenshot, show this.
Deleting the delay make due only printing first character from the message "<Due is ready!>", that's "<", as show in the third line from the screenshot.
Removing this:
for (int i = 0; i <= 1; i++) {
for (int j = 0; j <= NUM_ELEMENTS(relayPins[i]); j++) {
pinMode(relayPins[i][j], OUTPUT);
digitalWrite(relayPins[i][j], HIGH);
}
}
Makes due to work almost properly, when it starts, the message <Due is ready!> appear and when I send a command to turn 1 relay on, the command is coming in and the feedback line, "Triggering board...." it's working as it should, problem is right after this when due keeps printing a command and it's keep triggering that relay. But as in every case the actual relay it's never turning on or off.
Also I didn't made a debug code from esp32, it's keep running the main one, I don't think it matter as the commands to turn relay on or off are coming in as they should, but thought it's good to point this out as well.
