Solar night light: how cut the power at daytime?

I am building a ws2812b LED light-chain. The plan is to power my arduino mini from a 18650 battery at night and charge the battery with a TP4056 module by a solar panel at daytime.

I am struggling to find a diagram how to cut power to arduino at daytime as the solar panel provides voltage to the charging circuit. If the voltage drops in the dusk the arduino should power on from the charged battery.

I have found a circuit for a similar application but there is just one simple LED and the battery is connected directly to the solar panel - thats not the case with my TP4056 charger. I am not good in electronics - all I understand, that I need one ore two transistors to make it work, but how?

Can somebody give me a hint how to do this?

Here is my circuit and the other circuit i am talking about

sample.jpg

Just don't :slight_smile: Put it to sleep and call it a day (pun intended). In sleep the Arduino barely uses power. At least not more then any "cut power circuit" is going to use.

I guess I have to use a analog pin to mesure voltage from the solar panel and power the arduino and the leds on/off if the voltage reaches a certain level. How can I implement this into my code? Still prefer the physical "no code" power down solution because it would be easier understand for me than the code stuff.

#include <Adafruit_NeoPixel.h>
// Pattern types supported:
enum pattern { 
  NONE, RAINBOW_CYCLE, RAINBOW, COLOR_WIPE };
// Patern directions supported:
enum  direction { 
  FORWARD, REVERSE };

class NeoPatterns : 
public Adafruit_NeoPixel
{
public:

  //Member variables:
  pattern ActivePattern; // which pattern is running
  direction Direction;     // direction to run the pattern

    unsigned long Interval;  // milliseconds between updates
  unsigned long lastUpdate; // last update of position

  uint32_t Color1, Color2;  // What colors are in use
  uint16_t TotalSteps;  // total number of steps in the pattern
  uint16_t Index;  // current step within the pattern

  void (*OnComplete)();

  // Constructor - calls base-class constructor to initialize strip
  NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type)
: 
    Adafruit_NeoPixel(pixels, pin, type)
    {
    }
  void Update()
  {
    if ((millis() - lastUpdate) > Interval) // time to update
    {
      lastUpdate = millis();
      switch (ActivePattern)
      {
      case COLOR_WIPE:
        ColorWipeUpdate();
        break;
      case RAINBOW_CYCLE:
        RainbowCycleUpdate();
        break;
      case RAINBOW:
        RainbowUpdate();
        break;          
      default:
        break;
      }
    }
  }
  // Increment the Index and reset at the end
  void Increment()
  {
    if (Direction == FORWARD)
    {
      Index++;
      if (Index >= TotalSteps)
      {
        Index = 0;
        if (OnComplete != NULL)
        {
          OnComplete(); // call the comlpetion callback
        }
      }
    }
    else // Direction == REVERSE
    {
      --Index;
      if (Index <= 0)
      {
        Index = TotalSteps - 1;
        if (OnComplete != NULL)
        {
          OnComplete(); // call the comlpetion callback
        }
      }
    }
  }


  void Rainbow(uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = RAINBOW;
    Interval = interval;
    TotalSteps = 255;
    Index = 0;
    Direction = dir;
  }

  void RainbowUpdate() {
    uint16_t i;

    for (i = 0; i < numPixels(); i++)
    {
      setPixelColor(i, Wheel((i+Index) & 255));
    }
    show(); 
    Increment();  
  }


  void RainbowCycle(uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = RAINBOW_CYCLE;
    Interval = interval;
    TotalSteps = 255;
    Index = 0;
    Direction = dir;
  }


  void RainbowCycleUpdate()
  {
    for (int i = 0; i < numPixels(); i++)
    {
      setPixelColor(i, Wheel(((i * 256 / numPixels()) + Index) & 255));
    }
    show();
    Increment();
  }

  void ColorWipe(uint32_t color, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = COLOR_WIPE;
    Interval = interval;
    TotalSteps = numPixels();
    Color1 = color;
    Index = 0;
    Direction = dir;
  }
  // Update the Color Wipe Pattern

  void ColorWipeUpdate()
  {
    setPixelColor(Index, Color1);
    show();
    Increment();
  }
  // Input a value 0 to 255 to get a color value.
  // The colours are a transition r - g - b - back to r.
  uint32_t Wheel(byte WheelPos)
  {
    WheelPos = 255 - WheelPos;
    if (WheelPos < 85)
    {
      return Color(255 - WheelPos * 3, 0, WheelPos * 3);
    }
    else if (WheelPos < 170)
    {
      WheelPos -= 85;
      return Color(0, WheelPos * 3, 255 - WheelPos * 3);
    }
    else
    {
      WheelPos -= 170;
      return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
    }
  }
};

#define BUTTON_PIN   2
#define PIXEL_PIN    5
#define PIXEL_COUNT  12

NeoPatterns Strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);

bool oldState = HIGH;
int showType = 0;

void setup() {
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  Strip.begin();

  Strip.ActivePattern = RAINBOW_CYCLE; //set start LED mode/color
  Strip.Index = 0;
  Strip.Interval = 100;
  Strip.TotalSteps = 255;
  Strip.setBrightness(100);
  Strip.show();

  Serial.begin(9600);
}

void loop() {

  bool newState = digitalRead(BUTTON_PIN);
  if (newState == LOW && oldState == HIGH) {
    delay(20);
    newState = digitalRead(BUTTON_PIN);
    if (newState == LOW) {
      showType++;
      if (showType > 8)
        showType = 1;
      startShow(showType);
    }
  }
  oldState = newState;
  Strip.Update();
}
void startShow(int i) {
  switch (i) {
  case 0: 
    Strip.ActivePattern = COLOR_WIPE;
    Strip.Index = 0;
    Strip.Color1 = Strip.Color(0, 0, 0); //off
    Strip.Interval = 30;
    Strip.Update();
    Serial.println(showType);
    Serial.println(Strip.ActivePattern);
    break;
  case 1: 
    Strip.ActivePattern = COLOR_WIPE;
    Strip.Index = 0;
    Strip.Color1 = Strip.Color(255, 0, 255); //pink
    Strip.Interval = 30;
    Strip.Update();
    Serial.println(showType);
    break;
  case 2: 
    Strip.ActivePattern = COLOR_WIPE;
    Strip.Index = 0;
    Strip.Color1 = Strip.Color(200, 255, 0); //Green
    Strip.Interval = 30;
    Strip.Update();
    Serial.println(showType);
    break;
  case 3: 
    Strip.ActivePattern = COLOR_WIPE;
    Strip.Index = 0;
    Strip.Color1 = Strip.Color(0, 250, 255); //türkis
    Strip.Interval = 20;
    Strip.Update();
    Serial.println(showType);
    break;
  case 4: 
    Strip.ActivePattern = COLOR_WIPE;
    Strip.Index = 0;
    Strip.Color1 = Strip.Color(255, 150, 0); //orange
    Strip.Interval = 20;
    Strip.Update();
    Serial.println(showType);
    break;
  case 5: 
    Strip.ActivePattern = COLOR_WIPE;
    Strip.Index = 0;
    Strip.Color1 = Strip.Color(125, 0, 255); //lila
    Strip.Interval = 20;
    Strip.Update();
    Serial.println(showType);
    break;
  case 6: 
    Strip.ActivePattern = COLOR_WIPE;
    Strip.Index = 0;
    Strip.Color1 = Strip.Color(255, 255, 255); //weiss
    Strip.Interval = 20;
    Strip.Update();
    Serial.println(showType);
    break;
  case 7: 
    Strip.ActivePattern = RAINBOW_CYCLE;
    Strip.Index = 0;
    Strip.Interval = 100;
    Strip.TotalSteps = 255;
    Strip.Update();
    Serial.println(showType);
    break;
  case 8: 
    Strip.ActivePattern = RAINBOW;
    Strip.Index = 0;
    Strip.Interval = 300;
    Strip.TotalSteps = 255;
    Strip.Update();
    Serial.println(showType);
    break;
  }
}

Mm, doubt the latter. Both have pro's and cons.

You can do it with an analog pin but I even think a digital pin is fine and will also give a perfect sun/no-sun reading. Advantage to this is you can actually wake the Arduino with the falling voltage where as with a analog signal (which you have to read which doesn't happen in deep sleep) is that you need to periodically wake up the Arduino, take a measurement and determine to go back to sleep or not.

But just do some reading about sleeping the Arduino. There are even a couple of libraries out there to do it but I have no idea how good they are.

Bu in a nut, every loop you simply check if it's time to sleep. If it is, you set up the stuff to wake it up again, set up the sleep and put the Arduino to sleep.

At least I am a step further. I figured out how to read the solar panel voltage and react depending on measurement. At the moment if the solar panel voltage drops below 2.5v I set the LED brightness to 255 (on) and if the voltage is above 2.5v I set the brightness to 0 (off).

Still not quite happy, but at least some progress. Will do some reading on sleep modes. Thanks.

Best references: sleep and power consumption, and solar powered arduino.

skaman82:
At least I am a step further. I figured out how to read the solar panel voltage and react depending on measurement. At the moment if the solar panel voltage drops below 2.5v I set the LED brightness to 255 (on) and if the voltage is above 2.5v I set the brightness to 0 (off).

Still not quite happy, but at least some progress. Will do some reading on sleep modes. Thanks.

Sorry for bringing up an old post but how did you get on with this? did you get it going and how did you do it?