Atmega 328P power source supply problem

So I made a standalone circuit for a night light that fades through the visible spectrum with an RGB LED.

When I plug in the power leads into the 3.3 or 5V and ground on my arduino uno, it works perfectly.

I want to power it from three 1.5V button cells for a total of 4.5V. When I attach the power leads to the batteries, the light flickers, when changing from red to green (mostly in the yellow area), and it is a lot dimmer (even when compared to 3.3V in arduino).

I installed a 0.1uF capacitor across the 4.5V and ground power leads, it didn’t seem to make a difference.

Any thoughts or ideas how to make this work? Would it be better to use a 12V battery and regulate the voltage down to 5V?

I have attached a circuit diagram (except it is just a chip, no arduino, same circuit) and code in case it is useful.

#define GREEN 3
#define BLUE 5
#define RED 6
#define delayTime 120
int ldr = 1; //Define photosensor in Analog port 1
int lightinput = 0; //Default value for lightinput is zero
int trigger = 350; //Threshold value of light to trigger activation.
//I have found between 200 and 600 works best. You don't want it so
//sensitive that it detects itself and flickers at the end of it's
//cycle.

void setup() {

  pinMode(GREEN, OUTPUT); //define as digital outputs
  pinMode(BLUE, OUTPUT);
  pinMode(RED, OUTPUT);
  digitalWrite(GREEN, HIGH); //I am using a common ANODE LED so a value
  digitalWrite(BLUE, HIGH); //of HIGH is off, and LOW is full brightness.
  digitalWrite(RED, HIGH); //Opposite for common CATHODE LEDs
}

int redVal;
int blueVal;
int greenVal;
 
void loop() {
  lightinput = analogRead(ldr); //difine lightinput as value from photosensor
  if (lightinput < trigger) //compare value to threshold trigger
  { //open if statement (if DARK)
  int redVal = 255;
  int blueVal = 0;
  int greenVal = 0;
  for( int i = 0 ; i < 255 ; i += 1 ){
    greenVal += 1;
    redVal -= 1;
    analogWrite( GREEN, 255 - greenVal );
    analogWrite( RED, 255 - redVal );

    delay( delayTime );
  }
 
  redVal = 0;
  blueVal = 0;
  greenVal = 255;
  for( int i = 0 ; i < 255 ; i += 1 ){
    blueVal += 1;
    greenVal -= 1;
    analogWrite( BLUE, 255 - blueVal );
    analogWrite( GREEN, 255 - greenVal );

    delay( delayTime );
  }
 
  redVal = 0;
  blueVal = 255;
  greenVal = 0;
  for( int i = 0 ; i < 255 ; i += 1 ){
    redVal += 1;
    blueVal -= 1;
    analogWrite( RED, 255 - redVal );
    analogWrite( BLUE, 255 - blueVal );

    delay( delayTime );
  }
  } //close if statement
  else
  { //open else (if LIGHT)
  digitalWrite(GREEN, HIGH); //I am using a common ANODE LED so a value
  digitalWrite(BLUE, HIGH); //of HIGH is off, and LOW is full brightness.
  digitalWrite(RED, HIGH); //Opposite for common CATHODE LEDs
  delay(12000); //This code is supposed to save energy by only detecting
  //light every two minutes as opposed to constantly, however it does not
  //work.
  } //close else
} //close void loop

Capture.JPG

I should clarify that I am using an Atmega 328P with arduino uno bootloader installed, and a 16Mhz crystal.

Button cells can only put out a very limited amount of current. After that their voltage drops. Try measuring the voltage across the buttons when it's running.

For stuff like this I'd use an old phone charger or AAA batteries.

PS: What program do people use to generate those circuit diagrams?

http://fritzing.org/ is open source diagramming software.

The button batteries measure 4.3V when not attached.

They measure 3.2V when the program is running. I'm guessing this is the problem? I'm trying to find a small power source, the whole circuit is only a few milimeters larger than the Atmega chip, so I dont really want to use 3 AAA batteries.

chaines:
The button batteries measure 4.3V when not attached.

They measure 3.2V when the program is running. I'm guessing this is the problem? I'm trying to find a small power source, the whole circuit is only a few milimeters larger than the Atmega chip, so I dont really want to use 3 AAA batteries.

The current being drawn has dropped the voltage down by 1.1V so I'm guessing it's near the limit.

In theory a 328P should run down to 1.8V but you need to drop the clock frequency down. Try setting it to 1MHz internal clock and see what happens (use "fuse bits" for this).

You could also reduce the current getting through to the LED... put two sets of batteries in parallel, etc.

You might also be bumping up against the LED’s forward voltage. Some Blue LED’s need over 3.5 V to turn on.

If you want small but powerful batteries, consider a lithium CR2. Each cell is 3V nominal, and you could clock your Atmega328 at 8MHz or lower and run directly from it. If your LED is a little 5mm / 20mA job, it could also probably run directly from a single CR2… for a while. Technically you don’t have enough Vf but in reality you can often bend the spec a little for low-power LEDs (they’re just a little dim, adjust the resistor to compensate). But as the CR2 discharges and voltage drops over time, the blue and green will probably poop out before the red and the Atmega itself quit working. But maybe that’s a “low battery indicator” feature.

Another alternative would be a pair of CR2032s (lithium coin cells). You would be over-volting the Atmega with fresh cells (over 6v), so perhaps a 5.6V zener could reduce the voltage by wasting power for a few minutes until the cells naturally discharge a bit.

If you’re going to be using this a lot, consider a rechargeable Li-Po or Li-ion cell. They come in various small form factors (Li-ion is available in 10180 or even 2032 form factors) and run at a more convenient 3.6v. However, you MUST use a proper charger or smoke and flames will result. You’d also want to use the ADC on the Atmega as a voltmeter and shut itself off when appropriate to make sure you do not over-discharge the cell.

fungus:
In theory a 328P should run down to 1.8V but you need to drop the clock frequency down. Try setting it to 1MHz internal clock and see what happens (use "fuse bits" for this).

You'll also have to set the brown-out-detection voltage in the fuse bits too, it will brown-out at 2.7V by default with normal Arduino bootloader IIRC. Since current consumption is less at lower clock frequencies just reducing the clock speed may allow running from button cells (if nothing else takes many mA).

Thanks for all the suggestions and ideas. These will all help when I make future projects. What I had been doing was using 3 1.5v button cells (LR932) from inside a 12v battery. I made a second stack and attached in parallel for a total of 6 batteries running at 4.5 volts. It is still very small (< 2mm1mm1mm) and now when the LED is running the voltage only drops down to 3.9V, which has stopped all flickering. It seems to work well for a small project like this.

I attached a pic of the whole thing for size comparison to the ATMEGA 328p chip