I'm trying to connect this sensor to the Arduino Mega 2560R3. The board is powered via USB. I connected the sensor to 5V, GND and A0. The problem is, I can't get it to show distance properly. I tried with a couple of different codes but it always shows too little or too much. I also tried adding a gain factor into the code. But as soon as I move it from the reference height, it loses it's calibration (shows too little or too much), it's not so apparent on the closer distances (+- 1cm), but the further away I point it, the bigger the error (+- 1m). Can it be solved?
Present code that is uploaded:
const int anPin = 0;
double anVolt, inches, cm;
double sum=0;//Create sum variable so it can be averaged
int avgrange=60;//Quantity of values to average (sample size)
void setup() {
//This opens up a serial connection to shoot the results back to the PC console
Serial.begin(9600);
}
void loop() {
pinMode(anPin, INPUT);
//MaxSonar Analog reads are known to be very sensitive. See the Arduino forum for more information.
//A simple fix is to average out a sample of n readings to get a more consistant reading.\\
//Even with averaging I still find it to be less accurate than the pw method.\\
//This loop gets 60 reads and averages them
for(int i = 0; i < avgrange ; i++)
{
//Used to read in the analog voltage output that is being sent by the MaxSonar device.
//Scale factor is (Vcc/512) per inch. A 5V supply yields ~9.8mV/in
//Arduino analog pin goes from 0 to 1024, so the value has to be divided by 2 to get the actual inches
anVolt = analogRead(anPin)/2;
sum += anVolt;
delay(10);
}
inches = sum/avgrange;
cm = inches * 2.54*1.05;
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
//reset sample total
sum = 0;
delay(500);
}
I would suggest not using something that averages out 60 pings like this sketch. Make a sketch just ping once, display the value, then wait around 50ms and ping again. With 60 pings, the numbers will be all over the place.
I also don't know why your sketch adds 5% to the cm distance. Sounds like the accuracy isn't correct, so someone tried to fix this in this way. I also wouldn't use floating point numbers. So, the cm calculation instead of:
cm = inches * 2.54*1.05;
would be:
cm = inches * 254 / 100;
This will reduce the compiled size by about 1000 bytes and remove the 5% adjustment.
Thanks, I fixed the code with your suggestion. But the measurement was still not accurate. I added +6 to the end of the line because the result was on average 6-7 cm less than the actual distance. I'm thinking this is because the voltage on USB port must be less than 5V? If I had 5V of external reference on AREF pin, I think the results would be pretty much accurate.
Now...to test other sensors
Do you know maybe of any good Atmel tutorials so I could write in C and manipulate registers and libraries? I was reading on the forums about how to get Arduino Mega to work with Atmel Studio 6 because I want a software debuger, because it makes programing so much easier.
like AWOL said, try using pwm instead of analog. Scroll down a bit on this link and you'll see the Maxbotix pwm tutorial: Arduino Playground - MaxSonar Scroll down even farther and there is also a tutorial for a mode filter to implement instead of averaging your results. Definitely start out simple and work your way up to that, though.
I wrote a code for Serial communication Method with this sensor
any suggestion or feedback will be welcome
// written By : Mohannad Rawashdeh
// http://WWW.Genotronex.com
// http://www.instructables.com/member/Mohannad+Rawashdeh/
// this code to test EZ0 Sonar sensor using Serial method .
// Connect Tx....D8
// Connect Rx ....D9
#include <SoftwareSerial.h>
SoftwareSerial mySerial(8, 9,true); // RX, TX
int BW=4;
char *buffer;
byte x;
char array[3];
int counter=0;
void setup() {
// put your setup code here, to run once:
// set the data rate for the SoftwareSerial port
Serial.begin(9600);
mySerial.begin(9600);
pinMode(BW,OUTPUT);
digitalWrite(BW,LOW);
delay(250);
Serial.println("Calibrartion Cycle ");
delay(150);
}
void reading(){
mySerial.println(1);
while (mySerial.available())
{
x= mySerial.readBytes(buffer,1);
if(*buffer==0x52){
x= mySerial.readBytes(buffer,1);
array[0]=*buffer;
x= mySerial.readBytes(buffer,1);
array[1]=*buffer;
x= mySerial.readBytes(buffer,1);
array[2]=*buffer;
}
}
delayMicroseconds(220);
}
void loop() {
// put your main code here, to run repeatedly:
reading();
int Final_inch=(array[0]-48)*100 + (array[1]-48)*10 +(array[2]-48) ;
float Final_cm=Final_inch*2.54;
Serial.print(Final_inch);
Serial.println(" Inch ");
Serial.print(Final_cm);
Serial.println(" cm ");
delay(200);
}