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
Just don't 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.
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?