Three digit led display that uses a segment clock. Stuck on code

I am new to working with any kind of code. I have been working on making a three digit display that acts as a segment clock. The display may say 205. That would mean segment two five minutes left. I have been using chatgpt to make the code and debugging but I am stuck like chuck. The code I am at does not light any of the LEDs and I cannot find the problem. I am using tincercad to simulate the project. Use code tags to format code for the forum

#include <Adafruit_NeoPixel.h>
#include <Keypad.h>
#include <Adafruit_LiquidCrystal.h>

// Define NeoPixel pins and settings
#define LED_PIN_HUNDREDS 13
#define LED_PIN_TENS 12
#define LED_PIN_ONES 11
#define NUM_LEDS_PER_SEGMENT 28
#define NUM_LEDS 28
#define NUM_DIGITS 3

Adafruit_NeoPixel pixels_hundreds(NUM_LEDS_PER_SEGMENT, LED_PIN_HUNDREDS, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixels_tens(NUM_LEDS_PER_SEGMENT, LED_PIN_TENS, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixels_ones(NUM_LEDS_PER_SEGMENT, LED_PIN_ONES, NEO_GRB + NEO_KHZ800);

// Keypad settings
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

// LCD settings
Adafruit_LiquidCrystal lcd(0); // Replace with your LCD's I2C address

// Global variables
int displayedNumber[NUM_DIGITS] = {0};
char enteredDigits[NUM_DIGITS] = {'0', '0', '0'};
byte digitCount = 0;
int lastDisplayedMinutes = -1;
unsigned long lastLEDUpdateTime = 0;
const unsigned long LEDUpdateInterval = 1000;

const int maxSegments = 10;
int segmentCount = 0;
int currentSegment = 0;
int segmentTimes[maxSegments];
bool countdownActive = false;
unsigned long segmentStartTime = 0;
unsigned long segmentEndTime = 0;
int remainingSegmentMinutes = 0;

enum State {
  STATE_ENTER_SEGMENTS,
  STATE_ENTER_TIMES,
  STATE_COUNTDOWN
};

State currentState = STATE_ENTER_SEGMENTS;

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


  pixels_hundreds.begin();
  pixels_hundreds.show();
  pixels_hundreds.setBrightness(255);

  pixels_tens.begin();
  pixels_tens.show();
  pixels_tens.setBrightness(255);

  pixels_ones.begin();
  pixels_ones.show();
  pixels_ones.setBrightness(255);

  initializeLEDs();

  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Enter segments: ");
}

void loop() {
  char key = keypad.getKey();
  
  switch (currentState) {
    case STATE_ENTER_SEGMENTS:
      handleSegmentInput(key);
      break;
      
    case STATE_ENTER_TIMES:
      handleTimeInput(key);
      break;
      
    case STATE_COUNTDOWN:
      handleCountdown();
      break;
  }
}

void initializeLEDs() {
  for (int i = 0; i < NUM_LEDS_PER_SEGMENT; i++) {
    pixels_hundreds.setPixelColor(i, pixels_hundreds.Color(255, 255, 255));
    pixels_tens.setPixelColor(i, pixels_tens.Color(255, 255, 255));
    pixels_ones.setPixelColor(i, pixels_ones.Color(255, 255, 255));
  }
  pixels_hundreds.show();
  pixels_tens.show();
  pixels_ones.show();
}

void clearLEDs() {
  for (int i = 0; i < NUM_LEDS_PER_SEGMENT; i++) {
    pixels_hundreds.setPixelColor(i, pixels_hundreds.Color(0, 0, 0));
    pixels_tens.setPixelColor(i, pixels_tens.Color(0, 0, 0));
    pixels_ones.setPixelColor(i, pixels_ones.Color(0, 0, 0));

    // Print information for each LED
    Serial.print("Setting LEDs for initialization - Pixel ");
    
   
  }

  pixels_hundreds.show();
  pixels_tens.show();
  pixels_ones.show();
}


void handleSegmentInput(char key) {
  if (key >= '0' && key <= '9') {
    int digit = key - '0';
    segmentCount = segmentCount * 10 + digit; // Build the segment count

    lcd.setCursor(0, 1);
    lcd.print("Segments: ");
    lcd.print(segmentCount);
  } else if (key == '*') {
    if (segmentCount > 0 && segmentCount <= maxSegments) {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Enter times: ");
      lcd.setCursor(0, 1);
      lcd.print("Seg 1: ");
      currentState = STATE_ENTER_TIMES;
    } else {
      lcd.setCursor(0, 1);
      lcd.print("Invalid segments");
    }
  }
}

void handleTimeInput(char key) {
  if (key >= '0' && key <= '9') {
    int digit = key - '0';
    segmentTimes[currentSegment] = segmentTimes[currentSegment] * 10 + digit; // Build the segment time

    lcd.setCursor(0, 1);
    lcd.print("Seg ");
    lcd.print(currentSegment + 1);
    lcd.print(": ");
    lcd.print(segmentTimes[currentSegment]);
    lcd.print(" min");
  } else if (key == '#') {
    if (currentSegment < segmentCount - 1) {
      currentSegment++;
      lcd.setCursor(0, 1);
      lcd.print("Seg ");
      lcd.print(currentSegment + 1);
      lcd.print(": ");
      currentState = STATE_ENTER_TIMES;
    } else {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Countdown starts!");
      currentSegment = 0;
      segmentStartTime = millis();
      segmentEndTime = segmentStartTime + segmentTimes[currentSegment] * 60000UL;
      countdownActive = true;
      currentState = STATE_COUNTDOWN;
    }
  }
}

void handleCountdown() {
  if (currentSegment < segmentCount) {
    unsigned long currentTime = millis();
    if (currentTime >= segmentEndTime) {
      currentSegment++;
      if (currentSegment < segmentCount) {
        lcd.clear(); // Clear the LCD
        lcd.setCursor(0, 0);
        lcd.print("Segment ");
        lcd.print(currentSegment + 1);
        lcd.setCursor(0, 1); // Move to the second line
        lcd.print("Time: ");
        unsigned long minutes = segmentTimes[currentSegment];
        displaySegmentsAndDigits(currentSegment, minutes);

        // Update segmentStartTime and segmentEndTime for the new segment
        segmentStartTime = currentTime;
        segmentEndTime = segmentStartTime + segmentTimes[currentSegment] * 60000UL;

        // Clear the LEDs for the previous segment
        clearLEDs();
      } else {
        // Countdown finished
        lcd.clear(); // Clear the LCD
        lcd.setCursor(0, 0);
        lcd.print("Countdown finished");
        countdownActive = false;
      }
      remainingSegmentMinutes = segmentTimes[currentSegment];
    } else {
      // Calculate remaining time in MM:SS format
      unsigned long remainingTime = (segmentEndTime - currentTime) / 1000;
      unsigned long minutes = remainingTime / 60;
      unsigned long seconds = remainingTime % 60;
      lcd.setCursor(0, 1); // Position for MM:SS on the second line
      lcd.print("Seg ");
      lcd.print(currentSegment + 1);
      lcd.print(" Time:");
      if (minutes < 10) {
        lcd.print("0");
      }
      lcd.print(minutes);
      lcd.print(":");
      if (seconds < 10) {
        lcd.print("0");
      }
      lcd.print(seconds);
      
      Serial.print("Displaying segmentNumber=");
      Serial.print(currentSegment);  // Use the correct variable name
      Serial.print(", minutes=");
      Serial.println(minutes);
    }
  }
}
void displaySegmentsAndDigits(int segmentNumber, int minutes) {
  // Define LED configurations for each segment (adjust as needed)
  const byte segmentLEDs[][NUM_LEDS] = {
    // Define LED patterns for digits 0 to 9 here
     {1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0}, // 0
    {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // 1
    {1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1}, // 2
    {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}, // 3
    {0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0}, // 4
    {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, // 5
    {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, // 6
    {1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // 7
    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, // 8
    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1}  // 9
  };

  // Calculate hundreds, tens, and ones digits from segmentNumber
  int hundredsDigit = segmentNumber / 100;
  int tensDigit = (segmentNumber / 10) % 10;
  int onesDigit = segmentNumber % 10;

  // Set LEDs for the hundreds digit in green
  Serial.print("Setting LEDs for hundreds digit: ");
for (int i = 0; i < NUM_LEDS_PER_SEGMENT; i++) {
  Serial.print(segmentLEDs[hundredsDigit][i]);
}
Serial.println();

  for (int i = 0; i < NUM_LEDS_PER_SEGMENT; i++) {
    if (segmentLEDs[hundredsDigit][i] == 1) {
      pixels_hundreds.setPixelColor(i, pixels_hundreds.Color(0, 255, 0)); // Set segment LEDs to green
    } else {
      pixels_hundreds.setPixelColor(i, pixels_hundreds.Color(0, 0, 0)); // Turn off other LEDs
    Serial.println("Setting LEDs for hundreds digit:"); }
  }

  // Set LEDs for the tens and ones digits in red
  for (int i = 0; i < NUM_LEDS_PER_SEGMENT; i++) {
    if (i >= 0 && i < 28) {
      // LEDs 0 to 27 for the tens digit of segmentNumber (red)
      if (tensDigit == i) {
        pixels_tens.setPixelColor(i, pixels_tens.Color(255, 0, 0)); // Set tens digit LEDs to red
      } else {
        pixels_tens.setPixelColor(i, pixels_tens.Color(0, 0, 0)); // Turn off other LEDs
      }
    } else {
      // LEDs 28 to 55 for the ones digit of segmentNumber (red)
      if (onesDigit == (i - 28)) {
        pixels_ones.setPixelColor(i - 28, pixels_ones.Color(255, 0, 0)); // Set ones digit LEDs to red
      } else {
        pixels_ones.setPixelColor(i - 28, pixels_ones.Color(0, 0, 0)); // Turn off other LEDs
      }
    }
  }
Serial.print("Displaying segmentNumber=");
  Serial.print(currentSegment);
  Serial.print(", minutes=");
  Serial.println(minutes);
  // Show the LED display
  pixels_hundreds.show();
  pixels_tens.show();
  pixels_ones.show();
}

![segment timer|451x500](upload://zc8TvKFIDhuiRywSQHkuspnlUWk.png)


Welcome to the forum

ChatGPT is not well regarded by the members of this forum. For anything more than a trivial sketch it often gets things wrong, then users come here looking for help. It often takes longer to sort out problems than it would have done to learn how to do it yourself

Start by posting a schematic of your project.
Are the 7 segment displays common anode or common cathode ?
Which Arduino board are you using ?
How is the project as a whole powered ?
How are this displays powered ?

Yes, i have discovered that chat GPT is not very helpful. You may be right about learning it yourself may have been easier. Ignorance can be bliss sometimes.

The 7 segment displays are made of led strips. so 7 strips of 4 leds.
I am using the Arduino nano, however tinker cad only lets me use a arduino uno.
The project and displays are powered with a power bank, 5 volt, 10000 Mah battery.
I tried to post the picture with this last night, but I will do it again.

I suggest that you start by writing a small sketch that turns on each LED in each string . That will test your wiring and the use of the Nano to control them

There are examples with the Adafruit NeoPixel library that you can adapt to do that

This may be the crux of my problem. How do I look at examples in the adafruit neopixil library. I'm very new to this. I understands how parts of the code works but I could not make anything myself yet.

I have no experience of TinkerCad so I don't know whether it allows you to load the examples that come with libraries

Here is the Simple example from the library

// NeoPixel Ring simple sketch (c) 2013 Shae Erisson
// Released under the GPLv3 license to match the rest of the
// Adafruit NeoPixel library

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

// Which pin on the Arduino is connected to the NeoPixels?
#define PIN        6 // On Trinket or Gemma, suggest changing this to 1

// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 16 // Popular NeoPixel ring size

// When setting up the NeoPixel library, we tell it how many pixels,
// and which pin to use to send signals. Note that for older NeoPixel
// strips you might need to change the third parameter -- see the
// strandtest example for more information on possible values.
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

#define DELAYVAL 500 // Time (in milliseconds) to pause between pixels

void setup() {
  // These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
  // Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  // END of Trinket-specific code.

  pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
}

void loop() {
  pixels.clear(); // Set all pixel colors to 'off'

  // The first NeoPixel in a strand is #0, second is 1, all the way up
  // to the count of pixels minus one.
  for(int i=0; i<NUMPIXELS; i++) { // For each pixel...

    // pixels.Color() takes RGB values, from 0,0,0 up to 255,255,255
    // Here we're using a moderately bright green color:
    pixels.setPixelColor(i, pixels.Color(0, 150, 0));

    pixels.show();   // Send the updated pixel colors to the hardware.

    delay(DELAYVAL); // Pause before next pass through loop
  }
}

All but one of your connections from Arduino to Neopixel can be reserved and use only one signal wire if you would put all the Neopixels in series (DOUT to next DIN) then use your sketch (code) to address the individual WS2812 in the segments. You need external power to reach all segments (you seem to have the last segment with the signal line only).

The physical version of this has the LED digits daisy chained and works correctly for a three digit display. It just seems to have issues with running a segment timer. I have also gotten to run a timer. I will keep working on your suggestion. Hooking each digit to its own LED digit because I thought that would resolve the problem.

Keep the signal (data) wires from DOUT to DIN as short as practical (long enough not to bind, but no big service loops). Power and ground wires can be as long as you want. If you get to 100 pixels (3 meters?), you will want "power injection" (power and ground straight from power supply to Vcc/GND near 3m mark) to keep your pixels at the same brightness.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.