Stingray Multiple PIng object avoidance questions
suspect_device
Posts: 4
I recently bought a Sting Ray chassis from Parallax and am using an UNO R3, BOE Shield, and motor shield to control it. It's my first experience outside of a BOE BOT, and I'm trying to learn as I go. I'm trying to make it autonomous for now, it has three PING sensors across the front, and I'm having some trouble getting them to work with each other. In this particular code, the Ping sensors will work, and I can read it through the serial monitor without the "forward", "goRight", "goleft" function calls in it. So, it will sit still and read distance from all three sensors, but if you add motor direction controls, the serial monitor stops working and the sensors don't seem to all work. Am I out of memory? Or is my code terrible? I have tried other code including the "newPing" library and totally different code, but similar results.
#include <Ping.h> // initialize const int pingPin1 = 5 ; // pin used for the Ping Sensor const int pingPin2 = 6; //Right Ping sensor const int pingPin3 = 7; //Left Ping sensor int BaudRate = 9600 ; // Baud rate // set up void setup() { Serial.begin(BaudRate) ; // Setup Serial //Setup Channel A pinMode(12, OUTPUT); //Initiates Motor Channel A pin pinMode(9, OUTPUT); //Initiates Brake Channel A pin //Setup Channel B pinMode(13, OUTPUT); //Initiates Motor Channel B pin pinMode(8, OUTPUT); //Initiates Brake Channel B pin digitalWrite(9, HIGH); //Engage the Brake for Channel A digitalWrite(8, HIGH); //Engage the Brake for Channel B delay(2000); } void loop() { unsigned long duration1; int inches1, inches2, inches3; // Read distance 1 pinMode(pingPin1, OUTPUT); digitalWrite(pingPin1, LOW); delayMicroseconds(2); digitalWrite(pingPin1, HIGH); delayMicroseconds(5); digitalWrite(pingPin1, LOW); pinMode(pingPin1, INPUT); duration1 = pulseIn(pingPin1, HIGH); inches1 = microsecondsToInches(duration1); unsigned long duration2; // Read distance 2 pinMode(pingPin2, OUTPUT); digitalWrite(pingPin2, LOW); delayMicroseconds(2); digitalWrite(pingPin2, HIGH); delayMicroseconds(5); digitalWrite(pingPin2, LOW); pinMode(pingPin2, INPUT); duration2 = pulseIn(pingPin2, HIGH); inches2 = microsecondsToInches(duration2); unsigned long duration3; // Read distance 3 pinMode(pingPin3, OUTPUT); digitalWrite(pingPin3, LOW); delayMicroseconds(2); digitalWrite(pingPin3, HIGH); delayMicroseconds(5); digitalWrite(pingPin3, LOW); pinMode(pingPin3, INPUT); duration3 = pulseIn(pingPin3, HIGH); inches3 = microsecondsToInches(duration3); if (inches2 > 20) { forward(); } else if (inches1 <= 20) { goLeft(); } else if (inches3 <= 20) { goRight(); { Serial.print ("Distance : ") ; Serial.print(inches1); Serial.print("in, "); Serial.print(inches2); Serial.print("in, "); Serial.print(inches3); Serial.print("in, "); Serial.println(); } delay (10); } } void forward() { //Motor A forward @ full speed digitalWrite(12, HIGH); //Establishes forward direction of Channel A digitalWrite(9, LOW); //Disengage the Brake for Channel A analogWrite(3, 250); //Spins the motor on Channel A at full speed //Motor B backward @ half speed digitalWrite(13, LOW); //Establishes backward direction of Channel B digitalWrite(8, LOW); //Disengage the Brake for Channel B analogWrite(11, 250); //Spins the motor on Channel B at full speed } void reverse(){ digitalWrite(9, HIGH); //engage the Brake for Channel A digitalWrite(8, HIGH); //engage the Brake for Channel B delay(500); //Motor A reverse @ full speed digitalWrite(12, LOW); //Establishes forward direction of Channel A digitalWrite(9, LOW); //Disengage the Brake for Channel A analogWrite(3, 250); //Spins the motor on Channel A at full speed //Motor B backward @ half speed digitalWrite(13, HIGH); //Establishes backward direction of Channel B digitalWrite(8, LOW); //Disengage the Brake for Channel B analogWrite(11, 250); //Spins the motor on Channel B at full speed } void goRight(){ digitalWrite(9, HIGH); //Engage the Brake for Channel A digitalWrite(8, HIGH); //Engage the Brake for Channel B delay(20); //Motor A forward @ full speed digitalWrite(12, HIGH); //Establishes forward direction of Channel A digitalWrite(9, LOW); //Disengage the Brake for Channel A analogWrite(3, 200); //Spins the motor on Channel A at full speed //Motor B backward @ half speed digitalWrite(13, HIGH); //Establishes backward direction of Channel B digitalWrite(8, LOW); //Disengage the Brake for Channel B analogWrite(11, 200); //Spins the motor on Channel B at full speed delay(200); } void goLeft(){ digitalWrite(9, HIGH); //Engage the Brake for Channel A digitalWrite(8, HIGH); //Engage the Brake for Channel B delay(20); //Motor A forward @ full speed digitalWrite(12, LOW); //Establishes forward direction of Channel A digitalWrite(9, LOW); //Disengage the Brake for Channel A analogWrite(3, 200); //Spins the motor on Channel A at full speed //Motor B backward @ half speed digitalWrite(13, LOW); //Establishes backward direction of Channel B digitalWrite(8, LOW); //Disengage the Brake for Channel B analogWrite(11, 200); //Spins the motor on Channel B at full speed delay(200); } long microsecondsToInches(long microseconds) { return microseconds / 74 / 2; }
Comments
Anyway, I don't know about the ping.h or newPing library, as I'm not keenly familiar with either. However, in looking at newPing I see it relies on Timer2 in the Arduino's AVR, which will kill some of the PWM functionality on related lines. You always have to look to see what AVR hardware is affected by whatever libraries you use. Find other pins when there's a conflict.
You will benefit by starting with a simpler set of code, and building up. You don't mention you've tried with just one Ping, but that's where I'd start. You include the ping.h library but never appear to call it. Remove all extraneous code just to make sure there are no conflicts.
You want to look at how you're calling the Serial.print functions in the loop. Seems to me there's a logic error, as you've written it the serial monitor won't get data to unless the condition else if "(inches3 <= 20)" is met. Take it out of the if tests if you want that code to be run each time through the loop.
Though not the source of your problem, you might take note that you're not first braking the motors when you call forward().
Look to ways to simplify your coding with functions, so you can spot things like this. It'll make the code more streamlined and helps you spot errors. Your brake code is a good place to start. You can also put your hard-coded ping code in a single function, and pass in the pin number as an argument, as in:
long readPing (int pinNum) {
// etc
}
-- Gordon
else if (inches3 <= 20)
{
goRight();
{
Serial.print ("Distance : ") ;
Serial.print(inches1);
Serial.print("in, ");
TO
else if (inches3 <= 20)
{
goRight();
}
Serial.print ("Distance : ") ;
Serial.print(inches1);
Serial.print("in, ");
you will logically close off your if else statement as Mike suggested and move the serial print out of the condition that it's now in where that it is only called when inches3 <= 20 as Gordon alluded to.
Welcome to the forum and welcome to the Stingray club, keep us updated on your progress.
jim