The timer says it's on, but never executes

I have a sub that starts one of two timers (depending on the state of the zone). This sub called "CheckAndActivateRelays" is itself called by the Serial Port _DataReceived event. I put in breakpoints to help me troubleshoot and I see the tmrSoundSirensAfterDelay.Start () line succeeds when the timer state even changes to enabled. However, the associated Tick event never executes any of the code it contains.

If I do the same by calling sub from inside the click button, it works fine. Everything is in the same form without streams.

Anyone? Thanks to

private void checkAndActivateRelays(int zoneNumber)
   {

       if (globalFullAlarmSet || globalNightAlarmSet || globalDoorsAlarmSet)
           {
               if (zoneNumber == 1) //Entry zone
               {
                   //kick off a timer after delay specified in Settings1 file,
                   if (Settings1.Default.alarmSirenDurationInMinutes != 0)
                   {
                       //activates the relays if global alarm flags are still set to true 
                       //(i.e. user has not entered code in time)
                       globalAlarmEntryDurationTicks = 0;                           
                       tmrSoundSirensAfterDelay.Start();

                   }
               }
               else //If any other zone is activated during alarm set condition
               {
                   if (Settings1.Default.alarmSirenDurationInMinutes != 0)
                   {
                       //Output to relays 1 & 2
                       spIOCard.Write("~out10=1~");
                       spIOCard.Write("~out11=1~");

                       //then close after duration from Settings1 file
                       globalAlarmSirenDurationTicks = 0;
                       tmrSoundSirens.Start();
                   }
               }

           }

   }

   private void tmrSoundSirensAfterDelay_Tick(object sender, EventArgs e)
   {
       globalAlarmEntryDurationTicks = globalAlarmEntryDurationTicks + 1;

       if (globalAlarmEntryDurationTicks == Settings1.Default.alarmEntryDelayInSeconds) //Value from Settings1 file
       {
           spIOCard.Write("~out10=1~");
           spIOCard.Write("~out11=1~");
           globalAlarmEntryDurationTicks = 0;
           tmrSoundSirensAfterDelay.Stop();
           tmrSoundSirens.Start();
       }
   }

   private void tmrSoundSirens_Tick(object sender, EventArgs e)
   {           
       globalAlarmSirenDurationTicks = globalAlarmSirenDurationTicks + 1;

       if (globalAlarmSirenDurationTicks == (Settings1.Default.alarmSirenDurationInMinutes * 5))  //*60 Value from Settings1 file
       {
           spIOCard.Write("~out10=0~");
           spIOCard.Write("~out11=0~");               
           globalAlarmSirenDurationTicks = 0;
           tmrSoundSirens.Stop();
       }
   }



private void button24_Click(object sender, EventArgs e)
   {
       globalFullAlarmSet = true;
       checkAndActivateRelays(1);
   }

      

Received serial port code:

 private void spIO_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
       RxString = spIOCard.ReadExisting();

       if (RxString == "~in00=1~")
       {
           checkAndActivateRelays(1);
           button10.BackColor = System.Drawing.Color.Red;               
       }

       if (RxString == "~in00=0~")
       {
           button10.BackColor = System.Drawing.Color.LightGray;
       }

       if (RxString == "~in01=1~")
       {
           checkAndActivateRelays(2);
           button11.BackColor = System.Drawing.Color.Red;
       }

       if (RxString == "~in01=0~")
       {
           button11.BackColor = System.Drawing.Color.LightGray;
       }

       if (RxString == "~in02=1~")
       {
           button12.BackColor = System.Drawing.Color.Red;
       }

       if (RxString == "~in02=0~")
       {
           button12.BackColor = System.Drawing.Color.LightGray;
       }

      

}

+3


source to share


3 answers


Something to think about as you are using DataReceivedEvent . On MSDN, it goes up on a secondary thread. This is probably causing problems.



The DataReceived event is raised on the secondary thread when data is received from the SerialPort object. Because this event is a secondary thread and not the main thread, trying to change some items on the main thread, such as UI elements, might throw threads. If you need to change items in the main form or control, mail change requests back using Invoke, which will do the work on the corresponding thread.

+1


source


Since calling Start () is not an issue, setting the timer is where you need to look. Make sure you handle the tick event and set the interval.



 myTimer.Tick += new EventHandler(TimerEventProcessor);

   // Sets the timer interval to 5 seconds.
   myTimer.Interval = 5000;
   myTimer.Start();

      

0


source


The key point here is that you do this in an event SerialPort

DataReceived

. This event fires on a separate thread. This is important because you probably registered for an event Tick

on the main thread, but you are starting a timer on another. You need to register the event Tick

with the function checkAndActivateRelays

. Then he should be happy.

The DataReceived event is raised on the secondary thread when data is received from the SerialPort object. Because this event occurs on the secondary thread and not on the main thread, trying to change some elements of the main thread, such as UI elements, may throw a streaming exception. If you need to change items in the main form or control, submit change requests after using Invoke that will do the work on the appropriate flow.

-1


source







All Articles