Controlling LEDS with Shift registers, Arduino, and Raspberry PI

Hello,
I am controlling about 22 LEDs using 3 shift registers and an Arduino UNO, The Arduino UNO receives a string over serial messages from a Raspberry PI. This pi sends a string of either 1s or 0s that determine whether an LED is either on or off. The void loop in the Arduino IDE iterates through the string and based off of whether or not its a 1 or a 0, will then turn that corresponding LED on or off. 22 LEDs so the string has 22 1s or 0s. When everything is plugged in and connected it all works fine, till about after approximately 10 minutes. It seems to always be about 10 mins, all LEDS turn off. The Raspberry Pi is still sending out a string with 1s or 0s. But all the LEDS are still all off after 10 mins. I am confused as to what is causing this considering that it all works just fine till about 10 minutes in. I am wondering if there is a limit to the amount of serial data can be sent to the Arduino? and if so is there a way to clear it after each cycle so that way it can run indefinitely? I will post my code for both the Pi and the Uno below. Thank you for any information you can give me.

Pi code in Python3

def clear_lights(red_lightboard): ## Function for clearing all LEDS
    message='r0000000000000000000000\n'
    red_lightboard.write(message.encode('utf-8')) # writes the serial message that turns all LEDS off

red_lightboard = serial.Serial('/dev/ttyACM0',115200, timeout=1) # Sets up serial comm with arduino uno using usb connection
red_lightboard.reset_input_buffer() # clears any data in the input buffer
while True:
    clear_lights(red_lightboard) # clears lights on board
    red_stop_pins=red_stops() # Calls the function that obtains the LED positions of the current train stops
    Rlen = len(stop_pins.red)
    Rstring = [0] * Rlen # Preallocates a variable that will be sent to the arduino
    for i in range(0,len(red_stop_pins)): # If a train is stopped at the current stop, changes the value in the array from 0 to 1
        Rstring[red_stop_pins[i]] = 1
    R = ''.join(map(str,Rstring))
    print(R)
    testLED = 'r' + R + '\n'
    red_lightboard.write(testLED.encode('utf-8')) # message to arduino over serial
    time.sleep(60) # Pauses for 60 seconds before sending another message

Arduino Uno code

#include <Shifty.h>

Shifty reg_red;

const int NUM_red_STATIONS = 22;



// setup the shift registers and begin serial transmission
void setup() {
  reg_red.setBitCount(24);
  reg_red.setPins(11, 12, 8);
  
  Serial.begin(115200);
}

// the loop function runs over and over again forever
void loop() {
  // wait for a string to be send via serial,
  // in the form of "r***...*", where * is either a "1" or "0"
  while(Serial.available() > 0 ){
    String str = Serial.readStringUntil('\n');
    if (str.substring(0,1) == "r") {
      reg_red.batchWriteBegin();
      clear_lights();
      for (int i = 1; i <= NUM_red_STATIONS; i++) {
        if (str.substring(i, i+1) == "1") {
          reg_red.writeBit((i - 1), HIGH);
        }
        else if (str.substring(i, i+1) == "0") {
          reg_red.writeBit((i - 1), LOW);
        }
      }
      reg_red.batchWriteEnd();
    }
  }
}

void clear_lights() {
  for (int i = 0; i < NUM_red_STATIONS; i++) {
    reg_red.writeBit(i, LOW);
  }
}

No. But yes.

If the Arduino code does not read the serial data, it gets saved in a buffer. That buffer has a small limited size, 64 bytes I think. If the buffer gets full, the oldest bytes start to get overwritten, which can result in long messages getting partially lost. That's why it's a good idea to do what you have done and have marker characters at the start and end of the message (in your case 'r' and '\n').

As long as the Arduino code keeps reading the serial data from the buffer, the buffer won't get full and nothing will be lost.

They don't just freeze with the last pattern and not update again? The LEDs always go off after 10 mins?

I think that in 10 mins, your python code will have sent 20 messages, correct? That's not a high number of messages, so you could perform a test by hand to see if you get the same behaviour. You could not run your python code but instead use Serial Monitor to send the messages one at a time by pasting them into serial monitor and hitting send. Does this cause the LEDs to go off after approximately 20 messages?

If it does, because you are using serial monitor, you can have your Arduino code send messages back to help you debug the problem.

suggest you confirm that the Arduino is at least receiving expected messages

i'm surpised that you're actually sending segment values from the PC. why not send the digits that you want displayed and let the arduino encode the segments. you toggle the LED_BUILTIN whenever a valid msg is received

you could write some test code that just displays a count on the display to verify that the Arduino code can run longer than 10 mins

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