I have a robot that uses two motors to skid steer. The robot gets input from three ultrasonic sensors (left, middle, and right) and a passive infrared sensor. If the robot detects a person in front of it, then it follows.
The sensors seem to work as they are intended. The infrared sensor sees a person and the ultrasonic sensors see that the person is between 65cm and 150cm and it follows. If the left ultrasonic sensor has the person in range, it turns left, and if the right ultrasonic sensor has the person in range, it turns right.
The problem is that the robot gets stuck turning left or turning right depending on which sensor it checks first in the code. It's like it's stuck in a while loop even though I'm not using a while loop.
I have adapted NewPing and library. The code in question is at the bottom in the last function. The rest is part of NewPing to read the ultrasonic sensors.
If anybody has any suggestions, it would be greatly appreciated.
#include <NewPing.h>
#define SONAR_NUM 3 // Number of sensors.
#define MAX_DISTANCE 170 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 35 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).
unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM]; // Where the ping distances are stored.
uint8_t currentSensor = 0; // Keeps track of which sensor is active.
NewPing sonar[SONAR_NUM] = { // Sensor object array.
NewPing(11, 4, MAX_DISTANCE), //Left -- Each sensor's trigger pin, echo pin, and max distance to ping.
NewPing(8, 3, MAX_DISTANCE), //Center
NewPing(7, 9, MAX_DISTANCE), //Right
};
int ledR = 13;
int ledG = 2;
int ledB = A0;
int motorPinL = 5;
int motorPinR = 6;
int ePIR = 10;
boolean epirVal;
void setup() {
Serial.begin(115200);
pingTimer[0] = millis() + 75; // First ping starts at 75ms, gives time for the Arduino to chill before starting.
for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
pinMode (ledR, OUTPUT);
pinMode (ledG, OUTPUT);
pinMode (ledB, OUTPUT);
pinMode (motorPinL, OUTPUT);
pinMode (motorPinR, OUTPUT);
pinMode (ePIR, INPUT);
}
void loop() {
for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
if (millis() >= pingTimer[i]) { // Is it this sensor's time to ping?
pingTimer[i] += PING_INTERVAL * SONAR_NUM; // Set next time this sensor will be pinged.
if (i == 0 && currentSensor == SONAR_NUM - 1)
oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
sonar[currentSensor].timer_stop(); // Make sure previous timer is canceled before starting a new ping (insurance).
currentSensor = i; // Sensor being accessed.
cm[currentSensor] = 155; // Make distance 155 in case there's no ping echo for this sensor. changed from zero
sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
}
}
// Other code that *DOESN'T* analyze ping results can go here.
}
void echoCheck() { // If ping received, set the sensor distance to array.
if (sonar[currentSensor].check_timer())
cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
}
void allStop () {
analogWrite (motorPinL, 0);
analogWrite (motorPinR, 0);
digitalWrite (ledG, LOW); //LED corresponding to right ultrasonic sensor
digitalWrite (ledR, LOW); //LED corresponding to left ultrasonic sensor
digitalWrite (ledB, LOW); //LED corresponding to center ultrasonic sensor
}