June, 7th 2012
----------------------
- Updated schema.
- Segregated power supplies of arduino + sensor
- Added 0.047uf caps to the motor leads (one per lead) grounded by the casing.
- Motor + servo power supply changed to 4 AA rechargable batteries.
- Arduino + sensor when powered by USB everything seems to work fine, except the sensor is a bit slow to respond but that surely it's the code's fault.
- Pending issues:
Tried to power the arduino + sensor with a 9V 300mAh rechargable battery, but made sensor take even longer to reply to obstable, and once it did the system tipically went haywire (invisble obstacles + short burst wheel motions).
Solution: Find a better alternative portable powering alternative for the arduino + sensor.
June 6th, 2012
Ok, I think it's been widely established that the main culprits are my motors and their suckiness and so they produce too much electric noise that even the typical 0.1uf caps in the motor leads (not depicted, must update picture) won't (are not) help(ing) much/enough.
June, 5th, 2012 -- UPDATED PICTURE
Ok, the HC-SR04 part of my attempt of a first robot is still giving me grief ...
Whereas:
Power supply:
- USB + Batteries 6 or 8 AA ~6-9V downregulated to 5V and an unregulated line out
- the resistors are 8.8k
- and the "strange" labeled hc-sr5 is what the HR-SR04 should be (but Fritzing was lacking a pretty picture of it) is the TROUBLESOME module... :,(
So in the presented setup (I've tried several variations whereas this was the one presenting the "best results") the robot on perch (thus unable to go anywhere) presents me distance measurings as such:
Distance in centimers: 294
Distance in centimers: 47
Distance in centimers: 102
Distance in centimers: 183
Distance in centimers: 182
Distance in centimers: 136
Distance in centimers: 97
Distance in centimers: 0
Left: 500
Right: 179
Distance in centimers: -69
Left: 500
Right: 177
Distance in centimers: 0
Left: 500
Right: 178
Distance in centimers: -67
Left: 500
Right: 178
Distance in centimers: -66
Left: 500
Right: 178
Distance in centimers: -66
Left: 500
Right: 178
Distance in centimers: -65
Left: 500
Right: 0
Distance in centimers: 0
Left: 0
Right: 0
Distance in centimers: 0
Left: 3
Right: 178
Distance in centimers: 176
Distance in centimers: 44
Distance in centimers: 57
Distance in centimers: 102
Distance in centimers: 96
Distance in centimers: 27
Distance in centimers: 145
Distance in centimers: 0
Left: 500
Right: 178
Distance in centimers: 265
Distance in centimers: -285
So basically, just the fact that the motors are running the sensor (pointed forward) shows me wild variation of distance:
Distance in centimers: 47
Distance in centimers: 102
Distance in centimers: 183
Distance in centimers: 182
Distance in centimers: 136
Distance in centimers: 97
then once it "seemingly" randomly stumbles upon a value less than 6 (my conditional), the servo activates:
Distance in centimers: 0
Left: 500
Right: 179
Distance in centimers: -69
....
when it's scanning the motors are off, and the returned values seem accurate enough... but then... servo goes back to center... and it's silly value time again... at that point the loop is restarting again... but if check the forward distance still within the sweeping function I get an ok value....
So the only things I heavily suspect is:
- (wheel) motors working => interference with sonic ranging
- the start of my loop() section should be "smoother" somehow?
My testing code below for appreciation:
#include <DistanceSRF04.h>
#include <Servo.h>
DistanceSRF04 dist; // Define the "batvision" object
Servo neckServo; // Define the Servo object
const int stopDist = 6; // STOPPING distance (TWEEK THIS)
int distance; // current distance to obstacle
int distArray[2]; // array of distances measured during a sonar sweep
int enableRight = 5; // Enable/disable RIGHT motor
int enableLeft = 10; // Enable/disable LEFT motor
int directionRight = 6; // Direction of RIGHT motor
int directionLeft = 11; // Direction of LEFT motor
void setup()
{
// initialize serial communication:
Serial.begin(9600);
dist.begin(2,3); // pins for batvision's Echo AND Trigger (respectively)
neckServo.attach(9); // attach the servo on pin 9 to the servo object
pinMode(enableRight, OUTPUT);
pinMode(enableLeft, OUTPUT);
pinMode(directionRight, OUTPUT);
pinMode(directionLeft, OUTPUT);
}
void loop()
{
delay(500);
howFar();
Serial.print("\nDistance in centimers: ");
Serial.print(distance);
delay(500); //make it readable
if(distance > stopDist){
forward();
}
else{
stopBot();
lookAround();
if(distArray[0] <= distArray[1] && distArray[1] > stopDist){
forwardRight();
delay(500);
}
else if(distArray[0] > distArray[1] && distArray[0] > stopDist){ //hmm - 2
forwardLeft();
delay(500);
}
else if(distArray[0] <= distArray[1] && distArray[1] <= stopDist){ // hmmmm
reverseLeft();
delay(500);
}
else if(distArray[0] > distArray[1] && distArray[1] <= stopDist){
reverseRight();
delay(500);
}
}
} // close loop()
void howFar()
{
delay(25);
distance = dist.getDistanceCentimeter();
delay(25);
}
void lookAround()
{
int pos;
for(pos = 30; pos <= 150; pos += 1) // goes from 30 degrees to 150 degrees in steps of 1 degree
{
neckServo.write(pos); // tell servo to go to position in variable 'pos'
delay(15);
if(pos == 45){
delay(1000);
distArray[0] = dist.getDistanceCentimeter();
if(distArray[0] < 0){distArray[0] = 500;}
}
if(pos == 135){
delay(1000);
distArray[1] = dist.getDistanceCentimeter();
if(distArray[1] < 0){distArray[1] = 500;}
}
}
neckServo.write(90); // returns to looking forward
// testing -- distance read here seems accurate enough
delay(250);
howFar();
delay(50);
Serial.print("\nLeft: ");
Serial.print(distArray[0]);
Serial.print("\nRight: ");
Serial.print(distArray[1]);
delay(500); //make it readable
}
// Robot directional controls
void forward()
{
digitalWrite(enableRight, HIGH);
digitalWrite(enableLeft, HIGH);
digitalWrite(directionRight, HIGH); // HIGH (currently) means FORWARD
digitalWrite(directionLeft, HIGH);
}
void forwardRight() // ANTI-CLOCKWISE MOVE
{
digitalWrite(enableRight, LOW);
digitalWrite(enableLeft, HIGH);
digitalWrite(directionLeft, HIGH);
}
void forwardLeft() // CLOCKWISE MOVE
{
digitalWrite(enableRight, HIGH);
digitalWrite(directionRight, HIGH);
digitalWrite(enableLeft, LOW);
}
void reverse()
{
digitalWrite(enableRight, HIGH);
digitalWrite(enableLeft, HIGH);
digitalWrite(directionRight, LOW);
digitalWrite(directionLeft, LOW);
}
void reverseRight()
{
digitalWrite(enableRight, LOW);
digitalWrite(enableLeft, HIGH);
digitalWrite(directionLeft, LOW);
}
void reverseLeft()
{
digitalWrite(enableRight, HIGH);
digitalWrite(directionRight, LOW);
digitalWrite(enableLeft, LOW);
}
void stopBot()
{
digitalWrite(enableRight, LOW);
digitalWrite(enableLeft, LOW);
}