Serial corruption when plugging in DC power supply

Hi,

I am pretty new to electronics, and I am lost as to what direction I need to be going in. I have a Wemos D1 mini powered by my PC and I am reading a serial output from a RJ-11 that connects to a fencing scoring machine called a Favero FA-05. I am trying to light up an LED strip according to the output of the serial connection. The LED strip is a 300 LED 16.4ft 5050SMD. I have a DC 5v 10a power supply with a barrel jack adapter. I understand this isn't an appropriate power supply, I am really just pushing 2 amps through the lights during this development. I will buy a more appropriate one later.

The corruption I am seeing is unexpected changes in a byte in my serial monitor output.
For example: a HEX string of when things are working without the LED power supply plugged in:

11:45:23.587 -> The message in HEX is: FF,0,0,0,0,0,0,0,30,0,

Then once I plug in the LED power supply (and nothing has changed on the fencing scoring machine), I get a bunch of output like this:

11:30:44.289 -> The message in HEX is: FF,0,0,0,0,0,0,0,10,0,
11:30:45.554 -> The message in HEX is: FF,7F,0,0,0,0,0,0,0,0,
11:30:45.882 -> The message in HEX is: FF,FD,0,0,0,0,0,0,0,0,

The issue I am coming across is that when I plug in the LED power supply, I start to get corruption/random output in the serial. The second I unplug the LED power, I am able to read the serial with no issues. I am thinking this is a noise issue, but I do not know for sure. I have tried adding capacitors for a noise filter, but I do not know if I am placing them in the correct spot.

I tried adding a 1μF capacitor between the LED power supply + and GND but I didn't see any difference. I also tried a 1000μF, and a 47μF. I also tried messing with the FastLED interrupt stuff, but I felt like that wasn't really relevant in this situation as I don't think I am missing the serial from an interrupt, I am getting false information on the serial output while the LED power supply is plugged in. Is my power supply just giving me "dirty" unstable power? Is there anything else I could try?

Code I am running:

#include <FastLED.h>
#define MY_NAME "REPEATER"

const unsigned int MAX_MESSAGE_LENGTH = 10;
const unsigned int MAX_SERIAL_BUFFER_BYTES = 512;
const char STARTING_BYTE = 255;

const int FOTL_DATA = 16;           // D2
const int FOTR_DATA = 15;         // D1
const int NUM_LEDS = 300; // Number of LEDs in your LED strip/matrix

CRGB left[NUM_LEDS]; // FOTL LED array
CRGB right[NUM_LEDS]; // FOTR LED array

struct __attribute__((packed)) dataPacket {
  int unsigned Right_Score;
  int unsigned Left_Score;
  int unsigned Seconds_Remaining;
  int unsigned Minutes_Remaining;
  bool Green_Light;
  bool Red_Light;
  bool White_Green_Light;
  bool White_Red_Light;
  bool Yellow_Green_Light;
  bool Yellow_Red_Light;
  bool Yellow_Card_Green;
  bool Yellow_Card_Red;
  bool Red_Card_Green;
  bool Red_Card_Red;
  bool Priority_Left;
  bool Priority_Right;
};

// Shows if new data is available for display
bool new_data = false;

// Initializes Message_Position
unsigned int message_pos = 0;

void setup() {

  FastLED.addLeds<WS2812, FOTL_DATA, GRB>(left, NUM_LEDS);
  FastLED.addLeds<WS2812, FOTR_DATA, GRB>(right, NUM_LEDS);
  FastLED.setMaxPowerInVoltsAndMilliamps(5, 8000); 

  Serial.setRxBufferSize(1024);
  Serial.begin(2400);  // initialize serial port
  delay(10);
  Serial.println();
  Serial.println();
  Serial.println();
  Serial.print("Initializing...");
  Serial.println(MY_NAME);
  Serial.println("Initialized.");
}

void loop() {

  EVERY_N_MILLISECONDS(200) {
    wdt_reset();
  }

  dataPacket packet;

  //  Check to see if anything is available in the serial receive buffer
  while (Serial.available() > 0) {

    //EVERY_N_MILLISECONDS(500) {
      //Serial.println("Checking available Serial Data.");
    //}

    // Create a place to hold the incoming message
    static char message[MAX_MESSAGE_LENGTH];
    static char prev_message[MAX_MESSAGE_LENGTH];

    char inByte = Serial.read();

    // Message coming in (check if starting character)
    if (inByte == STARTING_BYTE) {
      // Resets message position
      message_pos = 0;
      // Stores the Byte in the message position
      message[message_pos] = inByte;
      //increments message position
      message_pos++;
    } else if (message_pos < (MAX_MESSAGE_LENGTH - 1)) {
      // Stores the Byte in the message position
      message[message_pos] = inByte;
      //increments message position
      message_pos++;
    } else if (message_pos == (MAX_MESSAGE_LENGTH - 1)) {

      // Prints the Message if different from previous
      // Excudes the internal use byte in position 7 or check sum.
      if (message[1] != prev_message[1] or message[2] != prev_message[2] or message[3] != prev_message[3] or message[4] != prev_message[4] or message[5] != prev_message[5] or message[6] != prev_message[6] or message[8] != prev_message[8]) {
        // Sets New Data to True
        new_data = true;

        Serial.print("The message in HEX is: ");
        for (int i = 0; i < MAX_MESSAGE_LENGTH; i++) {
          Serial.print(message[i], HEX);
          Serial.print(",");
        }
        Serial.print('\n');
        /*
        Serial.print(message[5],BIN);
        Serial.println("");
        */

        // Assigns values from message to packet
        packet.Green_Light = bitRead(message[5], 3);
        packet.Red_Light = bitRead(message[5], 2);
        packet.White_Green_Light = bitRead(message[5], 1);
        packet.White_Red_Light = bitRead(message[5], 0);
        packet.Yellow_Green_Light = bitRead(message[5], 4);
        packet.Yellow_Red_Light = bitRead(message[5], 5);

        // Stuff not needed for repeaters
        packet.Yellow_Card_Green = bitRead(message[8], 2);
        packet.Yellow_Card_Red = bitRead(message[8], 3);
        packet.Red_Card_Green = bitRead(message[8], 0);
        packet.Red_Card_Red = bitRead(message[8], 1);

        packet.Priority_Right = bitRead(message[6], 2);
        packet.Priority_Left = bitRead(message[6], 3);

        // Stores the Score and Time
        packet.Right_Score = hex_string_to_int(message[1]);
        packet.Left_Score = hex_string_to_int(message[2]);
        packet.Seconds_Remaining = hex_string_to_int(message[3]);
        packet.Minutes_Remaining = hex_string_to_int(message[4]);

        // Sets Previous Message to Current Message
        for (int i = 0; i < MAX_MESSAGE_LENGTH; i++) {
          prev_message[i] = message[i];
        }

        // Resets Message Position
        message_pos = 0;

        // Clears the Serial Buffer if more than Max Buffer Bytes bytes in the buffer
        if (Serial.available() > MAX_SERIAL_BUFFER_BYTES) {
          Serial.println("...............Clearing the Serial Buffer...............");
          while (Serial.available() > 0) {
            char inByte = Serial.read();
          }
        }
        // Right fencer lights
        if (packet.Green_Light == 1) {
          fill_solid(right, NUM_LEDS, CRGB::Green); // On target right
          Serial.println("FOTR ON TARGET");
        } else if (packet.White_Green_Light == 1) {
          fill_solid(right, NUM_LEDS, CRGB::White); // Off target right
          Serial.println("FOTR OFF TARGET");
        } else {
          fill_solid(right, NUM_LEDS, CRGB::Black); // No light on right
          Serial.println("FOTR NO LIGHT");
        }
        // Left fencer lights
        if (packet.Red_Light == 1) {
          fill_solid(left, NUM_LEDS, CRGB::Red);
          Serial.println("FOTL ON TARGET");
        } else if (packet.White_Red_Light == 1) {
          fill_solid(left, NUM_LEDS, CRGB::White);
          Serial.println("FOTL OFF TARGET");
        } else {
          fill_solid(left, NUM_LEDS, CRGB::Black);
          Serial.println("FOTL NO LIGHT");
        }
        FastLED.show(); // Send the changes to the LEDs
      }
    } else {
      Serial.println("Unexpected Message Position, Reseting to zero.");
      message_pos = 0;
    }
  }
}

I tried a different power supply (5v 3a) and I had no serial corruption. I think my power supply is bad. I am going to replace it with a more appropriate one and see if it makes a difference.

Lights and other loads draw current. However, breadboards cannot handle such large currents, and the tracks burn, leading to unreliable connections. Breadboards are intended only for temporary experiments with low power logic circuitry.

The easiest fix is to power the lights and the Arduino separately. Solder the power supply connections, and connect all the grounds.

The Arduino must be powered by a supply with little to no electrical noise, or you should expect such malfunctions. There is an art to designing circuits that combine high current loads with MCUs, powered from a single supply. Look up "power supply decoupling" to learn more.

2 Likes

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