TM1637.h library displays incorrect characters after extended period of time

The project:
I am using a TM1637 7seg display as a count down timer for a coin operated module. Basically you put a quarter into a coin acceptor module, it sends a pulse to the Arduino, that adds a set amount of time to the counter and the time left on the counter is displayed on the TM1637 7seg display. So long as there is time left on the counter a relay is triggered that powers an external device. I am using TM1637.h "Grove 4-Digit Display" library from Seeed Studio to control the display.

The problem:
Everything works as intended until I leave the Arduino running for 2 hours or so. After running for a while the TM1637 display will display the top segment lit on all 4 character positions when it should just leave them blank. Upon inserting a coin the timer and relay works as it should and when its done counting down the display returns to the aforementioned state. Hitting reset or cycling power fixes this and after running for a while the display repeats the behavior.

I am fairly certain I have narrowed the problem down to the library itself as I have monitored pretty much all variables to look for something that may be rolling over after extended periods of time and I haven't found any culprits.

Are there any variables in the TM1637.h library that would be rolling over and causing it to display these odd characters rather than just being blank like it is supposed to?

My code:

#include <TM1637.h>
#include <Arduino.h>
#include <EEPROM.h>
#include <TM1637.h>
// Seconds to add to timer per 25c
int QuarterTimeAdd=300;

//clock and data pins for display
int CLK = 3;
int DIO = 4;
// relay pin
int relayPin = 5;

//defining variables for display
TM1637 tm(CLK,DIO);

// variable use to measure the intervals inbetween impulses
volatile int i=0;
// Number of impulses detected
volatile int impulsCount=0;
// Time left to run motor in seconds
volatile int time_left=0;
//Minutes and seconds variables derived from time_left
volatile int minutes=0;
volatile int seconds=0;
//Minutes and seconds variables to display on timer
volatile int tensOfMin_left=0;
volatile int Min_left=0;
volatile int tensOfSec_left=0;
volatile int Sec_left=0;
//arduino timer storage variable
boolean toggle1 = 0;

void setup() {
 // Serial.begin(9600);
 // setting up timer1 on arduino for 1hz (every second)
 cli();//stop interrupts
 //set timer1 interrupt at 1Hz
  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;//initialize counter value to 0
  // set compare match register for 1hz increments
  OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (must be <65536)
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS10 and CS12 bits for 1024 prescaler
  TCCR1B |= (1 << CS12) | (1 << CS10);  
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);
  sei();//allow interrupts  
  
  // Interrupt connected to PIN D2 executing IncomingImpuls function when signal goes from HIGH to LOW
 attachInterrupt(digitalPinToInterrupt(2),incomingImpuls, FALLING);
 
 // setting up relayPin as output
  pinMode(relayPin, OUTPUT);
  
  //initalizing display
  tm.init();
  //set brightness; 0-7
  tm.set(7);
}

void incomingImpuls()
{
  cli();
  impulsCount=impulsCount+1;
  i=0;
  sei();
}

ISR(TIMER1_COMPA_vect){//timer1 interrupt 1Hz subtracts 1 from time_left)
//generates pulse wave of frequency 1Hz/2 = 0.5kHz (takes two cycles for full wave- toggle high then toggle low)
  if (toggle1){
    if (time_left <= 0){}
    else{
    time_left = time_left - 1;
    toggle1 = 0;
    }
  }
  else{
    if (time_left <= 0){}
    else{
    toggle1 = 1;
    time_left = time_left - 1;
  }
  }
}  
void loop() {
//  Serial.println(time_left);
  //i ,intervul between pulses, is increased by 1 for each loop
  i=i+1;

// if coin counter detects quarter add 25 to time_left
 if (i>=30 and impulsCount==1){
   cli();
       if (time_left <=0){
      time_left = QuarterTimeAdd;
      }
      else{
    time_left=time_left+QuarterTimeAdd;
      }
    impulsCount=0;

    sei();
  }
//converting time_left in seconds to munites and seconds
seconds = time_left % 60;
minutes = time_left / 60;
//converting minutes and seconds to digits to be displayed
tensOfMin_left = minutes / 10;
Min_left = minutes % 10;
tensOfSec_left = seconds / 10;
Sec_left = seconds % 10;

//if time is <= 0 display 25CE else display time_left
// 7 segment displays these characters at these values 0-9=0-9 10-15=A-F 16=top segment blink 17=all segments stutter 18=pattern of filling in segments 19=top+topleft segments lit 20=all segments off
if(time_left<=0){
    tm.display(0,20);
  tm.display(1,20);
  tm.point(0);
  tm.display(2,20);
  tm.display(3,20 );
}
else{
    tm.display(0,tensOfMin_left);
  tm.display(1,Min_left);
  tm.point(1);
  tm.display(2,tensOfSec_left);
  tm.display(3,Sec_left);
}

// if time_left <=0 set relay pin to low else set it to high
if(time_left<=0){
  digitalWrite(relayPin,LOW);
  }
else{
  digitalWrite(relayPin,HIGH);
  }
// Serial.println(time_left);
}

Hi, @mazdamiata
Welcome to the forum.
Thanks for posting your code in tags.

Can you please post a schematic of your project?
What are you using to power your project?
Have you monitored your power supply?

Are you using the DC socket or 5V to the 5V pin or USB?

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

1 Like

There are multiple libraries available for the TM1637, so your question could be answered easily by trying a different one.

1 Like

Hi,

What model Arduino are you using?

Thanks.. Tom.... :smiley: :+1: :coffee: :australia:

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