Go Down

Topic: How MaxSonar EZ0 works with arduino? (Read 7159 times) previous topic - next topic

mfdavid

I got an Arduino Diecemilla and a MaxSonar EZ0. My code under arduino is:
Code: [Select]
#define anIn 0
#define LEDpin 13

int iAnVal;
int iAnValAnterior;

 
void setup() {

 Serial.begin(9600);//See note at the Serial.write line.
 pinMode(LEDpin, OUTPUT);  // prepare the pin "LEDpin" for output
 iAnVal = 0;

}

void loop() {
 iAnVal = analogRead(1);   // read a value from the sensor under analog 1
 delay(500);    
 Serial.println(iAnVal);
 digitalWrite(LEDpin,HIGH);
 delay(500);
 digitalWrite(LEDpin,LOW);
}


And my processing code is:
Code: [Select]
import processing.serial.*;

Serial myPort;  // Create object from Serial class
int val;      // Data received from the serial port

void setup()
{
 size(200, 200);
 String portName = "COM38";
 myPort = new Serial(this, portName, 9600);
}

void draw()
{

 if (val != 10) {
   print ("Val = " + val + "\n");
 }

}



The thing is: My output is something like this:
50
51
13

And I have to convert it to an int value. The other (and more serious) problem is that I can´t get accurate values. If I dont touch the sensor, I get different values, and sometimes, REALLY different values.

This value I get, is the distance in inchs, right? Or do I need to convert it somehow?

Thanks a lot.

MikMo

Is that all the processing code ?

I don't see you actually reading from the serial port anywhere, or assigning a value to val anywhere ???

mfdavid

sorry I forgot to post part of the processing code, sorry (i deleted a few comments and some part of the code was erased by accident).
The processing code is:

Code: [Select]

import processing.serial.*;

Serial myPort;  // Create object from Serial class
int val;      // Data received from the serial port

void setup()
{
 size(200, 200);
 String portName = "COM38";
 myPort = new Serial(this, portName, 9600);
}

void draw()
{

 if ( myPort.available() > 0) {  // If data is available,
   val = myPort.read();         // read it and store it in val
 }

 if (val != 10) {
   print ("Val = " + val + "\n");
 }
}

joeh

Is there a reason you don't store the iAnVal as you read it from the sensor? This is already an integer value.

I have also been using the MaxSonar EZ0 and it seems to be a very sensitive ranging module.  There may be some peripheral objects effecting your readings.  I would suggest to test the sensor in a large empty room if possible.

patrick

I'd suppose you check that analogue signal with an Oscilloscope, you may find that there is substantial noise in the signal. You could either ground all unused pins on the Arduino or switch to serial communication with the Maxsonar ?

HTH

estranged

#5
Feb 13, 2009, 03:38 am Last Edit: Feb 13, 2009, 03:39 am by estranged Reason: 1
I have one of the EZ0 sensors, and it is very sensitive.  Using just the analog pin I'll get all sorts of sudden fluctuations in the reading.  I found that using a large buffer of values, and averaging them out gives me a more usable signal.  It's probably not the best way to do signal analysis, but its what I came up with from my zero training.  :)

Here's the relevant parts I think:
Code: [Select]

int sensorPin = 1;

// an array to hold a bunch of sensor values for an average
int sampleSize = 99; // n readings 0 .. (n - 1)
int sensorReadings[100]; // n readings
int sampleCount = 0;

void setup()
{
 // set our inital setPoint to something
 int setPoint = 50;
 
 // init out our sensorReadings array
 int i;
 for (i = 0; i < sampleSize; i++) {
   sensorReadings[i] = setPoint;
 }
}

void loop() {
 delay(10);
 
 sensorValue = analogRead(sensorPin);
 
 // store the current value in our readings array
 sensorReadings[sampleCount] = sensorValue;
 
 // sampleCount starts life at 0, then loops through sampleSize
 if (sampleCount == sampleSize) {
   sampleCount = 0;
 } else {
   sampleCount++;
 }
 
 // figure out the average sensor value
 int i;
 int sensorSum = 0;
 int averageValue = 0;
 for (i = 0; i < sampleSize; i++) {
   sensorSum = sensorSum + sensorReadings[i];
 }
 averageValue = sensorSum / sampleSize;
}

// make decisions based on averageValue
// ...



With a 16MHz clock, it does all the looping and mathing pretty quickly, and I get perfectly fine response times.  I even put in a short delay to slow things down.  All this does is reduce the chances that I'll get a long enough string of bad fluctuations to influence the average reading.

Its very likely that my signal is really damn noisy. :)

Juanelm

#6
Mar 16, 2009, 02:09 am Last Edit: Mar 16, 2009, 02:13 am by Juanelm Reason: 1
Quote
I have one of the EZ0 sensors, and it is very sensitive.  Using just the analog pin I'll get all sorts of sudden fluctuations in the reading.  I found that using a large buffer of values, and averaging them out gives me a more usable signal.  It's probably not the best way to do signal analysis, but its what I came up with from my zero training.  


I adopted your approach, and I think it works very well.  I did a code that is shorter and perhaps more convenient if you don't need the values inside an array:

Code: [Select]

int sum=0;             //Create sum variable
int avgrange=50;    //Quantity of values to average

for(i = 0; i < avgrange ; i++)
     {
        sum+=analogRead(0);
        delay(10);
     }
     Serial.println(sum/avgrange);  //Print average of all measured values
     sum=0;                        //Reset sum variable to zero




patrick

#7
Mar 16, 2009, 09:44 am Last Edit: Mar 16, 2009, 09:47 am by patrick Reason: 1
Nice to see good progress here! Did anyone of you consider using the serial output of the Sensors as a less noisy alternative to the analogue signal? My ultimate goal is to connect three EZ-1 to one board and thought it'd be easier (for me at least) to use a Wiring board (which already has 2 Serial Inputs as standard). Unfortunately I'm not getting well along with my code http://wiring.org.co/cgi-bin/yabb/YaBB.pl?num=1234719208#3 and the Wiring community seems less buzzing than the Arduino community ?
Averaging the values on board is pretty neat!

This the code I use for Serial readout but the values are kinda crappy:
Code: [Select]
int val;

void setup() {
Serial1.begin(9600);               // MaxSonar-EZ1 connected to Serial1 Pin
Serial.begin(9600);                // Serial set to 9600 as specified by MaxSonar.
}

void loop() {
val = Serial1.read();
Serial.println(val);
val = 0;
delay(500);
}

estranged

The EZ0 sensor was the first sensor I bought, and it was my first arduino project.  So I have only used the analog input since it seemed like the easiest to start with.  Since it is working pretty well now, I'm not in a big hurry to tinker with it.  Someday though I will have to try out the serial and PWM options on it.

HotelZero

#9
May 12, 2009, 11:13 am Last Edit: May 12, 2009, 11:14 am by HotelZero Reason: 1
Just received my EZ1 a few days ago and have ran into the same issues that everyone else seems to have had.  My biggest issue seems to be random readings on the analog pin.  I am looking to do some sort of smoothing but instead of a large sampling, doing a smaller sampling, say 10 and do some sorting and drop the two or three lowest readings and average the rest.  Will have to see how that works.

snappy

Hi all, this is my first post.

I am also using the EZ1 and running into the sensitivity issue so I am using the averaging method described. I am using Juanelm's code but noticed the 'int i' variable is not declared. The following should help any beginner programmers out there if they don't know how to fix the issue. I hope this helps someone.  ::)



Code: [Select]

int i;
int sum=0;             //Create sum variable
int avgrange=50;    //Quantity of values to average

for(i = 0; i < avgrange ; i++)
     {
        sum+=analogRead(0);
        delay(10);
     }
     Serial.println(sum/avgrange);  //Print average of all measured values
     sum=0;                        //Reset sum variable to zero

OR
Code: [Select]

int sum=0;             //Create sum variable
int avgrange=50;    //Quantity of values to average

for(int i = 0; i < avgrange ; i++)
     {
        sum+=analogRead(0);
        delay(10);
     }
     Serial.println(sum/avgrange);  //Print average of all measured values
     sum=0;                        //Reset sum variable to zero

Go Up