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