0
Offline
Newbie
Karma: 0
Posts: 22
Arduino rocks
|
 |
« on: October 21, 2008, 10:08:46 am » |
Hi all, I've wired up an SRF05 ultrasonic range finder to my Arduino, and used the sketch from here: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1179936636My results vary from around 220,000 downwards. Is this to be expected? The SRF05 tech page at robot electronics states that if you divide by 58, you get a result in cm. Evidently this is not the case. Any ideas why? Is it usual to get such high readings from the sensor? It seems that the readings are accurate (around 20cm away, I get 200000, 10cm away I get approx 100000), and I've tried with two sensors so I don't think it's a hardware problem. It's just that the results don't match with what others seem to be getting. Possibly something to do with the serial communication and the omission of a decimal point somewhere? Any ideas?
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 11
Arduino rocks
|
 |
« Reply #1 on: November 18, 2008, 08:36:28 am » |
The SRF05 works in two modes:
1) The "SRF04 Compatibility mode" 2) and the SRF05 which is the default.
There's not much difference operationally between these two modes, but they require different connections.
Check the Devantech site to find out how you can connect it.
I have an SRF05 on my Arduino Diecimila and works great.
teoxan
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 22
Arduino rocks
|
 |
« Reply #2 on: November 18, 2008, 06:21:09 pm » |
Hi teoxan, thanks for the reply.
I'm aware there are two operating modes for the SRF05. I'm using the single pin mode. However, dividing by 58 does not give results in cm.
Anything below 10cm, I get a 6 digit number. So for 5cm, I get a result of 500000. Above that (i.e. above 10cm), I get a 7 digit number. E.g., 20cm gives 2000000. Up until 100cm, if I removed the last 5 digits, I would get an approximate answer in cm. Above 100cm I still get a 7 digit number, and removing the last 4 digits would give me an approximate result in cm. It seems the result is truncated after 7 digits...
I'm not sure if the result is getting truncated or what (it's an unsigned long... so it shouldn't, I don't think). But I can't just cut off a constant number of digits, as >10cm and >100cm both give a 7 digit number.
Any ideas why this is? At the moment I'm using an unsigned long for the pulse duration, and for the distance. When displaying this result to the LCD, I'm using ltoa(), which presumably could be the cause of errors except for the fact that even outputting the raw values to serial gives the same results...
I'm a bit stumped here. I'm sure it's something obvious that I'm missing. But there is no way that dividing by 58 gives a cm result.
Suggestions?
Regards,
Thom
|
|
|
|
« Last Edit: November 18, 2008, 06:22:12 pm by wiji »
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 11
Arduino rocks
|
 |
« Reply #3 on: November 19, 2008, 06:12:43 am » |
Check this site to get an idea of the code being used: http://letsmakerobots.com/node/1669Also, another good site for Arduino and sensor examples: http://www.freeduino.orgThere's an example for SRF05 there. teoxan
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 22
Arduino rocks
|
 |
« Reply #4 on: November 19, 2008, 08:31:35 am » |
Yeah I've read both of those - my code does appear to be correct, and I'm getting consistent results; just not what I expected.
I've done as much research as I can into this before posting here.
Could you send me the code you use and some examples of results please? I think that might be helpful. I've tried both modes and get the same results. I've also tried it on two different Arduinos, with two different SRF05 sensors, so I really don't know what's going on!
Cheers,
Thom
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 11
Arduino rocks
|
 |
« Reply #5 on: November 19, 2008, 05:49:36 pm » |
Here's the code I use: //Code for using SRF05 with Arduino and Wiring //SRF05 works in default mode-using same pin for pulse // and echo // The Mode pin of SRF05 is connected to Ground
int SRF05pin = 8; //connect to digital pin 8 unsigned long ultrasoundDuration;
void setup() { Serial.begin(9600); }
void loop() { pinMode(SRF05pin, OUTPUT); //pin is output digitalWrite(SRF05pin, LOW); delayMicroseconds(2); digitalWrite(SRF05pin, HIGH); delayMicroseconds(10); digitalWrite(SRF05pin, LOW); pinMode(SRF05pin, INPUT); // pin is now input // wait for a high pulse ultrasoundDuration = pulseIn(SRF05pin, HIGH); // get results Serial.print(ultrasoundDuration); Serial.print(ultrasoundDuration/148, DEC); //divide with 58 and you get cm Serial.print(" inches"); Serial.println(); delay(100); }
I hope this works for you. teoxan
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 22
Arduino rocks
|
 |
« Reply #6 on: November 19, 2008, 09:57:55 pm » |
Hmmm yeah that's pretty much the code I've been using. If I try it with (ultrasoundDuration/58) I get this sort of result: 2032433 cm 2031355 cm 2030278 cm 2028122 cm 1988252 cm 2024890 cm 2031355 cm 2032433 cm 2022735 cm 812500 cm 813577 cm 2031355 cm 2031355 cm 2019502 cm 2020579 cm 2029200 cm 2030278 cm 845905 cm
Strange... I'm not sure what else to try here!
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 22
Arduino rocks
|
 |
« Reply #7 on: November 19, 2008, 10:00:27 pm » |
Here's the full code just in case there's something I'm missing...
int ultraSoundpin = 6; unsigned long ultrasoundDuration = 0;
void setup() { Serial.begin(9600); }
void loop() {
// switch pin to output pinMode(ultraSoundpin, OUTPUT);
// send a low, wait 2 microseconds, send a high then wait 10 microseconds digitalWrite(ultraSoundpin, LOW); delayMicroseconds(2); digitalWrite(ultraSoundpin, HIGH); delayMicroseconds(10); digitalWrite(ultraSoundpin, LOW);
// switch pin to input pinMode(ultraSoundpin, INPUT);
// wait for a pulse to come in as high ultrasoundDuration = pulseIn(ultraSoundpin, HIGH);
// output Serial.print(ultrasoundDuration/58, DEC); Serial.print(" cm"); Serial.println(); delay(2000); }
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 11
Arduino rocks
|
 |
« Reply #8 on: November 20, 2008, 11:34:54 am » |
I think I found what maybe your problem.
Change the unsigned long to int. Create another variable, for example "ultrasound2" and put there the result from the division "ultrasoundDuration/2".
Divide it by 58 or 148 and you get correct results.
I don't know how to explain this yet, but another friend of mine had the same problem with you with his Arduino. So, i tried the way I tell you and it worked...
teoxan
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 22
Arduino rocks
|
 |
« Reply #9 on: November 24, 2008, 11:33:27 am » |
Gah tried that, and I get even more erratic results! Hehe, I'm not sure what's going on here at all. I'll check this method on my other Arduino and the other SRF05 unit later on, for now here's the (new) complete code, after halving the ultrasound duration before dividing by 58. int ultraSoundpin = 6; char disp_string[80]; unsigned int ultrasoundDuration = 0; unsigned int ultra_dist = 0;
void setup() { Serial.begin(9600); }
void loop() {
// switch pin to output pinMode(ultraSoundpin, OUTPUT);
// send a low, wait 2 microseconds, send a high then wait 10 microseconds digitalWrite(ultraSoundpin, LOW); delayMicroseconds(2); digitalWrite(ultraSoundpin, HIGH); delayMicroseconds(10); digitalWrite(ultraSoundpin, LOW);
// switch pin to input pinMode(ultraSoundpin, INPUT);
// wait for a pulse to come in as high ultrasoundDuration = pulseIn(ultraSoundpin, HIGH); ultra_dist = (ultrasoundDuration/2); // output Serial.print(ultra_dist/58, DEC); Serial.print(" cm"); //Serial.print(dist); //Serial.print(" cm"); Serial.println(); delay(2000); }
I've tried this with unsigned ints and longs, and with a long for the duration and an int for the distance... just gives me random results from 7-500 odd....! Thom
|
|
|
|
|
Logged
|
|
|
|
|
Copenhagen / Denmark
Offline
Edison Member
Karma: 5
Posts: 2338
Do it !
|
 |
« Reply #10 on: November 25, 2008, 03:06:12 am » |
A long shot.
Maybe it's because yourdelay is too short ?
Quote from the delayMicroseconds() description in the reference:
This function works very accurately in the range 3 microseconds and up. We cannot assure that delayMicroseconds will perform precisely for smaller delay-times.
To ensure more accurate delays, this functions disables interrupts during its operation, meaning that some things (like receiving serial data, or incrementing the value returned by millis()) will not happen during the delay. Thus, you should only use this function for short delays, and use delay() for longer ones.
|
|
|
|
« Last Edit: November 25, 2008, 03:07:20 am by MikMo »
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 22
Arduino rocks
|
 |
« Reply #11 on: November 25, 2008, 07:52:28 am » |
Thanks for that - I tried changing the value for the delay, but sadly it didn't help. This seems to be an unusual problem - I've tried this new code with two Arduinos and two SRF05 units, and the same results are obtained.
I'm sure I've read pretty much everything I can find about this range finder on the net, and there don't seem to be any other suggestions to try.
Could it be something to do with my arduino software set up? I have only tried compiling and running this on my laptop, with arduino0011 and arduino0012 IDE, running on Ubuntu.
Cheers for the help so far guys, but are there any more (however long) shots?
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 22
Arduino rocks
|
 |
« Reply #12 on: November 25, 2008, 08:35:10 am » |
I'm pretty sure the timing readings from the SRF05 are accurate - they're consistent when an object is placed at a fixed distance away.
The problem is the conversion. If I do (pulsetime/10000)/58 I get correct results for dist > 100cm but inaccurate below.
So, for (actual dist) = 200cm, the result will be 200cm, but the result for (actual dist) = 20cm will also be 200cm. Could it be something to do with the pulseIn method returning a value in mS rather than uS? I could hack something together that divides by 10000 for some range of pulse times, and by 100000 some other ranges, to make the numbers fit. But this seems like I'm just putting a plaster on things; curing rather than preventing.
Am I missing something obvious here? It feels like it...
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 11
Arduino rocks
|
 |
« Reply #13 on: November 25, 2008, 05:53:19 pm » |
I have the SRF05 right next to me , running the code I posted here, and it works fine..
The example with the distances you gave, means that the SRF05 doesn't actually work.
Now, I can only assume three obvious things:
1) The SRF05 is damaged 2) Your cables and your connections are bad 3) Software problem
Solutions I may think of, providing the SRF05 is not damaged:
1) Check your cables; also check the connections again.Use only one Mode ( either SRF04 Compatibility or SFR05) and make sure you have all connected properly
Can you tell us what mode you use and the pin connections of your SRF05 and Arduino?
2) I don't think you have a software problem, but to elliminate that possibilty, you can try all this on a Windows running computer.
teoxan
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 22
Arduino rocks
|
 |
« Reply #14 on: November 26, 2008, 06:11:32 am » |
Dang... Well, assuming the software is OK it's most likely a cable/USB problem then, as it seems unlikely that I would have bought two faulty Arduinos and/or two faulty SRF05 units, doesn't it? I think I have only one USB cable of this type, I'll see if I can find another and try the combinations of board/sensor/cable on my desktop Linux machine, and my XP machine, and see what happens. I found some code on a university site somewhere that seems to work... but I'm not sure why. /* Ultrasound Sensor SRF05 v1 *--------------------------- * * Reads values (00014-01199) from an ultrasound sensor (3m sensor) * and writes the values to the serialport. * * http://www.xlab.se | http://www.0j0.org * copyleft 2005 Mackie for XLAB | DojoDave for DojoCorp * */
int ultraSoundSignalOut = 7; // Ultrasound signal pin int ultraSoundSignalIn = 8; // Ultrasound signal pin int val = 0; int ultrasoundValue = 0; int timecount = 0; // Echo counter int ledPin = 13; // LED connected to digital pin 13
void setup() { beginSerial(9600); // Sets the baud rate to 9600 pinMode(ledPin, OUTPUT); // Sets the digital pin as output pinMode(ultraSoundSignalOut, OUTPUT); // Sets the digital pin as output pinMode(ultraSoundSignalIn, INPUT); // Sets the digital pin as output }
void loop() { timecount = 0; val = 0;
/* Send low-high-low pulse to activate the trigger pulse of the sensor * ------------------------------------------------------------------- */
digitalWrite(ultraSoundSignalOut, LOW); // Send low pulse delayMicroseconds(2); // Wait for 2 microseconds digitalWrite(ultraSoundSignalOut, HIGH); // Send high pulse delayMicroseconds(5); // Wait for 5 microseconds digitalWrite(ultraSoundSignalOut, LOW); // Holdoff
/* Listening for echo pulse * ------------------------------------------------------------------- */
val = digitalRead(ultraSoundSignalIn); // Append signal value to val while(val == LOW) { // Loop until pin reads a high value val = digitalRead(ultraSoundSignalIn); }
while(val == HIGH) { // Loop until pin reads a high value val = digitalRead(ultraSoundSignalIn); timecount = timecount +1; // Count echo pulse time }
/* Writing out values to the serial port * ------------------------------------------------------------------- */
ultrasoundValue = timecount; // Append echo pulse time to ultrasoundValue
serialWrite('A'); // Example identifier for the sensor printInteger(ultrasoundValue); serialWrite(10); serialWrite(13);
/* Lite up LED if any value is passed by the echo pulse * ------------------------------------------------------------------- */
if(timecount > 0){ digitalWrite(ledPin, HIGH); }
/* Delay of program * ------------------------------------------------------------------- */
delay(100); }
This seems to increment the timecount for every iteration of the while loop where the pin is high - but how does this compute the distance? Does the while loop read the pin at a set interval, and then calculate the distance? This gives me seemingly accurate results but is different to any other way of using the SRF05 that I've seen. Cheers, Thom
|
|
|
|
|
Logged
|
|
|
|
|
|