What parts of the following two codes cause the Arduino to output a constantly flickering pulse?

This is a mirrored question over on Stack Overflow, but since this forum deals with Arduino, I wanted to ask here in case this is just on the Arduino's end.

We have two bits of code here, one that runs in an RPi 3 Model B, and the other on an Arduino Uno. The Arduino UNO is connected to a set of 4 relays that each control a different component. For some reason, the COOLING_FAN_PIN always flickers rapidly between on and off, regardless of what pin its connected to, or whatever relay its connected to.

The relays themselves link power from a 220VAC source, the Arduino provides a 5VDC charge to trigger it.

These are the codes in question: GitHub

We've switched the Arduino pins around, to non-PWM pins and back, and the flickering still occurs, pull down resistors are included, changing the wires to see if they're the issue, changing the Serial interface, adding external power, and with common grounds.

With all that in mind, what should happen is that the relay only turns on and off when the appropriate signal is sent sensor data from the RPi, which then sends the appropriate command to the Arduino. Every other relay seems to be working fine, but it's just the COOLING_FAN_PIN that flickers constantly.

I would appreciate any bit of insight you might have as to why this is going on.

Your github link doesn't open for me. Suggest you just post your code, in code tags, like everyone else does, it's much more friendly. Many helpers won't even bother with the link, reducing your chances of help further.

1 Like

Alright, thanks for the heads up. Here's the code:

#include <Wire.h>

#define COOLING_FAN_PIN 10
#define EXHAUST_FAN_PIN 11
#define HEAT_LAMP_PIN 12
#define WINDOW_PIN 13

unsigned long startTime = millis();
const unsigned long duration = 35600;
String windowStatus = "closed";

void setup() {
  Serial.begin(9600);
  pinMode(COOLING_FAN_PIN, OUTPUT);
  pinMode(EXHAUST_FAN_PIN, OUTPUT);
  pinMode(HEAT_LAMP_PIN, OUTPUT);
  pinMode(WINDOW_PIN, OUTPUT);
}

void loop() {
  if (Serial.available()) {
    int command = Serial.read();
    Serial.println(command);
    switch (command) {
      case 1:
        openCloseWindow(windowStatus, "open", millis() - startTime);
        digitalWrite(EXHAUST_FAN_PIN, HIGH);
        digitalWrite(COOLING_FAN_PIN, HIGH);
        digitalWrite(HEAT_LAMP_PIN, LOW);
        break;

      case 2:
        openCloseWindow(windowStatus, "closed", millis() - startTime);
        digitalWrite(EXHAUST_FAN_PIN, LOW);
        digitalWrite(COOLING_FAN_PIN, LOW);
        digitalWrite(HEAT_LAMP_PIN, HIGH);
        break;

      case 3:
        openCloseWindow(windowStatus, "open", millis() - startTime);
        digitalWrite(EXHAUST_FAN_PIN, LOW);
        digitalWrite(COOLING_FAN_PIN, HIGH);
        digitalWrite(HEAT_LAMP_PIN, LOW);
        break;

      case 4:
        openCloseWindow(windowStatus, "closed", millis() - startTime);
        digitalWrite(EXHAUST_FAN_PIN, HIGH);
        digitalWrite(COOLING_FAN_PIN, LOW);
        digitalWrite(HEAT_LAMP_PIN, HIGH);
        break; 
      case 5:
        openCloseWindow(windowStatus, "open", millis() - startTime);
        digitalWrite(EXHAUST_FAN_PIN, LOW);
        digitalWrite(COOLING_FAN_PIN, LOW);
        digitalWrite(HEAT_LAMP_PIN, LOW);
        break;
      case 6:
        openCloseWindow(windowStatus, "closed", millis() - startTime);
        digitalWrite(EXHAUST_FAN_PIN, HIGH);
        digitalWrite(COOLING_FAN_PIN, LOW);
        digitalWrite(HEAT_LAMP_PIN, LOW);
        break;
      case 7:
        openCloseWindow(windowStatus, "closed", millis() - startTime);
        digitalWrite(EXHAUST_FAN_PIN, LOW);
        digitalWrite(COOLING_FAN_PIN, HIGH);
        digitalWrite(HEAT_LAMP_PIN, LOW);
        break;
      case 8:
        openCloseWindow(windowStatus, "open", millis() - startTime);
        break;
      case 9:
        digitalWrite(EXHAUST_FAN_PIN, HIGH);
        break;
      case 10:
        digitalWrite(COOLING_FAN_PIN, HIGH);
        break;
      case 11:
        digitalWrite(HEAT_LAMP_PIN, HIGH);
        break;
      case 12:
        openCloseWindow(windowStatus, "closed", millis() - startTime);
        break;
      case 13:
        digitalWrite(EXHAUST_FAN_PIN, LOW);
        break;
      case 14:
        digitalWrite(COOLING_FAN_PIN, LOW);
        break;
      case 15:
        digitalWrite(HEAT_LAMP_PIN, LOW);
        break;
      case 0:
      default:
        openCloseWindow(windowStatus, "closed", millis() - startTime);
        digitalWrite(EXHAUST_FAN_PIN, LOW);
        digitalWrite(COOLING_FAN_PIN, LOW);
        digitalWrite(HEAT_LAMP_PIN, LOW);
        break;
    }
  }
}

void openCloseWindow(String &currentStatus, String triggerStatus, unsigned long time) { //Window doesn't have any detection for open-close, only rotates when powered
  if (currentStatus != triggerStatus && time > duration) {
    digitalWrite(WINDOW_PIN, LOW);
    delay(2500);
    digitalWrite(WINDOW_PIN, HIGH);
    startTime = millis();
    currentStatus = triggerStatus;
  }
}

Okay. So, are you aware of ASCII values vs numerics? Your serial read is receiving ASCII, but your code is looking for values like 1, 2, etc.

It's not coincidental that carriage return (0x0D) and line feed (0x0A) end every send from Serial Monitor unless you change the default, and those are values 10 and 13 in your case statement.

Would it change anything if the RPi sends the data as bytes?

Can't say, don't think so, though. It would depend. I see @Delta_G may want to chip in, let's see what he has to say

From what I understood of the forum rules, the rule for double posting only referred to the Arduino forums? I had posted it on Stack Overflow earlier, not on here. If I made a mistake regarding that, then I apologize.

Regardless, the thing is, the entire thing was working when we tested on Monday. I don't know if someone changed part of it or not, but testing it today showed the flickering issue. I just want to make sure that it isn't on the Arduino side, or if it is, point it out for me.

I see. Well, in that case, I think that Stack Overflow would be a better forum since this project also involves an RPi.

Thanks @camsysca for your answer. I'll see if changing the serial read changes anything. I just can't test it right now as I don't have access to the project right now.

Then you numeric compare would work as intended, but your still have the CR, LF to take care of.

Okay. Had we pursued this, I'd have suggested you use plain character commands, instead of int values; that, of course, requires changes on the pi side, but it makes it easier to test the Arduino side independently, just using the Serial Monitor.
Whatever.

Why use Strings? If it's just for nice reading, you could change the function parameters like

void openCloseWindow(byte &currentStatus, byte triggerStatus, unsigned long time)
{
// ... 
}

having previously

# define CLOSED 0
# define OPEN   1

byte windowStatus = CLOSED;

and then call the function like

openCloseWindow(windowStatus, CLOSED, millis() - startTime);

Microprocessors have limited resources, minding the little bits is a good habit to get into. The code is perfectly happier dealing with the window status as a simple number.

a7

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.