Running an I2C device and several timers simultaneously

Hi, I am trying to build an alarm clock that first light up an LED progressively, and then launch a piezo alarm. I am using an 4 digits LED display with TM1637 chip as an I2C interface.

The problem is that there are timer conflicts between the display and the alarms, and that the time counter 'freeze' while the alarm is progressively firing up.

When I remove the code for TM1637, first the LED fade in, and then the piezo alarm starts, as it should. But when I add the I2C library, once the alarm starts the time on the display freeze and the LED light up at full power (without fading in), followed by a continuous piezo sound..

I came across the TimedAction library, but I don't really get how to use it with my particular project..

Here's my code so far:

//Clock display Start
#include <TimerOne.h>
#include "TM1637.h"
#define ON 1
#define OFF 0

int8_t TimeDisp[] = {0x00,0x00,0x00,0x00};
unsigned char ClockPoint = 1;
unsigned char Update;
unsigned char halfsecond = 0;
unsigned char second;
unsigned char minute = 0;
unsigned char hour = 12;

#define CLK 5
#define DIO 6
TM1637 tm1637(CLK,DIO);
//Clock display End

int speakerPin = 4;
int ledPin = 3;

void setup()
{
 // Serial.begin(9600);
  tm1637.set();
  tm1637.init();
  Timer1.initialize(500000);//timing for 500ms
  Timer1.attachInterrupt(TimingISR);//declare the interrupt serve routine:TimingISR  
}

void loop()
{
  if(Update == ON)
  {
    TimeUpdate();
    tm1637.display(TimeDisp);
  }
}

void TimingISR()
{
  halfsecond ++;
  Update = ON;
  if(halfsecond == 2){
    second ++;
    if(second == 60)
    {
      minute ++;
      if(minute == 60)
      {
        hour ++;
        if(hour == 24)hour = 0;
        minute = 0;
      }
      second = 0;
    }
    halfsecond = 0;  
  }
  
 //Start alarms
 if ((hour == 12) && (minute == 1)) {
   led_alarm();
   piezo_alarm();
   }
 
 
 
  ClockPoint = (~ClockPoint) & 0x01;
}

void TimeUpdate(void)
{
  if(ClockPoint)tm1637.point(POINT_ON);
  else tm1637.point(POINT_OFF); 
  TimeDisp[0] = hour / 10;
  TimeDisp[1] = hour % 10;
  TimeDisp[2] = minute / 10;
  TimeDisp[3] = minute % 10;
  Update = OFF;
}

void led_alarm()
{
  pinMode(ledPin, OUTPUT);
  analogWrite(ledPin, LOW);
  for (int fadeValue = 0; fadeValue <= 150; fadeValue += 1) {
    analogWrite(ledPin, fadeValue);
    delay(1000);
  }
 delay(5000);
}
  
void piezo_alarm()
{
for (int x = 0; x < 15; x++) {
tone(speakerPin, 80, 80);
delay(3000);
}
////////////
for (int x = 0; x < 10; x++) {
tone(speakerPin, 100, 60);
delay(120);
tone(speakerPin, 100, 60);
delay(2000);
}
///////////
for (int x = 0; x < 8; x++) {
tone(speakerPin, 100, 60);
delay(120);
tone(speakerPin, 300, 60);
delay(600);
}
}

I hope someone can give me some advice on how to fix the conflicts and use the timers simultaneously, to keep track of time while the alarm is firing up.

Thank you!

you have used delays and for in the program.

a delay means stop and count down till end of delay. Do nothing else while waiting

a "for" means do nothing but go round and round the same piece of code until it ends. If there is a delay then go around, stop do nothing, go back around

wouldn't it be better if you checked to see if a piece of code needs to be paused then go of and play in the rest of the program then return in say a few ms to check on the pause again

wouldn't it be better then to loop around making a led fade you changed the led slightly then went of to check the program and on the next time around made it just a touch brighter before going of again to check the rest of the code

look at blink with out delay examples and how to make a simple counter

I strongly suspect you could write an alarm clock code without using the Timer library. Just use millis() and there should not be any conflicts. See the demo several things at a time which is an extended example of BWoD

...R

Thank you very much, millis() was exactly what I was looking for! Your example helped a lot !