Code works when plugged in but not when powered by battery

My code runs as desired when plugged into the USB, but not when powered only by battery. I tried it on an identically wired project and got the same results, so I know it’s not a wiring/hardware issue. I also eliminated any calls to the serial port.

When plugged in, the LED strip LEDRing is gray and black, which is the default resting state. When the acceleratometer breaks threshold, the LEDRing lights do a 2 part, 100ms each animation of alternating orangered and aqua before reverting back to the black and grey resting state.

However when it runs from battery power, the functionality of the buttons and sensors all still work, but the resting state of the LEDRing is Redorange and Aqua, as if it is permanently stuck in one of the animation frames.

/*Wiring notes
 * 
 * buttons wired from Digital Pin thru button to GND
 * 
 * ACCELEROMETER
 * AD0 and GND to GND
 * VCC to 5V
 * SDA & SCL to Arduino SDA & SCL
 * 
 */





//include Ultrasonic library
#include "SR04.h"

//define ultrasonic pins
#define TRIG_PIN 15
#define ECHO_PIN 16

//initialize ultrasonic
SR04 sr04 = SR04(ECHO_PIN,TRIG_PIN);
long swish;

//define button pins
#define PinT1Up 2
#define PinT1Dn 3
#define PinT2Up 4
#define PinT2Dn 5

//include accelerometer libraries
#include "I2Cdev.h"
#include "MPU6050.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
#endif

//initialize accel parameters
MPU6050 accelgyro;

long az;
long azoff=-15800;
long accelSens = 1200;
unsigned long timeSlam;

//define LED strip parameters
#include "FastLED.h"
#define NUM_LEDS_SCORE 21
#define NUM_LEDS_RING 29
#define T1LED_PIN 6
CRGB T1leds[NUM_LEDS_SCORE];
#define T2LED_PIN 7
CRGB T2leds[NUM_LEDS_SCORE];
#define RINGLED_PIN 8
CRGB Ringleds[NUM_LEDS_RING];

// initiate scores and buttons
int T1Score = 0;
int T2Score = 0;
byte T1UpState = HIGH;
byte T1DnState = HIGH;
byte T2UpState = HIGH;
byte T2DnState = HIGH;
int buttonDelay = 10;

unsigned long ms = 0;

void setup() {
// Serial.begin(9600);

  //set pins up
  pinMode(PinT1Up, INPUT_PULLUP);
  pinMode(PinT1Dn, INPUT_PULLUP);
  pinMode(PinT2Up, INPUT_PULLUP);
  pinMode(PinT2Dn, INPUT_PULLUP);

  //set up LED strips
  FastLED.addLeds<NEOPIXEL, T1LED_PIN>(T1leds, NUM_LEDS_SCORE);
  FastLED.addLeds<NEOPIXEL, T2LED_PIN>(T2leds, NUM_LEDS_SCORE);
  FastLED.addLeds<NEOPIXEL, RINGLED_PIN>(Ringleds, NUM_LEDS_RING);

       // join I2C bus (I2Cdev library doesn't do this automatically)
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif

    // initialize device
    //Serial.println("Initializing I2C devices...");
    accelgyro.initialize();

    // verify connection
    //Serial.println("Testing device connections...");
    //Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");


    //get accel offset from resting average accel
  {
  unsigned int q = abs(accelgyro.getAccelerationZ());
  delay (10);
  unsigned int r = abs(accelgyro.getAccelerationZ());
  delay (10);
  unsigned int s = abs(accelgyro.getAccelerationZ());
  azoff = ((q + r + s) / 3);
  }
}

//LLLLLLLLLLLLOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOPPPPPPPPPPPPPPPPP

void loop() {
  //get button states
  T1UpState = digitalRead(PinT1Up);
  T1DnState = digitalRead(PinT1Dn);
  T2UpState = digitalRead(PinT2Up);
  T2DnState = digitalRead(PinT2Dn);

  //set current millis time to variable
  ms = millis();

  //check for bag landing and flash ring
  az = long(accelgyro.getAccelerationZ());
         if (abs(abs(az)-azoff) > accelSens){
          timeSlam = ms;
        }

  //check for bag swish and rainbow ring
   swish=sr04.Distance();
        if (swish < 25 && swish > 0){
          for (int n = 0; n < NUM_LEDS_RING+40; n++){
            Ringleds[max(n,0)] = CRGB::Red;
            Ringleds[max(n-1,0)] = CRGB::OrangeRed;
            Ringleds[max(n-2,0)] = CRGB::Yellow;
            Ringleds[max(n-3,0)] = CRGB::Green;
            Ringleds[max(n-4,0)] = CRGB::Blue;
            Ringleds[max(n-5,0)] = CRGB::Purple;
            Ringleds[max(n-6,0)] = CRGB::Black;
            Ringleds[max(n-13,0)] = CRGB::Red;
            Ringleds[max(n-14,0)] = CRGB::OrangeRed;
            Ringleds[max(n-15,0)] = CRGB::Yellow;
            Ringleds[max(n-16,0)] = CRGB::Green;
            Ringleds[max(n-17,0)] = CRGB::Blue;
            Ringleds[max(n-18,0)] = CRGB::Purple;
            Ringleds[max(n-19,0)] = CRGB::Black;
            Ringleds[max(n-27,0)] = CRGB::Red;
            Ringleds[max(n-28,0)] = CRGB::OrangeRed;
            Ringleds[max(n-29,0)] = CRGB::Yellow;
            Ringleds[max(n-30,0)] = CRGB::Green;
            Ringleds[max(n-31,0)] = CRGB::Blue;
            Ringleds[max(n-32,0)] = CRGB::Purple;
            Ringleds[max(n-33,0)] = CRGB::Black;
            FastLED.show();
            delay(20);
          }
          timeSlam = (ms - 200L); //cancel slam animation
        }
        
        
  //check button presses and increment scores
  if ((T1UpState == LOW) && (T1DnState == HIGH))
  {
    T1Score++;
    T1Score = constrain(T1Score, 0, 21);
    while ((digitalRead(PinT1Up) == LOW) && (digitalRead(PinT1Dn) == HIGH));
    delay(buttonDelay);
  }
  if ((T1UpState == HIGH) && (T1DnState == LOW))
  {
    T1Score--;
    T1Score = constrain(T1Score, 0, 21);
    while ((digitalRead(PinT1Up) == HIGH) && (digitalRead(PinT1Dn) == LOW));
    delay(buttonDelay);
  }
  if ((T2UpState == LOW) && (T2DnState == HIGH))
  {
    T2Score++;
    T2Score = constrain(T2Score, 0, 21);
    while ((digitalRead(PinT2Up) == LOW) && (digitalRead(PinT2Dn) == HIGH));
    delay(buttonDelay);
  }
  if ((T2UpState == HIGH) && (T2DnState == LOW))
  {
    T2Score--;
    T2Score = constrain(T2Score, 0, 21);
    while ((digitalRead(PinT2Up) == HIGH) && (digitalRead(PinT2Dn) == LOW));
    delay(buttonDelay);
  }
 
  //show scores on LED strips
  for (int i = 0; i < T1Score; i++) {
    T1leds[20-i] = CRGB::Aqua;
    if ((20-i-1) % 5 == 0) {
      T1leds[20-i] = CRGB::OrangeRed;
    }
  }
  for (int j = T1Score; j<21; j++) {
    T1leds[20-j] = CRGB::Black;
  }
  for (int k = 0; k < T2Score; k++) {
    T2leds[20-k] = CRGB::OrangeRed;
    if ((20-k-1) % 5 == 0) {
      T2leds[20-k] = CRGB::Aqua;
    }
  }
  for (int m = T2Score; m<21; m++) {
    T2leds[20-m] = CRGB::Black;
  }


  if((ms - timeSlam) < 100){
          for (int n = 0; n < NUM_LEDS_RING; n++){
            if (n % 2 == 0) Ringleds[n] = CRGB::Aqua;
             else Ringleds[n] = CRGB::OrangeRed;//Slammer animation frame 1
          }
  } else if((ms - timeSlam) < 200){
          for (int n = 0; n < NUM_LEDS_RING; n++){
            if (n % 2 == 0) Ringleds[n] = CRGB::OrangeRed;
            else Ringleds[n] = CRGB::Aqua;//Slammer animation frame 2
          }
  } else {
         for (int n = 0; n < NUM_LEDS_RING; n++){
            if (((n+1) % 4) == 0) Ringleds[n] = CRGB::DarkGrey;
            else Ringleds[n] = CRGB::Black;
            }
          }

  FastLED.show();
}

Do you have a meter? I suspect you are experiencing voltage drop. What type of battery are you using? How many LEDs are you driving?

I do have a meter. The weird thing is, the old version of the code below works perfectly fine. Same number of LEDs, same physical setup, just different code. Also all of the LEDs are powered from their own voltage regulators directly to the battery. The Arduino is taking 9V from my battery pack straight into Vin:

/*Wiring notes
 * 
 * buttons wired from Digital Pin thru button to GND
 * 
 * ACCELEROMETER
 * AD0 and GND to GND
 * VCC to 5V
 * SDA & SCL to Arduino SDA & SCL
 * 
 */





//include Ultrasonic library
#include "SR04.h"

//define ultrasonic pins
#define TRIG_PIN 15
#define ECHO_PIN 16

//initialize ultrasonic
SR04 sr04 = SR04(ECHO_PIN,TRIG_PIN);
long swish;

//define button pins
#define PinT1Up 4
#define PinT1Dn 5
#define PinT2Up 2
#define PinT2Dn 3

//include accelerometer libraries
#include "I2Cdev.h"
#include "MPU6050.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
#endif

//initialize accel parameters
MPU6050 accelgyro;

int16_t az;
int16_t azoff=-15800;
int16_t accelSens = 1000;
boolean slammer = false;

//define LED strip parameters
#include "FastLED.h"
#define NUM_LEDS_SCORE 21
#define NUM_LEDS_RING 29
#define T1LED_PIN 7
CRGB T1leds[NUM_LEDS_SCORE];
#define T2LED_PIN 6
CRGB T2leds[NUM_LEDS_SCORE];
#define RINGLED_PIN 8
CRGB Ringleds[NUM_LEDS_RING];

// initiate scores and buttons
int T1Score = 0;
int T2Score = 0;
byte T1UpState = HIGH;
byte T1DnState = HIGH;
byte T2UpState = HIGH;
byte T2DnState = HIGH;
int buttonDelay = 10;

void setup() {
 Serial.begin(9600);
  
  //set pins up
  pinMode(PinT1Up, INPUT_PULLUP);
  pinMode(PinT1Dn, INPUT_PULLUP);
  pinMode(PinT2Up, INPUT_PULLUP);
  pinMode(PinT2Dn, INPUT_PULLUP);

  //set up LED strips
  FastLED.addLeds<NEOPIXEL, T1LED_PIN>(T1leds, NUM_LEDS_SCORE);
  FastLED.addLeds<NEOPIXEL, T2LED_PIN>(T2leds, NUM_LEDS_SCORE);
  FastLED.addLeds<NEOPIXEL, RINGLED_PIN>(Ringleds, NUM_LEDS_RING);

       // join I2C bus (I2Cdev library doesn't do this automatically)
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif

    // initialize device
    //Serial.println("Initializing I2C devices...");
    accelgyro.initialize();

    // verify connection
    //Serial.println("Testing device connections...");
    //Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
  
}

//LLLLLLLLLLLLOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOPPPPPPPPPPPPPPPPP

void loop() {
  //get button states
  T1UpState = digitalRead(PinT1Up);
  T1DnState = digitalRead(PinT1Dn);
  T2UpState = digitalRead(PinT2Up);
  T2DnState = digitalRead(PinT2Dn);

  //check for bag landing and flash ring
  az = accelgyro.getAccelerationZ();
         if (abs(az)+azoff > accelSens){
          slammer = true;
        }

  //check for bag swish and rainbow ring
   swish=sr04.Distance();
        if (swish < 20 && swish > 0){
          for (int n = 0; n < NUM_LEDS_RING+40; n++){
            Ringleds[max(n,0)] = CRGB::Red;
            Ringleds[max(n-1,0)] = CRGB::OrangeRed;
            Ringleds[max(n-2,0)] = CRGB::Yellow;
            Ringleds[max(n-3,0)] = CRGB::Green;
            Ringleds[max(n-4,0)] = CRGB::Blue;
            Ringleds[max(n-5,0)] = CRGB::Purple;
            Ringleds[max(n-6,0)] = CRGB::Black;
            Ringleds[max(n-13,0)] = CRGB::Red;
            Ringleds[max(n-14,0)] = CRGB::OrangeRed;
            Ringleds[max(n-15,0)] = CRGB::Yellow;
            Ringleds[max(n-16,0)] = CRGB::Green;
            Ringleds[max(n-17,0)] = CRGB::Blue;
            Ringleds[max(n-18,0)] = CRGB::Purple;
            Ringleds[max(n-19,0)] = CRGB::Black;
            Ringleds[max(n-27,0)] = CRGB::Red;
            Ringleds[max(n-28,0)] = CRGB::OrangeRed;
            Ringleds[max(n-29,0)] = CRGB::Yellow;
            Ringleds[max(n-30,0)] = CRGB::Green;
            Ringleds[max(n-31,0)] = CRGB::Blue;
            Ringleds[max(n-32,0)] = CRGB::Purple;
            Ringleds[max(n-33,0)] = CRGB::Black;
            FastLED.show();
            delay(20);
            
          }
          Ringleds[0] = CRGB::DarkGrey;
          Ringleds[4] = CRGB::DarkGrey;
          Ringleds[8] = CRGB::DarkGrey;
          Ringleds[12] = CRGB::DarkGrey;
          Ringleds [16] = CRGB::DarkGrey;
          Ringleds[20] = CRGB::DarkGrey;
          Ringleds[24] = CRGB::DarkGrey;
        }
        
        
  //check button presses and increment scores
  if ((T1UpState == LOW) && (T1DnState == HIGH))
  {
    T1Score++;
    T1Score = constrain(T1Score, 0, 21);
    while ((digitalRead(PinT1Up) == LOW) && (digitalRead(PinT1Dn) == HIGH));
    delay(buttonDelay);
  }
  if ((T1UpState == HIGH) && (T1DnState == LOW))
  {
    T1Score--;
    T1Score = constrain(T1Score, 0, 21);
    while ((digitalRead(PinT1Up) == HIGH) && (digitalRead(PinT1Dn) == LOW));
    delay(buttonDelay);
  }
  if ((T2UpState == LOW) && (T2DnState == HIGH))
  {
    T2Score++;
    T2Score = constrain(T2Score, 0, 21);
    while ((digitalRead(PinT2Up) == LOW) && (digitalRead(PinT2Dn) == HIGH));
    delay(buttonDelay);
  }
  if ((T2UpState == HIGH) && (T2DnState == LOW))
  {
    T2Score--;
    T2Score = constrain(T2Score, 0, 21);
    while ((digitalRead(PinT2Up) == HIGH) && (digitalRead(PinT2Dn) == LOW));
    delay(buttonDelay);
  }
 
  //show scores on LED strips
  for (int i = 0; i < T1Score; i++) {
    T1leds[20-i] = CRGB::Aqua;
    if ((20-i-1) % 5 == 0) {
      T1leds[20-i] = CRGB::OrangeRed;
    }
  }
  for (int j = T1Score; j<21; j++) {
    T1leds[20-j] = CRGB::Black;
  }
  for (int k = 0; k < T2Score; k++) {
    T2leds[20-k] = CRGB::OrangeRed;
    if ((20-k-1) % 5 == 0) {
      T2leds[20-k] = CRGB::Aqua;
    }
  }
  for (int m = T2Score; m<21; m++) {
    T2leds[20-m] = CRGB::Black;
  }

  if(slammer == true){
          for (int n = 0; n < NUM_LEDS_RING; n++){
            if (n % 2 == 0) Ringleds[n] = CRGB::Aqua;
            else Ringleds[n] = CRGB::OrangeRed;
          }
         FastLED.show();
         delay(100);
          for (int n = 0; n < NUM_LEDS_RING; n++){
            if (n % 2 == 0) Ringleds[n] = CRGB::OrangeRed;
            else Ringleds[n] = CRGB::Aqua;
          }
         FastLED.show();
         delay(100);
         for (int n = 0; n < NUM_LEDS_RING; n++){
            Ringleds[n] = CRGB::Black;
          }
          slammer = false;
  }

//Dimly illuminate ring
  Ringleds[0] = CRGB::DarkGrey;
  Ringleds[4] = CRGB::DarkGrey;
  Ringleds[8] = CRGB::DarkGrey;
  Ringleds[12] = CRGB::DarkGrey;
  Ringleds[16] = CRGB::DarkGrey;
  Ringleds[20] = CRGB::DarkGrey;
  Ringleds[24] = CRGB::DarkGrey;
  
  FastLED.show();
  //Serial.print(slammer);
}

The main difference between this old code and the new broken code is that I removed a delay() from the animation and replaced it with a millis() setup, which is when the problem reared its head.

If i start up plugged into the computer and then unplug, it still works perfectly fine. It’s only when I boot up from battery power than the issue comes up.

Power comes from a pack of 6 AAs. I am driving the Arduino straight from the battery pack. Then I have 4 voltage regulators, one wired up to the 4 LED lit buttons, and each of the other 3 wired to an addressable LED strip of 21, 21, and 29 LEDs respectively.

If the USB cable is connected and the external power supply is on, everything works perfectly.
If I then unplug the USB cable, everything continues to work perfectly.
If while unplugged I cycle the power, then the issue comes up.
Also, if I cycle the Arduino via the reset button while it is plugged in and working, everything continues to work fine.
If I have the USB plugged into a separate 5V power souce (like a phone charger) I have the same issue. It only seems to work if it's specifically plugged into the computer.

It seems that the IF statement at the end of my sketch that decides how to light the LEDRing based on how long it has been since the accelerometer was trigger is evaluating differently depending on whether the arduino was plugged into the computer or not when it booted.

Help?

What is the different code?

For example, if the LED program is different, it would represent a different current draw.

For example, if you programmed 10 leds to turn on to full brightness red, they would draw about

20ma for red *10leds is 200ma

for white, full brightness

20ma for red + 20ma for green + 20ma for blue = 60ma for white

60ma * 10 = 600ma

that is three times the current draw, using the same exact code except for one line. Use the meter to test the voltage at the end of the strip (far end, opposite of where the power is fed in)

Could also be an issue with grounding of the led strips.

Use your dmm continuity tester to check for continuity of ground between the led pins and the arduino ground pin with the usb cable unplugged.

Hi,

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
Please include ALL your power supply wiring.

Thanks.. Tom... :slight_smile:

The main difference between this old code and the new broken code is that I removed a delay() from the animation and replaced it with a millis() setup, which is when the problem reared its head. Like I previously said, if I upload the sketch and then remove the USB cable, the program continues to run perfectly fine.

The old code worked perfectly fine and the lighting sequences are exactly the same. The millis() timing thing is when I got issues.

This is why I really don't think it's a wiring/power supply issue. But here's my wiring diagram anyway:

This is just the power wiring and the LED strip Din wiring. There is also an accelerometer and ultrasonic sensor wired to the arduino but they receive their 5V power from the 5V pin on the Arduino. They are the only things actually drawing their power through the arduino.

Here is a video of the issue:

Hi,
Where are all the capacitors that are supposed to be around each of the 78 series regulators?
Please consult the data sheets.

Where is is the accell and sonar units in the diagram?
A complete circuit diagram please.

I am surprised for such a professionally looking project you have no proper schematics.

Tom... :slight_smile: