I'm facing a problem with my Arduino Nano, LED PWM-driver and a DCF77 time modul (sorry it's in german).
In a nutshell: I can light up the LEDs in the way I want them and I can receive the correct time from the dcf77 modul seperatly. BUT as soon as I combine it, it fails.
So the idea is, to have the time modul to give me the time and then light up the correct LEDs. But as soon as I light up any LEDs, I don't get the time anymore, hence my output stops. So I can read the time as long as I want, but the moment I visualize it, everthing stops. I simplified my code to make it easier to understand:
#include <Tlc59711.h>
#define DATA_PIN 11
#define CLOCK_PIN 13
#define NUM_CONTROLLERS 4
#define NUM_LEDS NUM_CONTROLLERS * 12
#define LED_ON 20535 // max is 65535
#define DCF_PIN 7
int HIGH_Start = 0;
int HIGH_Ende = 0;
int HIGH_Zeit = 0;
int LOW_Start = 0;
int LOW_Ende = 0;
int LOW_Zeit = 0;
bool Signal = false;
int ZEIT_SEKUNDE = 0;
int ZEIT_MINUTE = 0;
int ZEIT_STUNDE = 0;
bool registers[NUM_LEDS];
Tlc59711 tlc(NUM_CONTROLLERS);
void setup() {
Serial.begin(9600);
pinMode(10, OUTPUT);
tlc.beginSlow(200, true);
clearLEDs();
setTime();
pinMode(DCF_PIN, INPUT);
}
void loop() {
unsigned long currentMillis = millis();
int DCF_SIGNAL = digitalRead(DCF_PIN);
if (DCF_SIGNAL == HIGH && Signal == false) {
Signal = true;
HIGH_Start = currentMillis;
LOW_Ende = HIGH_Start;
LOW_Zeit = LOW_Ende - LOW_Start;
registers[14] = 1;
if(LOW_Zeit > 350) {
ZEIT_SEKUNDE++;
// I can wait here for any amount of time
// and I will get no LOW signal anymore afterwards
if (ZEIT_SEKUNDE > 50) {
num2LEDs(ZEIT_SEKUNDE, 0);
setTime();
}
}
}
if (DCF_SIGNAL == LOW && Signal == true) {
Signal = false;
registers[14] = 0;
HIGH_Ende = currentMillis;
LOW_Start = HIGH_Ende;
HIGH_Zeit = HIGH_Ende - HIGH_Start;
// setTime();
}
}
void clearLEDs() {
// Reset all register pins
for (int i = 0; i < NUM_LEDS; i++) {
registers[i] = false;
}
}
void time2LEDs() {
ZEIT_SEKUNDE = ZEIT_SEKUNDE + 1;
if(ZEIT_SEKUNDE == 60) {
ZEIT_SEKUNDE = 0;
ZEIT_MINUTE = ZEIT_MINUTE + 1;
if(ZEIT_MINUTE == 60) {
ZEIT_MINUTE = 0;
ZEIT_STUNDE = ZEIT_STUNDE + 1;
if(ZEIT_STUNDE == 24) {
ZEIT_STUNDE = 0;
}
}
}
num2LEDs(ZEIT_SEKUNDE, 0);
num2LEDs(ZEIT_MINUTE, 14);
num2LEDs(ZEIT_STUNDE, 28);
}
void num2LEDs(uint8_t value, int offset) {
uint8_t units = value % 10;
uint8_t tens = (value - units) / 10;
for (int i = 0; i < 9; i++) {
if (units - i > 0) {
registers[i + offset] = 1;
} else {
registers[i + offset] = 0;
}
}
for (int i = 0; i < 6; i++) {
if (tens - i > 0) {
registers[i + 9 + offset] = 1;
} else {
registers[i + 9 + offset] = 0;
}
}
}
void setTime() {
for (int i = 0; i < NUM_LEDS; i++) {
if (registers[i] == 1) {
tlc.setChannel(i, LED_ON);
} else {
tlc.setChannel(i, 0);
}
}
tlc.write();
}
I just modified that library in a little way and removed lines with SPIF, because the nano doesn't have it. But since this code works as long as I don't use the dcf77 modul, I figured that should not be a problem. If needed I can provide that modified code as well.
If you a Timer Module -- is it a real time clock? After reading the time of the day, in which variables you are storing them in your sketch? Please, post the picture of your Timer Module? (I normally use DS3231/DS1307 RTC Module.)
Are you showing the time of the day on display unit? Show the picture of the display unit. What do you mean by LED display?
Thank you already for your interest! @SurferTim From the code you see that the DCF77 input is assigned to Pin 7 and the LED driver is at the SPI ports 11 and 13. Since the LED driver doesn't have a latch, because the latch is set automatically after 200ms without new inut.
@GolamMostafa I'm not a 100% sure what you men, but I guess the answer is yes. The module is basically just an antenna receiving in every second the a new bit for hours, minutes, days, ... If you click on the link you for the mosule there is an image of it, but in German unfortunatly since it's a german time module.
And my LED display is just single LEDs only showing the time. But for simplifying the code I don't store that data but just receive the seconds here which results in the same error.
And no there is no library. But here on Wikipedia you can find a documentation how to read the time signal: DCF77 - Wikipedia
Can you read the accumulated seconds from your Time Module and show it on the Serial Module of NANO?
Say, you have got 10 from your Time Module, how are you going to show it by the single LED? Do you flash the LED for 10 times? At what DPin, the LED is connected>
What is the interfacing of your Module -- SPI, UART, I2C, Bitbang?
@mainz007
Are you sure you posted the right code, it does not compile.
ZEIT_MINUTE is not defined. I'm sure there are many many other errors.
Please check your code
Be careful that you are not calling setTime() at a place that the delay involved with writing to the LED controller will interfere with the decoding of the signal from the DCF77.
I don't see how FreeRTOS could possibly help. If writing to the LED controller is causing enough of a delay to interfere with measuring a precise time with millis(), then switching tasks in a RTOS would likely cause even worse time measurement errors.
@jim-p Sorry you're right, I quickly also deleted unneccessary variables without compiling again. I edited my code to add those again, but nothing else.
@david_2018 I was missing the delay, in the LED driver modul. Will try later, if that is the problem. Because the time modul sends for 100 or 200ms a high signal and the transfering hapens after a 200ms delay. So this could really be the case. Will let you know later if it worked.
Well the millis () function uses interrupts for timing and unfortunately the Adafruit TLC59711 code disables interrupts for a while everytime it sends data to the LEDs. That will cause millis() to skip some counts.
It will also affect delay()
Sorry I start to become crazy with this project. The delay is only 200 microseconds and the HIGH should be 100 or 200milliseconds.
@david_2018 I think you're right but currently I don't know how to solve it tbh. But I'm sure now it has something to do with the library. Maybe I need to write my own library...
It is possible it is a hardware problem. post an annotated schematic (the language of electronics) showing exactly how it is wired, show all power sources etc. Post links to technical information on each of the hardware devices.
I wait until the total 1000ms are over and see when the HIGH/LOW change happens.
That millis is using interrupt and my library is disabling interrupts, would just mean that I can maybe not realiably count if the HIGH was 100 or 200ms, but I would stay in a rythmn of 1000ms +/- to increase the time by a second. So the clock should not stop but only show the wrong time.
I do not think so, intermittent processors are rarer and fail rather quickly if faulty. Your problem is not unique. I recommend using the rising or falling edge of the input, the Nano can detect that. This will give you more time to do your processing. Check this link: https://docs.arduino.cc/built-in-examples/digital/StateChangeDetection/
@gilshultz But I already do that. I just also count how many seconds passed since then or am I missing something?
I also added the schematics and actual layout. I have problems understanding, why Fritzing suggestes additional connections (visualized by the dashed lines).