Constantly collecting sensor input & acting on data on a schedule

I'm new at programming Arduino and don't have a programming background, although I've written several simplistic programs, but none of them were time sensitive or used interrupts.

Please let me know how you might approach this using Arduino. Maybe there is a library that makes this easier.

  • Constantly gather data from multiple sensors, and
  • Periodically analyze the sensor data, then act on it.

Initially, the period will be constant, but I suspect it might be necessary to change the period based on the rate of change in the sensor data.

Thanks in advance for your help.

I'm new at programming Arduino and don't have a programming background, although I've written several simplistic programs, but none of them were time sensitive or used interrupts.

Please let me know how you might approach this using Arduino. Maybe there is a library that makes this easier.

  • Constantly gather data from multiple sensors, and

  • Periodically analyze the sensor data, then act on it.

Initially, the period will be constant, but I suspect it might be necessary to change the period based on the rate of change in the sensor data.

Thanks in advance for your help.

That's a pretty open and vague question. The answer must be similar. To do so, you simply write the code that reads the sensors and then write the code to react to the values you get. If you want responsiveness, make sure none of it is blocking code, so no for or while loops waiting for some long process to finish all the way and absolutely no use of the delay function.

Try to get started writing some code. It will be a lot easier to help you out once you have that. Even if it is crappy code, at least it gives us something to work from.

It depends on what you mean by "constantly collecting". Where do the collected data go, before they are processed further?

If you want to watch the input for significant changes, this has to be done during data acquisition. Then a single variable for each data channel holds the current sensor value, and an alert flag can be set when a significant change is detected. Another part of loop() does some output, either periodically or if the alert flag is set.

Look at the BlinkWithoutDelay function for doing something at regular intervals, then extend the condition to do the same also if the alert flag is set.

 if (alert || millis()-lastTime>=interval) doSomething;

I’ve written some code, but it is basically sequential. First data from sensors are collected (to measure the distance from vehicle to any objects in its way. Then adjustments to the vehicle’s trajectory are made in a series of “if” statements.

/*
  Trigger pins have oranges wires
  Echo pins have brown wires
 */

#include "QuickStats.h"
QuickStats stats;

#define AIN1pin 12
#define AIN2pin 11

#define SLPpin 10

#define BIN2pin 9
#define BIN1pin 8

#define trigPinLeft 7
#define trigPinCenter 5
#define trigPinRight 3

#define echoPinLeft 6
#define echoPinCenter 4
#define echoPinRight 2


#define hard 100  //  time allotted for a hard turn
#define slight 100  // time allotted for a slight turn
#define slowspeed 125
#define fastspeed 125
#define cd 30 // cd is critical distance or the distance to decide when to go straight or stop
#define rh 1.05
#define rl 0.95

  int Left, Center, Right, PreviousLeft, PreviousCenter, PreviousRight;

/*
 * Bout is right wheel
 * Aout is left wheel
 * Distance Detector: Brown wire = echo ;   Orange wire = trigger
 * 
 */

void setup() {

  pinMode(trigPinRight,  OUTPUT);
  pinMode(trigPinCenter, OUTPUT);
  pinMode(trigPinLeft,   OUTPUT);
  pinMode(echoPinRight,  INPUT);
  pinMode(echoPinCenter, INPUT);
  pinMode(echoPinLeft,   INPUT);
  pinMode(SLPpin,OUTPUT) ;
  pinMode(AIN1pin,OUTPUT);
  pinMode(AIN2pin,OUTPUT);
  pinMode(BIN1pin,OUTPUT);
  pinMode(BIN2pin,OUTPUT);

  Serial.begin (9600);

}

void loop() {
  

  
  // Determine distances for left, center and right side of vehicle
  
     Left = checkdistance(trigPinLeft, echoPinLeft);
     Center = checkdistance(trigPinCenter, echoPinCenter);
     Right = checkdistance(trigPinRight, echoPinRight);

 // Print distances measured
    
    Serial.print(Left);
    Serial.print(", ");
    Serial.print(Center);
    Serial.print(", ");
    Serial.println(Right);

    // check to see if vehicle is not moving
    
   if ( 
      (Left <= rh *PreviousLeft && Left >= rl *PreviousLeft)  &&
      (Center <= rh *PreviousCenter && Center >= rl *PreviousCenter) &&
      (Right <= rh *PreviousRight && Right >= rl *PreviousRight) )

      {
        stopnow();
        backward( slowspeed, 2000);
        stopnow();
        Serial.println("backwards");
        goto EndofDistanceCheck;        
        
      }

   // if getting to close on all sides, then stop
    
   if (Right < cd && Center < cd && Left < cd) {

       stopnow();
       delay(1000);
       Serial.println("stop");
       goto EndofDistanceCheck;    
       }

// if clear on all sides by distance cd, then go straight

  if (Right >= cd && Center >= cd && Left >= cd) {  

       Serial.println("go straight");
       forward(fastspeed);
       goto EndofDistanceCheck;
       }

 // make turns based on relative distances from vehicle to objects

  if (Left <= Right && Right <= Center) {  
    
       Serial.println("slight right");
       turnright(slowspeed,slight);
       goto EndofDistanceCheck;
       }

   if (Left <= Center && Center <= Right) {
      
       Serial.println("hard right");
       turnright(slowspeed, hard);
       goto EndofDistanceCheck;
       }

   if (Center <= Left && Left <= Right) {
    
       Serial.println("hard right");
       turnright(slowspeed, hard);
       goto EndofDistanceCheck;
       }
       
   if (Right <= Left && Left <= Center) {  
    
       Serial.println("slight left");
       turnleft(slowspeed,slight);
       goto EndofDistanceCheck;
       }
        
   if (Right <= Center && Center <= Left) {  

       Serial.println("hard left");
       turnleft(slowspeed,hard);
       goto EndofDistanceCheck;
       }

   if (Center <= Right && Right <= Left) {
    
       Serial.println("hard left");
       turnleft(slowspeed,hard);
       goto EndofDistanceCheck;
       }



EndofDistanceCheck:
    Serial.print(Left);
        Serial.print(", ");
        Serial.println(PreviousLeft);
        Serial.print(Center);
        Serial.print(", ");
        Serial.println(PreviousCenter);
        Serial.print(Right);
        Serial.print(", ");
        Serial.println(PreviousRight);

Record previous distances in order to make a comparison with next set of measurements

     PreviousLeft = Left;
     PreviousCenter = Center;
     PreviousRight = Right;  

}

// Begin subroutines

void turnright(int speed, int time) {  
  digitalWrite(AIN1pin,LOW);
  digitalWrite(AIN2pin,HIGH);
  digitalWrite(BIN1pin,LOW);
  digitalWrite(BIN2pin,LOW);
  go(speed);
  delay(time);
}


void turnleft(int speed, int time) {  
  digitalWrite(AIN1pin,LOW);
  digitalWrite(AIN2pin,LOW);
  digitalWrite(BIN1pin,LOW);
  digitalWrite(BIN2pin,HIGH);
  go(speed);
  delay(time);
}


void forward(int speed) { 
  digitalWrite(AIN1pin,LOW);
  digitalWrite(AIN2pin,HIGH);
  digitalWrite(BIN1pin,LOW);
  digitalWrite(BIN2pin,HIGH);  
  go(speed);
}


void backward(int speed, int time) { 
  digitalWrite(AIN1pin,HIGH);
  digitalWrite(AIN2pin,LOW);
  digitalWrite(BIN1pin,HIGH);
  digitalWrite(BIN2pin,LOW); 
  go(speed);
  delay(time);
}


void stopnow() {  // Stop by setting SLP pin to 0
  digitalWrite(SLPpin, LOW); 
}


void go(int setspeed) {  // Go at set speed by setting SLP pin using analog write
  analogWrite(SLPpin, setspeed);
}

// take three measurements and determine median because sensor results can be awful

int checkdistance(int trigPin, int echoPin) {
  
  float distance[3];
  
  for(int i=0;i<3;i++){
 
      digitalWrite(trigPin, LOW); 
      delayMicroseconds(2); 
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);   
      digitalWrite(trigPin, LOW);
      long duration = pulseIn(echoPin, HIGH);
      distance[i] = (duration/2) / 29.1;
      
                }
         
   return stats.median(distance,3);

  }
goto EndofDistanceCheck;

OOOOH, goto is a big no-no. You should never ever need it in C code with all the control structures it has. goto belongs in BASIC.

If you want to skip the rest of the checks when you find one that is true then make them all else if.

OK, removed goto and added else. That was easy enough. Thanks. However, it didn’t really get to my question. I want to continuously collect sensor data. Periodically, I want to run the if-else statements.

/*
  Trigger pins have oranges wires
  Echo pins have brown wires
 */

#include "QuickStats.h"
QuickStats stats;

#define AIN1pin 12
#define AIN2pin 11

#define SLPpin 10

#define BIN2pin 9
#define BIN1pin 8

#define trigPinLeft 7
#define trigPinCenter 5
#define trigPinRight 3

#define echoPinLeft 6
#define echoPinCenter 4
#define echoPinRight 2


#define hard 100  //  time alloted for a hard turn
#define slight 100  // time alloted for a slight turn
#define slowspeed 125
#define fastspeed 125
#define cd 30 // cd is critical distance or the distance to decide when to go straight or stop
#define rh 1.05
#define rl 0.95

  int Left, Center, Right, PreviousLeft, PreviousCenter, PreviousRight;

/*
 * Bout is right wheel
 * Aout is left wheel
 * Distance Detector: Brown wire = echo ;   Orange wire = trigger
 * 
 */

void setup() {

  pinMode(trigPinRight,  OUTPUT);
  pinMode(trigPinCenter, OUTPUT);
  pinMode(trigPinLeft,   OUTPUT);
  pinMode(echoPinRight,  INPUT);
  pinMode(echoPinCenter, INPUT);
  pinMode(echoPinLeft,   INPUT);
  pinMode(SLPpin,OUTPUT) ;
  pinMode(AIN1pin,OUTPUT);
  pinMode(AIN2pin,OUTPUT);
  pinMode(BIN1pin,OUTPUT);
  pinMode(BIN2pin,OUTPUT);

  Serial.begin (9600);

}

void loop() {
  

  
  // Determine distances for left, center and right side of vehicle
  
     Left = checkdistance(trigPinLeft, echoPinLeft);
     Center = checkdistance(trigPinCenter, echoPinCenter);
     Right = checkdistance(trigPinRight, echoPinRight);

 // Print distances measured
    
    Serial.print(Left);
    Serial.print(", ");
    Serial.print(Center);
    Serial.print(", ");
    Serial.println(Right);

    // check to see if vehicle is not moving
    
   if ( 
      (Left <= rh *PreviousLeft && Left >= rl *PreviousLeft)  &&
      (Center <= rh *PreviousCenter && Center >= rl *PreviousCenter) &&
      (Right <= rh *PreviousRight && Right >= rl *PreviousRight) )

      {
        stopnow();
        backward( slowspeed, 2000);
        stopnow();
        Serial.println("backwards");
       
      }

   // if getting to close on all sides, then stop
    
   else if (Right < cd && Center < cd && Left < cd) {

       stopnow();
       delay(1000);
       Serial.println("stop"); 
       }

// if clear on all sides by distance cd, then go straight

  else if (Right >= cd && Center >= cd && Left >= cd) {  

       Serial.println("go straight");
       forward(fastspeed);
       }

 // make turns based on relative distances from vehicle to objects

  else if (Left <= Right && Right <= Center) {  
    
       Serial.println("slight right");
       turnright(slowspeed,slight);
       }

   else if (Left <= Center && Center <= Right) {
      
       Serial.println("hard right");
       turnright(slowspeed, hard);
       }

   else if (Center <= Left && Left <= Right) {
    
       Serial.println("hard right");
       turnright(slowspeed, hard);
       }
       
   if (Right <= Left && Left <= Center) {  
    
       Serial.println("slight left");
       turnleft(slowspeed,slight);
       }
        
   else if (Right <= Center && Center <= Left) {  

       Serial.println("hard left");
       turnleft(slowspeed,hard);
       }

   else if (Center <= Right && Right <= Left) {
    
       Serial.println("hard left");
       turnleft(slowspeed,hard);
       }

        Serial.print(Left);
        Serial.print(", ");
        Serial.println(PreviousLeft);
        Serial.print(Center);
        Serial.print(", ");
        Serial.println(PreviousCenter);
        Serial.print(Right);
        Serial.print(", ");
        Serial.println(PreviousRight);

// Record previous distances in order to make a comparison with next set of measurements

     PreviousLeft = Left;
     PreviousCenter = Center;
     PreviousRight = Right;  

}

// Begin subroutines

void turnright(int speed, int time) {  
  digitalWrite(AIN1pin,LOW);
  digitalWrite(AIN2pin,HIGH);
  digitalWrite(BIN1pin,LOW);
  digitalWrite(BIN2pin,LOW);
  go(speed);
  delay(time);
}


void turnleft(int speed, int time) {  
  digitalWrite(AIN1pin,LOW);
  digitalWrite(AIN2pin,LOW);
  digitalWrite(BIN1pin,LOW);
  digitalWrite(BIN2pin,HIGH);
  go(speed);
  delay(time);
}


void forward(int speed) { 
  digitalWrite(AIN1pin,LOW);
  digitalWrite(AIN2pin,HIGH);
  digitalWrite(BIN1pin,LOW);
  digitalWrite(BIN2pin,HIGH);  
  go(speed);
}


void backward(int speed, int time) { 
  digitalWrite(AIN1pin,HIGH);
  digitalWrite(AIN2pin,LOW);
  digitalWrite(BIN1pin,HIGH);
  digitalWrite(BIN2pin,LOW); 
  go(speed);
  delay(time);
}


void stopnow() {  // Stop by setting SLP pin to 0
  digitalWrite(SLPpin, LOW); 
}


void go(int setspeed) {  // Go at set speed by setting SLP pin using analog write
  analogWrite(SLPpin, setspeed);
}

// take three measurements and determine median because sensor results can be awful

int checkdistance(int trigPin, int echoPin) {
  
  float distance[3];
  
  for(int i=0;i<3;i++){
 
      digitalWrite(trigPin, LOW); 
      delayMicroseconds(2); 
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);   
      digitalWrite(trigPin, LOW);
      long duration = pulseIn(echoPin, HIGH);
      distance[i] = (duration/2) / 29.1;
      
                }
         
   return stats.median(distance,3);

  }

arduino-jto:
Periodically, I want to run the if-else statements.

OK, so you only want to run the part with the if statements every so often? Get thee to the Blink Without Delay example and any of the many many fine tutorials about it. My favorite is https://www.gammon.com.au/blink or this thread from the forum Demonstration code for several things at the same time - Project Guidance - Arduino Forum

Cross post in Programming Questions http://forum.arduino.cc/index.php?topic=462999.msg3177886#msg3177886

Reported to mods

OP, make one thread and stick to it. Please don't waste our time trying to answer on one thread what might already be said on the other.

@arduino-jto, do not cross-post. Threads merged.

Had I received an answer to my original post or found a method to move it to a different forum, I wouldn't have made the second post. Since no one answered and very few people looked at my first post, it seemed to make sense to move it to a different forum.

If there was a better approach, given the lack of follow-on posts, I'd appreciate learning about it.

Thanks.

There are a lot of people answering threads in all parts of the forum, so it's not that it wasn't seen. Normally when you're not getting any responses the trick is to look at your question. In your case the question lacks detail and it's pretty vague. So I'm sure lots of folks looked and said, I don't want to write a whole treatise on how to make something happen at regular intervals, especially when there are probably more tutorials on that one topic than any other.

In the future when you find that you're not getting responses, come back and fill in some detail and maybe even include an attempt at the code. You'll find that most folks around here just can't stop themselves from commenting on crappy code, so write something even if it is crappy and doesn't work and you'll start getting hits.

arduino-jto:
I want to continuously collect sensor data. Periodically, I want to run the if-else statements.

What shall happen to the excess data, collected between execution of the if-else statements?

arduino-jto:
If there was a better approach ... I'd appreciate learning about it.

Click Report to moderator. Ask for the thread to be moved. Not rocket science.