So recently I started making a sonar out of ultrasonic HC-SR04 sensor and servo motor. The idea was to slowly rotate servo 180 degrees while measuring distance.
Soon after I noticed that regular pulseIn() command could wait 20ms while doing nothing. So I started learning interrupts. I came up with a code which sends TRIG signal and records sending time with micros() function. When an interrupt occurs on ECHO pin, we subtract current time with TRIG time and get time of round trip of the sound.
The code works as intended without servos connected, but it behaves interestingly ! I always get distance which is 8 cm bigger than actual distance. So I had to subtract 8 cm every time ! Also I noticed that max reliable range decreased , using pulseIn() I could measure distance of 400cm, and with mine code it starts to show weird numbers after 150cm...
So i thought that 150cm is enough for me, and tried to run the code with servos attached. everything ran as intended, until the servos started to move. Now I was getting distance along with pretty much random numbers, periodically positive and negative.
I could just use one the fancy libraries out there, but I am curious what am I doing wrong, why i need to subtract 8cm each time , why my reliable range decreased so much, and most importantly why am I getting weird values while servos are on ?
CODE :
#include <Servo.h>
#define ECHO 2
#define TRIG 7
Servo servo;
int distance;
volatile long echoTime = 0;
long trigTime = 0,sendTime = 0,timeServo = 0;
bool scanning = false;
byte servoDir = -1,servoAngle = 0;
void setup()
{
servo.attach(12);
Serial.begin(115200);
pinMode(ECHO,INPUT);
pinMode(TRIG,OUTPUT);
attachInterrupt(digitalPinToInterrupt(ECHO), echo_interupt, FALLING);
}
void loop()
{
// SERVO
if((millis() - timeServo > 10)){
if(servoAngle <= 0 || servoAngle >= 180)servoDir = -servoDir;
servoAngle += servoDir;
servo.write(servoAngle);
timeServo = millis();
}
// GETTING RESULTS
if(echoTime > 0){
distance = echoTime - trigTime;
distance /= 58;
echoTime = 0;
trigTime = 0;
Serial.println(distance - 8);
}
// SENDING PULSE
if(millis() - sendTime > 20){
digitalWrite(TRIG,LOW);
delayMicroseconds(2);
digitalWrite(TRIG,HIGH);
delayMicroseconds(10);
digitalWrite(TRIG,LOW);
trigTime = micros();
sendTime = millis();
}
}
// INTERUPT
void echo_interupt(){
echoTime = micros();
}