2

I am using the HC-SR04 ultra sound sensor for Arduino. I have used the following code to calculate distance and it works perfectly.

  long duration;
  digitalWrite(trigger, LOW);  
  delayMicroseconds(2);
  digitalWrite(trigger, HIGH);
  delayMicroseconds(10); 
  digitalWrite(trigger, LOW);
  duration = pulseIn(echo, HIGH);
  distance = (duration/2) / 29.1;

However I want to use three more of these sensors, for a total of four. This block of code will be called every time I want to find the distance of one of the sensors. I am worried however that delayMicroseconds() pauses the entire program and that I cannot perform other tasks in while the sensors are working (e.g. driving wheels, it's a robot). The following code is object oriented for each sensor.

class distSensor{
   int trigPin;
   int echoPin;
   int distance;

   //Will be used in timer
   unsigned long previousMillis;

   public:
   distSensor(int tPin,int ePin){
   trigPin = tPin;
   echoPin = ePin;

   pinMode(trigPin, OUTPUT);
   pinMode(echoPin, INPUT);

   previousMillis = 0;
 }

 int calculateDistance(){

  //records time since program start
  unsigned long currentMillis = millis();

  long duration;
  digitalWrite(trigPin, LOW); 

  //check if the previous time the method was called is greater than the interval of 2
  if(currentMillis - previousMillis > 2){
    digitalWrite(trigPin, HIGH);
    previousMillis = currentMillis;
  }

  //check if distance between current time and previous time it was called is greater than interval of 10.
  if(currentMillis - previousMillis > 10){
      digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2) / 29.1;
  }
  return distance;
 }
};

In the calculateDistance() method I am trying to do the same thing as the first code but without delay() and instead a timer. But when I run the program it does not work and distance is read as 0. Can anyone help me rewrite the HC-SR04 code from the start that doesn't delay the whole program?

Greenonline
  • 3,152
  • 7
  • 36
  • 48
Don Grey
  • 71
  • 1
  • 4

3 Answers3

2

delay() causes the processor to do nothing but wait. You need to switch to millis().

In your code, you need to "grab" the current time using millis() and store it in a variable. Add the number of milliseconds that you want to wait to this variable - you will have to consider the case where this value will overflow for a complete solution. Then, in your code, you need to create an infinite loop where you check what millis() returns. When your stored value and millis() match, it is time to execute the code that would normally come after the delay() call.

Here, Arduino Playground - How and Why to avoid delay(), delay() and millis() are discussed in detail.

So that this answer will cover your question, consider placing all your events which need to be timed into this one infinite loop. Also, consider keeping independent variables, one for each timed event, such that different events are timed independently.

Greenonline
  • 3,152
  • 7
  • 36
  • 48
st2000
  • 7,513
  • 2
  • 13
  • 19
1
enter code here
#define ECHO 5        // Pin received echo pulse
#define TRIGGER 6     // Pin sends shot pulse

int distance; // the distance in cms         
unsigned long previousMicros = 0; // will sotre last time TRIGGER was updated    
long OnTime = 10; //microseconds of on-time     
long OffTime = 2; //microseconds of off-time    
unsigned long previousMillis = 0; //will store last time viewTime was updated   
int triggerState = LOW; // triggerState used to set it up   
long duration;   
void setup()    
{   
  Serial.begin(9600);   
  pinMode(ECHO, INPUT);   
  pinMode(TRIGGER, OUTPUT);     
}    

void loop()   
{   
  // check to see if it's time to change the state of the TRIGGER    
  unsigned long currentMicros = micros();     
  if((triggerState == LOW) && (currentMicros - previousMicros >= OffTime))     
   {      
     triggerState = HIGH; // turn it on      
     previousMicros = currentMicros; // remember the time     
     digitalWrite(TRIGGER, triggerState); // update the actual trigger     
   }    
   else if((triggerState == HIGH) && (currentMicros - previousMicros >= OnTime))    
   {           
     triggerState = LOW; // turn it off          
     previousMicros = currentMicros; // remember the time           
     digitalWrite(TRIGGER, triggerState); // update the actual trigger      
   }    



duration = pulseIn(ECHO,HIGH  );      
Serial.println(distance);        
distance = ((duration*0.034)/2);       
Serial.print("distance: ");        

}

this will run your code without delay but the problem is you will get a zero every time resulting from pulseIn() which from there on I dont know how to fix it yet

sempaiscuba
  • 1,042
  • 9
  • 21
  • 32
Koops
  • 111
  • 4
0
unsigned long currentMillis = micros();
digitalWrite(Trig, LOW);

if (currentMillis - previousMillis > 4) {
  digitalWrite(Trig, HIGH);
  previousMillis = currentMillis;
}

if (currentMillis - previousMillis > 12) {
  digitalWrite(Trig, LOW);
  previousMillis = currentMillis;
}

impulseTime = pulseIn(Echo, HIGH);
distance_sm = impulseTime / 58; // convert to centimeters
distance = distance_sm;
VE7JRO
  • 2,515
  • 19
  • 27
  • 29