7 segment clock - ledstrip - wemos d1 mini

Hello,

I tried to make this clock:
7 segment clock

I used the code and hardware unchanged from his github page.
RTC DS3231, Wemos D1miniV3, WS2812B ledstrip.

The clock and the other things, are doing very well (I mean, they are giving the right numbers). Sometimes they forget a second, but thats not an issue.
But the colors are very strange. SO I try to change the led-order from RGB to GBR or whatever, but nothing helps.
And more, a few more leds are lit.

When I test the ledstrip on another Arduino board, it works as usual.

What happened? What could I test anymore?


Gr.
Johan

Hi, are GND's connected together?
Which is the version of ESP board are you using?
I got some problem with the 3.0.0 and I've solved the problem with the 2.7.4

Yes, grounds are connected.
And the version of de ESP8266 is 3.0.1.

I'll try to downgrade it, and see of that helps...

Thanks.

Great! Version 2.7.4 works!

I don't ask how it's possible, only take advantage of it...:slight_smile:

1 Like

Sorry, here I am again...

Whats the matter when I put this system (RTC + WS2812B) on an Arduino UNO?
I removed all wifi-things, all ESP-things. Only the FASTLed and RTC library.
Time is displayed correctly.
But now there are some segments who light up incorrectly.

This photo is 8:54 hour:

Never change the order or code in the displaynumbers function.

Gr.
Johan

Can I see your code please?

#include <Wire.h>
#include <RtcDS3231.h>                        // Include RTC library by Makuna: https://github.com/Makuna/Rtc

#include <FastLED.h>
#define NUM_LEDS 86                           // Total of 86 LED's     
#define DATA_PIN 6                           // Change this if you are using another type of ESP board than a WeMos D1 Mini
#define MILLI_AMPS 2400
#define COUNTDOWN_OUTPUT 5

RtcDS3231<TwoWire> Rtc(Wire);
CRGB LEDs[NUM_LEDS];

// Settings
unsigned long prevTime = 0;
byte r_val = 255;
byte g_val = 0;
byte b_val = 0;
bool dotsOn = true;
byte brightness = 255;
byte clockMode = 0;                           // Clock modes: 0=Clock, 1=Countdown, 2=Temperature, 3=Scoreboard
unsigned long countdownMilliSeconds;
unsigned long endCountDownMillis;
byte hourFormat = 24;                         // Change this to 12 if you want default 12 hours format instead of 24
CRGB countdownColor = CRGB::Green;
CRGB alternateColor = CRGB::Black;
long numbers[] = {
  0b000111111111111111111,  // [0] 0
  0b000111000000000000111,  // [1] 1
  0b111111111000111111000,  // [2] 2
  0b111111111000000111111,  // [3] 3
  0b111111000111000000111,  // [4] 4
  0b111000111111000111111,  // [5] 5
  0b111000111111111111111,  // [6] 6
  0b000111111000000000111,  // [7] 7
  0b111111111111111111111,  // [8] 8
  0b111111111111000111111,  // [9] 9
  0b000000000000000000000,  // [10] off
  0b111111111111000000000,  // [11] degrees symbol
  0b000000111111111111000,  // [12] C(elsius)
  0b111000111111111000000,  // [13] F(ahrenheit)
};

void setup() {
  pinMode(COUNTDOWN_OUTPUT, OUTPUT);
  Serial.begin(115200);
  delay(200);

  // RTC DS3231 Setup
  Rtc.Begin();
  RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);

  if (!Rtc.IsDateTimeValid()) {
    if (Rtc.LastError() != 0) {
      // we have a communications error see https://www.arduino.cc/en/Reference/WireEndTransmission for what the number means
      Serial.print("RTC communications error = ");
      Serial.println(Rtc.LastError());
    } else {
      // Common Causes:
      //    1) first time you ran and the device wasn't running yet
      //    2) the battery on the device is low or even missing
      Serial.println("RTC lost confidence in the DateTime!");
      // following line sets the RTC to the date & time this sketch was compiled
      // it will also reset the valid flag internally unless the Rtc device is
      // having an issue
      Rtc.SetDateTime(compiled);
    }
  }
  delay(200);
  //Serial.setDebugOutput(true);

  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(LEDs, NUM_LEDS);
  FastLED.setDither(false);
  FastLED.setCorrection(TypicalLEDStrip);
  FastLED.setMaxPowerInVoltsAndMilliamps(5, MILLI_AMPS);
  fill_solid(LEDs, NUM_LEDS, CRGB::Black);
  FastLED.show();
  digitalWrite(COUNTDOWN_OUTPUT, LOW);
  endCountDownMillis = millis() + countdownMilliSeconds;
  allBlank();

}

void loop() {

  updateClock();
  FastLED.show();

}

void displayNumber(byte number, byte segment, CRGB color) {
  /*

      __ __ __        __ __ __          __ __ __        12 13 14
    __        __    __        __      __        __    11        15
    __        __    __        __      __        __    10        16
    __        __    __        __  42  __        __    _9        17
      __ __ __        __ __ __          __ __ __        20 19 18
    __        65    __        44  43  __        21    _8        _0
    __        __    __        __      __        __    _7        _1
    __        __    __        __      __        __    _6        _2
      __ __ __       __ __ __           __ __ __       _5 _4 _3

  */

  // segment from left to right: 3, 2, 1, 0
  byte startindex = 0;
  switch (segment) {
    case 0:
      startindex = 0;
      break;
    case 1:
      startindex = 21;
      break;
    case 2:
      startindex = 44;
      break;
    case 3:
      startindex = 65;
      break;
  }

  for (byte i = 0; i < 21; i++) {
    yield();
    LEDs[i + startindex] = ((numbers[number] & 1 << i) == 1 << i) ? color : alternateColor;
  }
}

void allBlank() {
  for (int i = 0; i < NUM_LEDS; i++) {
    LEDs[i] = CRGB::Black;
  }
  FastLED.show();
}

void updateClock() {
  RtcDateTime now = Rtc.GetDateTime();
  // printDateTime(now);

  int hour = now.Hour();
  int mins = now.Minute();
  int secs = now.Second();

  if (hourFormat == 12 && hour > 12)
    hour = hour - 12;

  byte h1 = hour / 10;
  byte h2 = hour % 10;
  byte m1 = mins / 10;
  byte m2 = mins % 10;
  byte s1 = secs / 10;
  byte s2 = secs % 10;

  CRGB color = CRGB(r_val, g_val, b_val);

  if (h1 > 0)
    displayNumber(h1, 3, color);
  else
    displayNumber(10, 3, color); // Blank

  displayNumber(h2, 2, color);
  displayNumber(m1, 1, color);
  displayNumber(m2, 0, color);

  displayDots(color);
}

void updateCountdown() {
  byte cd_r_val = 0;
  byte cd_g_val = 255;
  byte cd_b_val = 0;
  digitalWrite(COUNTDOWN_OUTPUT, LOW);
  countdownColor = CRGB(cd_r_val, cd_g_val, cd_b_val);
  //allBlank();



  if (countdownMilliSeconds == 0 && endCountDownMillis == 0)
    return;

  unsigned long restMillis = endCountDownMillis - millis();
  unsigned long hours   = ((restMillis / 1000) / 60) / 60;
  unsigned long minutes = (restMillis / 1000) / 60;
  unsigned long seconds = restMillis / 1000;
  int remSeconds = seconds - (minutes * 60);
  int remMinutes = minutes - (hours * 60);

  Serial.print(restMillis);
  Serial.print(" ");
  Serial.print(hours);
  Serial.print(" ");
  Serial.print(minutes);
  Serial.print(" ");
  Serial.print(seconds);
  Serial.print(" | ");
  Serial.print(remMinutes);
  Serial.print(" ");
  Serial.println(remSeconds);

  byte h1 = hours / 10;
  byte h2 = hours % 10;
  byte m1 = remMinutes / 10;
  byte m2 = remMinutes % 10;
  byte s1 = remSeconds / 10;
  byte s2 = remSeconds % 10;

  CRGB color = countdownColor;
  if (restMillis <= 60000) {
    color = CRGB::Red;
  }

  if (hours > 0) {
    // hh:mm
    displayNumber(h1, 3, color);
    displayNumber(h2, 2, color);
    displayNumber(m1, 1, color);
    displayNumber(m2, 0, color);
  } else {
    // mm:ss
    displayNumber(m1, 3, color);
    displayNumber(m2, 2, color);
    displayNumber(s1, 1, color);
    displayNumber(s2, 0, color);
  }

  displayDots(color);

  if (hours <= 0 && remMinutes <= 0 && remSeconds <= 0) {
    Serial.println("Countdown timer ended.");
    //endCountdown();
    countdownMilliSeconds = 0;
    endCountDownMillis = 0;
    digitalWrite(COUNTDOWN_OUTPUT, HIGH);
    return;
  }
}

void endCountdown() {
  allBlank();
  for (int i = 0; i < NUM_LEDS; i++) {
    if (i > 0)
      LEDs[i - 1] = CRGB::Black;

    LEDs[i] = CRGB::Red;
    FastLED.show();
    delay(25);
  }
}

void displayDots(CRGB color) {
  if (dotsOn) {
    LEDs[42] = color;
    LEDs[43] = color;
  } else {
    LEDs[42] = CRGB::Black;
    LEDs[43] = CRGB::Black;
  }

  dotsOn = !dotsOn;
}

void hideDots() {
  LEDs[42] = CRGB::Black;
  LEDs[43] = CRGB::Black;
}

This is the code from This Tutorial.

I removed all ESP-stuff (i think...)

But I don't understand why there are some wrong segments light up.

Thanks for looking at this problem!

Gr.
Johan

If you load this code on Wemos you got same problem?

No, then it works without problems...

It seems to be the UNO has another way to command the ledstrip?
Or the libraries are not suitable for UNO.

J.

I don't think so...
Really strange, the library should works in the same way...
Have you tried to split program in 2 parts and test one a time?

And where have I to put the split?

I only call the updateClock() function.

My bad, i was looking the original code :sweat_smile:

Have you tried load an example code about FastLED?

You can also use your program without the RTC part, just put the "displayNumber" routine inside a FOR cycle in order to check all values in "numbers" variable.
If it works it could be a RTC problem (e.g. bad data read)

Try to remove yield() from "displayNumber" routine.

Another example of the FastLED library works fine. (DemoReel100) No strange things as fas as i can see.

And to tackle the RTC isn't necessary i think, because it works fine in the Wemos Mini. So, I think there is nothing wrong with it.

In addition: there must be displayed a countdown clock as well. And without the RTC (i'm simple using millis() for testing it, with code below) it has the same problem.

#include <FastLED.h>

#define NUM_LEDS 86                           // Total of 86 LED's     
#define DATA_PIN 6                           // Change this if you are using another type of ESP board than a WeMos D1 Mini
#define MILLI_AMPS 2400

bool dotsOn = true;
byte brightness = 255;
byte r_val = 0;
byte g_val = 250;
byte b_val = 0;
CRGB LEDs[NUM_LEDS];
CRGB alternateColor = CRGB::Black;

long numbers[] = {
  0b000111111111111111111,  // [0] 0
  0b000111000000000000111,  // [1] 1
  0b111111111000111111000,  // [2] 2
  0b111111111000000111111,  // [3] 3
  0b111111000111000000111,  // [4] 4
  0b111000111111000111111,  // [5] 5
  0b111000111111111111111,  // [6] 6
  0b000111111000000000111,  // [7] 7
  0b111111111111111111111,  // [8] 8
  0b111111111111000111111,  // [9] 9
  0b000000000000000000000,  // [10] off
  0b111111111111000000000,  // [11] degrees symbol
  0b000000111111111111000,  // [12] C(elsius)
  0b111000111111111000000,  // [13] F(ahrenheit)
};

int lesson = 1;
long hour_duration = 2700000;
long pause_duration = 900000;

unsigned long previousMillis = 0;
int interval = 1000;

void setup() {
  Serial.begin(9600);
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(LEDs, NUM_LEDS);
  FastLED.setDither(false);
  FastLED.setCorrection(TypicalLEDStrip);
  FastLED.setMaxPowerInVoltsAndMilliamps(5, MILLI_AMPS);
  fill_solid(LEDs, NUM_LEDS, CRGB::Black);
  FastLED.show();
}

void loop()
{
  while (lesson == 1 || lesson == 2 || lesson == 4 || lesson == 5 || lesson == 6 || lesson == 7 || lesson == 8 || lesson == 10 || lesson == 11)
  {

    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;

      showCountDown();

      Serial.println(lesson);
      hour_duration = hour_duration - 1000;
    }

    if (hour_duration == 0)
    {
      Serial.println("lesson is over");
      hour_duration = 2700000;
      lesson = lesson + 1;
    }
  }

  while (lesson == 3 || lesson == 9)
  {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;

      showCountDownPause();
      Serial.println(lesson);

      //Serial.println(pause_duration);
      pause_duration = pause_duration - 1000;
    }
    if (pause_duration == 0)
    {
      Serial.println("pause is over");
      pause_duration = 900000;
      lesson = lesson + 1;
    }
  }
}

void displayNumber(byte number, byte segment, CRGB color) {
  /*

      __ __ __        __ __ __          __ __ __        12 13 14
    __        __    __        __      __        __    11        15
    __        __    __        __      __        __    10        16
    __        __    __        __  42  __        __    _9        17
      __ __ __        __ __ __          __ __ __        20 19 18
    __        65    __        44  43  __        21    _8        _0
    __        __    __        __      __        __    _7        _1
    __        __    __        __      __        __    _6        _2
      __ __ __       __ __ __           __ __ __       _5 _4 _3

  */

  // segment from left to right: 3, 2, 1, 0
  byte startindex = 0;
  switch (segment) {
    case 0:
      startindex = 0;
      break;
    case 1:
      startindex = 21;
      break;
    case 2:
      startindex = 44;
      break;
    case 3:
      startindex = 65;
      break;
  }

  for (byte i = 0; i < 21; i++) {
    yield();
    LEDs[i + startindex] = ((numbers[number] & 1 << i) == 1 << i) ? color : alternateColor;
  }
}

void displayDots(CRGB color) {
  if (dotsOn) {
    LEDs[42] = color;
    LEDs[43] = color;
  } else {
    LEDs[42] = CRGB::Black;
    LEDs[43] = CRGB::Black;
  }

  dotsOn = !dotsOn;
}

void hideDots() {
  LEDs[42] = CRGB::Black;
  LEDs[43] = CRGB::Black;
}

void showCountDown()
{

  unsigned long hours   = ((hour_duration / 1000) / 60) / 60;
  unsigned long minutes = (hour_duration / 1000) / 60;
  unsigned long seconds = hour_duration / 1000;

  byte h1 = hours / 10;
  byte h2 = hours % 10;
  byte m1 = minutes / 10;
  byte m2 = minutes % 10;
  byte s1 = seconds / 10;
  byte s2 = seconds % 10;

  CRGB color = CRGB(r_val, g_val, b_val);

  if (hours > 0) {
    // hh:mm
    displayNumber(h1, 3, color);
    displayNumber(h2, 2, color);
    displayNumber(m1, 1, color);
    displayNumber(m2, 0, color);
  } else {
    // mm:ss
    displayNumber(m1, 3, color);
    displayNumber(m2, 2, color);
    displayNumber(s1, 1, color);
    displayNumber(s2, 0, color);
  }
  displayDots(color);
  FastLED.show();
}

void showCountDownPause()
{
  allBlank();
  unsigned long hours   = ((pause_duration / 1000) / 60) / 60;
  unsigned long minutes = (pause_duration / 1000) / 60;
  unsigned long seconds = pause_duration / 1000;

  byte h1 = hours / 10;
  byte h2 = hours % 10;
  byte m1 = minutes / 10;
  byte m2 = minutes % 10;
  byte s1 = seconds / 10;
  byte s2 = seconds % 10;

  CRGB color = CRGB(r_val, g_val, b_val);

  if (hours > 0) {
    // hh:mm
    displayNumber(h1, 3, color);
    displayNumber(h2, 2, color);
    displayNumber(m1, 1, color);
    displayNumber(m2, 0, color);
  } else {
    // mm:ss
    displayNumber(m1, 3, color);
    displayNumber(m2, 2, color);
    displayNumber(s1, 1, color);
    displayNumber(s2, 0, color);
  }
  displayDots(color);
  FastLED.show();
}

void allBlank() {
  for (int i = 0; i < NUM_LEDS; i++) {
    LEDs[i] = CRGB::Black;
  }
  FastLED.show();
}

Have you removed yield() from displayNumber routine?

O, sorry, yes I have. But no succes...

And, when I count up, I see the problem, but so far I have no solution.

When I passed the 1 minute, the seconds counts up to 99.
Then the minutes go to 2, and the segment-problems starts.

So, there is in the code a false calculation of time, but where?

void loop()
{

  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    countup();
    x = x + 1000;

  }
}

and the same of updateClock or countDown...

void countup()
{
  unsigned long hours   = ((x / 1000) / 60) / 60;
  unsigned long minutes = (x / 1000) / 60;
  unsigned long seconds = x / 1000;

  byte h1 = hours / 10;
  byte h2 = hours % 10;
  byte m1 = minutes / 10;
  byte m2 = minutes % 10;
  byte s1 = seconds / 10;
  byte s2 = seconds % 10;

  CRGB color = CRGB(r_val, g_val, b_val);

  if (hours > 0) {
    // hh:mm
    displayNumber(h1, 3, color);
    displayNumber(h2, 2, color);
    displayNumber(m1, 1, color);
    displayNumber(m2, 0, color);
  } else {
    // mm:ss
    displayNumber(m1, 3, color);
    displayNumber(m2, 2, color);
    displayNumber(s1, 1, color);
    displayNumber(s2, 0, color);
  }
  displayDots(color);
  FastLED.show();
}