My project is a digital clock using LED strips, and for the most part it runs great. My only issue now is that sometimes the LEDs strips stop lighting up but the rest of the circuit is still running fine (the lights on the components are still on). The components are a realtime clock, a photoresistor, and an Arduino nano. The photoresistor and the Arduino's lights are still on even though the LED strips stop lighting up. The clock can start working again once the system is restarted (unplugging and plugging in) but then the same issue will happen again after a few days.
There are 2 things that I might suspect are causing this, 1 is that the power supply might not provide enough current, and 2 is because of the resistors between the Arduino and the LED strips.
However, I'm not sure if these are really the cause...
for the code, I'm not sure which parts to add here since I don't know what would cause it to turn off after several days. could you tell me what you would be looking for in the code that might affect it?
All of the code. If you knew where the problem was, you'd be able to fix it.
I do not see decoupling caps for the LEDs.
Also need to know the type of power supply, actual product link, and the same for the LED strips.
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#endif
#include <DS3231_Simple.h>
DS3231_Simple Clock;
//declare variable for date and time from RTC
DateTime DateAndTime;
// declare Arduino pins connected to LED strips
#define LED_TIME_PIN 5
#define LED_MONTHS_PIN 6
// number of LEDs per strip
#define LED_TIME_COUNT 30
#define LED_MONTHS_COUNT 26
//32-bit merged colour = (red * 65536) + (green * 256) + blue -> color values max at 255
// 0 would be equvalent to off
uint32_t Color_White = (255 * 65536) + (255 * 256) + 255;;
uint32_t Color_Off = 0;
uint32_t Color_Bad = (255 * 65536) + (60 * 256) + 60;
// at low brightness values, only the highest value color LED is on
const int MIN_BRIGHTNESS = 4;
uint32_t Color_Time = Color_White;
uint32_t Color_Months = Color_White;
int Clock_Brightness = 0;
// Declare our NeoPixel objects:
Adafruit_NeoPixel strip_Time(LED_TIME_COUNT, LED_TIME_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip_Months(LED_MONTHS_COUNT, LED_MONTHS_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
// NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
//Smoothing of the readings from the light sensor so it is not too twitchy
const int NUM_READINGS = 10; //average of how many light sensor values
int Photoresistor[NUM_READINGS]; // store values in matrix
int PhotoIndex = 0; // the index of the current reading
long sum_photo = 0; // the running total
long average_photo = 0; // the average
void setup() {
Serial.begin(9600);
Clock.begin();
// initialize LEDs
strip_Time.begin(); // INITIALIZE NeoPixel strip_Time object (REQUIRED)
strip_Time.show(); // Turn OFF all pixels ASAP
strip_Time.setBrightness(100); // Set inital BRIGHTNESS (max = 255)
strip_Months.begin(); // INITIALIZE NeoPixel strip_Months object (REQUIRED)
strip_Months.show(); // Turn OFF all pixels ASAP
strip_Months.setBrightness(100); // Set BRIGHTNESS (max = 255)
// initialize values in Photoresistor array:
for (int currentReading = 0; currentReading < NUM_READINGS; currentReading++) {
Photoresistor[currentReading] = 0;
}
}
void GetBrightness() {
Photoresistor[PhotoIndex] = analogRead(A0); //get value from analog pin connected to photoresistor
Serial.print("Photoresistor value = "); Serial.println(Photoresistor[PhotoIndex]);
PhotoIndex ++;
if (PhotoIndex >= NUM_READINGS) {
PhotoIndex = 0;
}
//get average value for photoresistor
sum_photo = 0;
for (int i = 0; i < NUM_READINGS; i++)
{
sum_photo += Photoresistor[i];
}
Serial.print("sum_photo = "); Serial.println(sum_photo);
// insurance that value wont go below 0
if (sum_photo < 0){
sum_photo = 10 * NUM_READINGS;
Serial.print("corrected sum_photo = "); Serial.println(sum_photo);
}
average_photo = sum_photo / NUM_READINGS;
Serial.print("average_photo = "); Serial.println(average_photo);
// insurance that value wont go above 1023 (max analog reading)
if (average_photo > 1023){
average_photo > 900;
Serial.print("corrected sum_photo = "); Serial.println(sum_photo);
}
//set the brightness based on photoresistor values
Clock_Brightness = map(average_photo, 0, 1023, 225, MIN_BRIGHTNESS);
Serial.print("Clock_Brightness = "); Serial.println(Clock_Brightness);
strip_Time.setBrightness(Clock_Brightness);
strip_Months.setBrightness(Clock_Brightness);
}
void loop() {
//Function to get time from RTC & choose color
ReadTime();
//Function to display the time with LEDs
DisplayTime();
//Function to display the months with LEDs
DisplayMonths();
//all lights on (For testing)
//strip_Time.clear(); //clear the time LEDs
//strip_Time.fill(Color_White, 0, 30);
//strip_Months.clear(); //clear the months LEDs
//strip_Months.fill(Color_White, 0, 26);
//Function to get brightness form light photoresistor
GetBrightness();
strip_Time.show();
strip_Months.show();
delay(000); //make value (1000) to have 1 second delay during testing
Serial.println("");
}
void ReadTime() {
//get date and time from RTC
DateAndTime = Clock.read();
// print info in serial monitor
Serial.println("");
Serial.print("Time is: "); Serial.print(DateAndTime.Hour);
Serial.print(":"); Serial.print(DateAndTime.Minute);
Serial.print(":"); Serial.println(DateAndTime.Second);
Serial.print("Date is: 20"); Serial.print(DateAndTime.Year);
Serial.print("/"); Serial.print(DateAndTime.Month);
Serial.print("/"); Serial.println(DateAndTime.Day);
//determine color for time
Serial.print("Color_Time: ");
int Hour = DateAndTime.Hour;
if (Hour > 6 && Hour < 16){
Color_Time = Color_Bad;
Serial.println("Color_Bad");
}
else {
Color_Time = Color_White;
Serial.println("Color_White");
}
}
void DisplayTime() {
strip_Time.clear(); //clear the clock face
//hours
int Hour = DateAndTime.Hour;
int Hours_firstdigit, Hours_seconddigit;
//remove firt set of if statements for 24hr clock
if (Hour == 0) {
Hour = 12;
}
else if (Hour > 12) {
Hour = Hour - 12;
}
// remove until here
if (Hour > 19){
Hours_firstdigit = 2;
Hours_seconddigit = Hour - 20;
}
else if (Hour > 9) {
Hours_firstdigit = 1;
Hours_seconddigit = Hour - 10;
}
else if (Hour < 10) {
Hours_firstdigit = 0;
Hours_seconddigit = Hour;
}
// take Time_displayNumber out of if statement if you want 0 to be shown
if (Hours_firstdigit > 0) {
Time_displayNumber(Hours_firstdigit, 0, Color_Time); //Time_displayNumber(int digitToDisplay, int offsetBy, uint32_t colourToUse)
}
Serial.print("Hours_firstdigit: "); Serial.println(Hours_firstdigit);
Time_displayNumber(Hours_seconddigit, 7, Color_Time);
Serial.print("Hours_seconddigit: "); Serial.println(Hours_seconddigit);
//minutes
int Minutes_firstdigit = floor(DateAndTime.Minute / 10); //gives largest whole number less than or equal to value
Time_displayNumber(Minutes_firstdigit, 16, Color_Time);
Serial.print("Minutes_firstdigit: "); Serial.println(Minutes_firstdigit);
int Minutes_seconddigit = DateAndTime.Minute % 10; //get remainder when number is divided by 10
Time_displayNumber(Minutes_seconddigit, 23, Color_Time);
Serial.print("Minutes_seconddigit: "); Serial.println(Minutes_seconddigit);
// used to make center ':' blink with the seconds
int seconds = DateAndTime.Second;
int mod = seconds % 2;
Serial.print("mod: "); Serial.println(mod);
if (mod == 0) {
strip_Time.fill(Color_Time, 14, 2);
Serial.println("blink: on");
}
else {
strip_Time.fill(Color_Off, 14, 2);
Serial.println("blink: off");
}
}
void DisplayMonths() {
int mon = DateAndTime.Month;
int date = DateAndTime.Day;
strip_Months.clear(); //clear the clock face
// light the current month
strip_Months.fill(Color_Months, (mon - 1), 1);
// date
int Day_firstdigit, Day_seconddigit;
if (date > 29) {
Day_firstdigit = 3;
Day_seconddigit = date - 30;
}
else if (date > 19) {
Day_firstdigit = 2;
Day_seconddigit = date - 20;
}
else if (date > 9) {
Day_firstdigit = 1;
Day_seconddigit = date - 10;
}
else if (date < 10) {
Day_firstdigit = 0;
Day_seconddigit = date;
}
// take Months_displayNumber out of if statement if you want 0 to be shown
if (Day_firstdigit > 0) {
Months_displayNumber(Day_firstdigit, 12, Color_Months);
}
Serial.print("Day_firstdigit: "); Serial.println(Day_firstdigit);
Months_displayNumber(Day_seconddigit, 19, Color_Months);
Serial.print("Day_seconddigit: "); Serial.println(Day_seconddigit);
}
Look at the power supply, it has a sticker on it.
There's no point in doing much else until you know if you have adequate power.
Also, you will need decoupling caps for those LED strips.
Thats something I wish I could check but to see the serial monitor I would have to plug it into my computer, when I do that it restarts the circuit so it starts working as expected again. Is the only way to check the serial monitor to have an external display?
When I troubleshoot a problem like this I just leave it printing for weeks at a time. I clear the prints in the morning. Another thing you could do is comment out the ``DisplayMonths()``` to see if the issue stops.
yes I have the serial prints for when I troubleshoot, but I never tried troubleshooting by leaving it hooked up to my computer for several days. I may try it though if I can't solve the issue. For now I'll try to just add a code for the onboard LED of the Arduino to check if the Arduino is running or if the whole circuit failed
When you say crash do you mean permanent damage to the Arduino? I think that the issues I'm having are flushed out with a reboot to the system so not permanent... but still I'll take note of the factors you mentioned to see if they happen around when the LEDs stop working