Want to use Counter/Timer in Arduino

I want to use counter/timer in my Arduino such that if there will be no commands or signals for 5 seconds then everything should be stopped.

I am using a radio link for wireless communication to run two motors so if signal lost I mean will not receive the signal from the radio-link transmitter section within 5 seconds then motors should stop working;

There is a need of this if it is out of range then motors continuously runs; because it received the last signal from the radio-link.

Thank you

That's what the built in function 'millis()' is used for.

you could architect your code this way

unsigned long lastBeat = 0;
const unsigned long timeout = 5000; // 5s in ms

bool commandPending() {
  // to change
  // returns true if a command is pending
  return ... ;
}

void handleCommand() {
  // ..
}

void heartBeatLost() {
  // ...
}

void setup() {
  // ...
}

void loop() {
  // deal with commands
  if (commandPending()) {
    handleCommand();
    lastBeat = millis();
  }

  // deal with timeout
  if (millis() - lastBeat >= timeout) {
    heartBeatLost();
  }
}

just need to fill in the ...

1 Like
unsigned long TimeoutTimer = 0;

void loop()
{
   if (millis() - TimeoutTimer > 5000)
      SHUT_DOWN();

   if (radio received data)
      TimeoutTimer = millis();
}
1 Like

Yes , like this one ...
Can you please write it with the explanation code with the comments ? I'm a little bit confused :slight_smile:

it's basically the same as the one I posted too. I just added a bit more meat on the bone.

The way it works is you maintain current a variable (TimeoutTimer or in my case lastBeat) that records the last time you got a command (ie update it every time you get a command) and you always compare that time with the current time. If it's more than the 5s delay, then it's a timeout and you need to handle it

1 Like

What part do you not understand?

this one

TimeoutTimer = millis(); // Re-start the timeout timer

1 Like

means its update the time every 5 seconds ?

NO.

Here, I'll read it for you

unsigned long TimeoutTimer = 0;

void loop()
{
   if (millis() - TimeoutTimer > 5000)
      SHUT_DOWN();

   if (radio received data)
      TimeoutTimer = millis();
}

Declare a time stamp variable.
Repeat endlessly:

  • any time the current time is more than 5 seconds greater than the time stamp, shut down
  • any time a radio message is received, record the current time in the time stamp

end repeat

1 Like

means if signal will receive after 5 seconds then shut down ... ?

means radio signal receive within every 5 seconds ?

YES

NO (just means update the timestamp whenever you get a signal)

okay so it stop working when It will not receive any signal ..?

well, it does what you want to do in the SHUT_DOWN(); or heartBeatLost(); (for my code) function

so if you shut down the motors in that line, then the motors won't restart until you get a new command. (and the shutdown function will keep getting called until such time)

1 Like

Here is the code that I want to add the timer/counter function

#include <Servo.h>
const int m_1 = 5;
const int m_2 = 6;


String strID = "";
int BaudRate = 4800;
Servo ESC_1; // create servo object to control the ESC 1
Servo ESC_2; // create servo object to control the ESC 2
#define FWD 0
#define BWD 1

unsigned int FORWARD = 2000;
unsigned int NEUTRAL = 1500;
unsigned int REVERSE = 1000;

unsigned int APwm = NEUTRAL;
unsigned int BPwm = NEUTRAL;

boolean ADirection = FWD;
boolean BDirection = FWD;
unsigned int AVelocity = 0; // CURRENT VELOCITY OF M1 in 0-100%
unsigned int BVelocity = 0; // CURRENT VELOCITY OF M2 in 0-100%

String inputString = "";
int TaskNumber = 0;


unsigned int GetValue(void)// fetch three digit number value from received string and convert to INTEGER
{
  unsigned int Val = 0;
  Val = (inputString[3] - 48) * 100;
  Val = Val + (inputString[4] - 48) * 10;
  Val = Val + (inputString[5] - 48);
  return (Val);
}

void setup()
{
  Serial.begin(BaudRate); 
 
  ESC_1.attach(m_1);// (pin, min pulse width, max pulse width in microseconds)
  ESC_2.attach(m_2);// (pin, min pulse width, max pulse width in microseconds)

  Serial.println("ABC System Started");
  ESC_1.writeMicroseconds(APwm);
  ESC_2.writeMicroseconds(BPwm);
}
boolean AFwdFlag = 0;
boolean BFwdFlag = 0;

void loop()
{
   
  
serialEvent(); 

if(TaskNumber){
  if(TaskNumber==1) Serial.println("OK");
  if(TaskNumber==2 || TaskNumber==4) {ESC_1.writeMicroseconds(NEUTRAL); } //motor A for Neutral
  if(TaskNumber==3 || TaskNumber==4) {ESC_2.writeMicroseconds(NEUTRAL);}  //motor B for Neutral

 // Task 4 is common here above, it means that both motors are at neutral position 
  
  if(TaskNumber==5 || TaskNumber==7) {             // Task 5 = motor A is in forward direction or backward direction and Task 7 =  both motors are in forward or backward direction
                      if(ADirection==FWD) { APwm= NEUTRAL + (((FORWARD-NEUTRAL)/100)*AVelocity); ESC_1.writeMicroseconds(APwm); AFwdFlag=1; }
                      else {
                              if(AFwdFlag==1)
                               {
                                ESC_1.writeMicroseconds(NEUTRAL);delay(100);
                                ESC_1.writeMicroseconds(REVERSE);delay(100); 
                                ESC_1.writeMicroseconds(NEUTRAL);delay(100);
                                AFwdFlag=0;
                               } 
                              APwm= NEUTRAL - (((NEUTRAL-REVERSE)/100)*AVelocity); ESC_1.writeMicroseconds(APwm);  
                           }
                     } 


  if(TaskNumber==6 || TaskNumber==7) {                 // Task 6 = motor B is in forward direction or backward direction and Task 7 =  both motors are in forward or backward direction
                      if(BDirection==FWD) { BPwm= NEUTRAL + (((FORWARD-NEUTRAL)/100)*BVelocity); ESC_2.writeMicroseconds(BPwm); BFwdFlag=1; }
                      else {
                              if(AFwdFlag==1)
                               {
                                ESC_2.writeMicroseconds(NEUTRAL);delay(100);
                                ESC_2.writeMicroseconds(REVERSE);delay(100); 
                                ESC_2.writeMicroseconds(NEUTRAL);delay(100);
                                BFwdFlag=0;
                               } 
                              BPwm= NEUTRAL - (((NEUTRAL-REVERSE)/100)*BVelocity); ESC_2.writeMicroseconds(BPwm);  
                           }
                     } 

 
  TaskNumber=0;
  
}

}
// <AN> <A+xxx> <A-xxx>
// <BN> <B+xxx> <B-xxx>
// <CN> <C+xxx> <C-xxx>

void serialEvent() {      // RX0 for receiving 

  while (Serial.available()) {             
 
    char inChar = (char)Serial.read();
    inputString += inChar;

    if (inChar == '\r' || inChar == 10)
    {
      
      if(inputString[0]=='<') 
      {

        if(inputString[1]=='A' && inputString[2]=='T' && inputString[3]=='>' ) TaskNumber=1; // AT

        if(inputString[2]=='N' && inputString[3]=='>' )
        {
          if ( inputString[1] == 'A') TaskNumber = 2; // Set Motor A to Neutral
          if ( inputString[1] == 'B') TaskNumber = 3; // Set Motor B to Neutral
          if ( inputString[1] == 'C') TaskNumber = 4; // Set Both Motors to Neutral
        }
    
        if(inputString[6]=='>' )
        {
          
          if ( inputString[1] == 'A') { 
            if(inputString[2]=='+') ADirection=FWD; else ADirection=BWD; 
            AVelocity=GetValue(); 
            TaskNumber=5;
          }  
          
          if ( inputString[1] == 'B') { 
            if(inputString[2]=='+') BDirection=FWD; else BDirection=BWD; 
            BVelocity=GetValue(); 
            TaskNumber=6;
          }  
                    
          if ( inputString[1] == 'C'){ 
            if(inputString[2]=='+') { ADirection=FWD; BDirection=FWD;} 
            else {ADirection=BWD; BDirection=BWD;} 
            AVelocity=GetValue();
            BVelocity=GetValue(); 
            TaskNumber=7;
          }  
          
        }
  
      }
      inputString = "";
    }
  }

Do some research into the processor watchdog feature.

what do you expect us to do with your code?

can't you try to integrate the concept of keeping time of the last message?

Well, research never hurts. But this is not a good application for the watchdog. Lots of timeouts are managed very simply by program logic and the millis/micros timers. The watchdog exists mainly to restart the program if completely unexpected behaviour like a rare software bug or hardware fault condition causes the processor to lose control. Not for something expected like this.

That's a fairly complex bit of software. I'm sure at your level of programming you can figure out a simple thing like this.

Just locate the places where:

  • you receive some input
  • you want it to stop
1 Like