Arduino Nano with SPI and digital input

Hello everyone,

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();
}

The included library is not the original from Adafruit but a modified one by Ulrich Stern, which can be found here: GitHub - ulrichstern/Tlc59711: Arduino library for controlling TI's TLC59711 (or TLC5971)

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.

Thank you very much for your help already.

Best regards
Marco

UPDATE 1: Schematics and Layout:


It might help if you post how the devices are connected to the Nano.

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?

Is there a library for the DCF77 module?
I don't see it included.

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.

The problem as suspected in post #8 could be avoided by allowing the two tasks running concurrently under Arduino_FreeRTOS.

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.

1 Like

That was my intuitive assertion. The actual result could be established by real experiments.

@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()

1 Like

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...

See post #13

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.

Sorry for the delay:

@jim-p Why is missing some counts a problem?

  1. I count the high period which is 100 or 200ms
  2. I send the new data to via SPI and wait 200 µs.
  3. 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.

@gilshultz I will provide the schematics later this evening. But if it's a hardware problem it should be one with the Arduino Nano right? And those schematics are available here already: https://content.arduino.cc/assets/NANOEveryV3.0_sch.pdf

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).