Newbie having issues with millis

Hi there, I'm brand new to Arduino (and programming in general) so please bare with me.

I'm trying to create a wireless device that will alarm when it disconnects (ie, out of range). I've got a transmitter toggling a high and low signal every 2000 ms. My idea is to have my receiver start a timer when the signal flips, and if it is still in the same sate after 2100 ms, sound an alarm.

the sketch seems to not work, then eventually the alarm get stuck on. Been banging my head for the last couple of days trying different things, so any help would be much appreciated!

Inbedded_-_Inbedded_with_millis.ino (1.06 KB)

please bare with me.

Never on a first date.
What kind of guy do you think I am?

Please post your code, using code tags.

Opps, there we go!

int LED = 13;
int alarm = 7;
int hightimer;
int lowtimer;
#include <VirtualWire.h>

void setup()
{
    vw_set_ptt_inverted(true); // Required for DR3100
    vw_set_rx_pin(12);
    vw_setup(4000);  // Bits per sec
    pinMode(LED, OUTPUT);
    pinMode(alarm, OUTPUT);
    Serial.begin(9600);
    vw_rx_start();       // Start the receiver PLL running
}
    void loop()
{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;

    if (vw_get_message(buf, &buflen)) // Non-blocking
    {
      if(buf[0]=='1')
      {  
       digitalWrite(LED,1);
       hightimer = millis();
       Serial.print(hightimer);
       if(buf[0] =='1' && millis()-hightimer> 2100)
        {
          digitalWrite(alarm, HIGH);
         }
       }  //end of HIGH check
       
     if(buf[0]=='0')
        {
          digitalWrite(LED,0);
          lowtimer = millis();
          if(buf[0] =='0' && millis()-lowtimer > 2100)
            {
              digitalWrite(alarm, HIGH);
            }
       }  //end of LOW check

    
}//END OF Rx


}//END OF LOOP

I see what you're saying. Any suggestions on ways to fix this?

I tried using the delay function, but it makes the program slowly drift out of sync...

Have also tried putting the logic into a while() but couldn't get it to work.

Is my approach to this fundamentally flawed? It seems that I need be running two routines at once.

Look at how the Blink without Delay sketch works.

Always use type ' unsigned long ' with millis variables.

I'm trying to create a wireless device that will alarm when it disconnects (ie, out of range). I've got a transmitter toggling a high and low signal every 2000 ms. My idea is to have my receiver start a timer when the signal flips, and if it is still in the same sate after 2100 ms, sound an alarm.

loop() {
  What time is it now? Millis(). 
  What state is the input in now? digitalread().
  What state was the input it last time I read it? That's stored in a variable.
  When did the state last flip? That's stored in a variable, too.

  If the input has changed state since the last time I read it {
    put the new state in the variable
    put the current millis in the variable.
  }
  else {
    if it's been more than (say) 2100 millis since last state change {
      sound an alarm
    }
    else {
      meh, do nothing
    }
  }
}

The demo Several Things at a Time is an extended example of the use of millis().

...R

Thanks everyone, that really helps. I feel like I'm getting close but my code still isn't working.

My alarm isn't going off when disconnecting, though sounds briefly when the signal reconnects.

int ledPin = 13;
int ledState;
int alarmPin = 7;
int alarmState;
int flag;
unsigned long markA = 0;
unsigned long currentMillis;
unsigned long markB = 0;
const long interval = 2100;
#include <VirtualWire.h>

void setup()
{
    vw_set_ptt_inverted(true); // Required for DR3100
    vw_set_rx_pin(12);
    vw_setup(4000);  // Bits per sec
    pinMode(ledPin, OUTPUT);
    pinMode(alarmPin, OUTPUT);
    Serial.begin(9600);
    vw_rx_start();       // Start the receiver PLL running
}
    void loop()
{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
    currentMillis = millis();

    if (vw_get_message(buf, &buflen)) // Non-blocking
    {
      if(buf[0]=='1')
      {  
       ledState = HIGH;
       markB = currentMillis;
         if(currentMillis - markA > interval)
           {
            alarmState = HIGH;
           }
           else
           {
            alarmState = LOW;
           }
      }
     
      if(buf[0]=='0')
        {
          ledState = LOW;
          markA = currentMillis;
            if(currentMillis - markB > interval)
            {
              alarmState = HIGH;
            }
            else
            {
              alarmState = LOW; 
            }
        }
    }   
    
digitalWrite(alarmPin, alarmState);
digitalWrite(ledPin, ledState);

}//END OF LOOP

I would consider using a faster burst rate and then looking for the burst for a any one out of 3 or so where a missed burst or two does not trigger the alarm. RF is subject to all sorts of outside interference (other transmitters, phase of the moon, something blocking the signal etc.). Give it multiple chances to reset the counter (start counting up with a count time of the expected burst timing - if your counter exceeds the limit you specify, then you are indeed out of range, when you receive a burst, you reset the counter). Basing the alarm on a single missed reception will probably end up driving you nuts.

Thanks, I tried increasing the rate but still no error detection.

just retried Paul's code, working now!

Thanks so much!