Pages: [1] 2 3 4   Go Down
Author Topic: multiple maxbotix LVEZ on one UNO?  (Read 4163 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all,

Apologies as this is a little long and I am quite new to this -- I followed this tutorial (http://www.electrojoystick.com/tutorial/?page_id=285) to get a Maxbotix LV-EZ1 sensor sending data via analog output to an Uno board connected via USB to a Macbook Pro.  I get accurate data into the serial monitor and can read it in Max/MSP (final goal) -- this part is working!

I would like to know how many of these sensors I can use with one Uno board.  Right now I have two connected in parallel but only one is reading with any accuracy; the other is printing to the serial bus correctly, but always 6 inches.  Both are powered by the single 5v pin, each connected to separate GND pins and into analog 0 and 1 respectively.  I have been trying to get values from each in alternation by repeating the code from the tutorial with each analog pin:


    int configPin = 13;                 //Set the sonar Calibration Pin

    void setup() {                    //begin of program

    Serial.begin(9600);             //serial baud rate 9600

    pinMode(configPin,OUTPUT);       //make Calibration pin output

    }

    void loop(){                     //looping of program

    digitalWrite(configPin,HIGH);    //raise the reset pin high

    delay(200);                      //start of 1st calibration ring

    float sensorvalue1 = analogRead(0); //get analog sensor value from pin 0

    float inchvalue1 = (254.0/1024.0) *2.0* sensorvalue1; //convert to inches

    Serial.print("01 ");      //print inch text
   
    Serial.println(inchvalue1);        //print inch value

    delay(100);                      //optional delay 100 ms
   
    digitalWrite(configPin,LOW);      //turn off 1st Calibration ring and sensor
   
    delay(200);                      //delay between cycles
   
    digitalWrite(configPin,HIGH);    //raise the reset pin high

    delay(200);                      //start of 2nd calibration ring
   
    float sensorvalue2 = analogRead(1); //get analog sensor value from pin 1

    float inchvalue2 = (254.0/1024.0) *2.0* sensorvalue2; //convert to inches

    Serial.print("02 ");      //print inch text
   
    Serial.println(inchvalue2);        //print inch value

    delay(100);                      //optional delay 100 ms

    digitalWrite(configPin,LOW);      //turn off 2nd Calibration ring and sensor

    delay(100);                      //delay 100 ms

    }

Is the code wrong, or do I have to change how things are connected?  Do I need all of this code toggling the configuration pin?  Do I need to establish separate configPin for each analog pin I'm using?  I have tried without it and it seems to make the readings more accurate, but I don't understand how it works exactly.  For the wires coming out of the same pin on the Uno, I just have the exposed copper wrapped together, no resistors or anything like that.

If I am posting in the wrong place please re-direct me.

Thanks!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I recently got two maxbotix LV-EZ4 sensors, and have them connected in what maxbotix calls the Constantly Looping config (see application notes on this page: http://www.maxbotix.com/downloads.htm). In this config, each sensor needs +V, Gnd, and an analog line to read it, as well as one pin to act as the initial kick-off control. For one sensor, this is four pins, and you'll need an additional analog pin for each sensor connected. Check out maxbotix's app notes if you haven't already -- they have great diagrams and instructions.

I skimmed your code, and got lost with the delays a bit. What are you calling the calibration pin? Is that the pin connected to the sensor's RX line? Where is your EN pin connected? Mine is connected to Vcc permanently.

Here's some code I have. From my setup() function I call sonarInit(SONAR_CTL) that boots the sensors (configured as above). This takes about half a second for continuous ranging to begin.

Code:
#define Vcc           5.0f
#define SONAR_CTL     A1
#define SONAR_FIRST   A2
#define SONAR_SECOND  A3

void sonarInit(int controlPin)
{
  // wait for boot
  delay(250);
  // trigger ranging
  digitalWrite(controlPin, HIGH);
  delayMicroseconds(25);
  digitalWrite(controlPin, LOW);
  // Make high-impedance input to signal round-robin ranging.
  pinMode(controlPin, INPUT);
  // wait for calibration+initial ranging times.
  delay(49+49+100);
  // sonars should alternate automatically now
}

void setup()
{
  Serial.begin(38400);
  Serial.println("Sonar test (EZ4) Start");

  // Sonar setup
  pinMode(SONAR_CTL, OUTPUT);
  pinMode(SONAR_FIRST, INPUT);
  pinMode(SONAR_SECOND, INPUT);

  Serial.println("boot");
  sonarInit(SONAR_CTL);
  Serial.println("first");
  sonarRange(SONAR_FIRST);

  Serial.println("running");
}

Once it's all initialized, my loop() function just calls the sonarRange() on each analog input:

Code:
// No need to call faster than 49msec per sensor
int sonarRange(int sonarPin)
{
  // At 5V, inches = analogRead() / 1024 * Vcc / 0.009 = 0.542534722
  return analogRead(sonarPin) * 0.542534722f;
}

void loop()
{
  int leftDist = sonarRange(SONAR_FIRST);
  int rightDist = sonarRange(SONAR_SECOND);

  Serial.print("L = "); Serial.print(leftDist);
  Serial.print("  R = "); Serial.println(rightDist);
  delay(333); // Must be at least 50
}

I hope this was helpful. This code works great for the sensors I have. The caveat to having sensors auto-range round-robin like this is that each one takes 49ms, so your sensor frequency goes from 20Hz, to 10Hz, to 6Hz, to 5Hz, etc. as you add sensors. A 10Hz frequency is fine for my project.
Logged

Ontario, Ohio
Offline Offline
Full Member
***
Karma: 1
Posts: 205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@RoverHacker

Hey there,
Am having success using a single LV1 with PWM, but now I would like to try using two LV1's. It seems the only  way to do this is to use the analog chaining. I'm a little confused about which pin on the LV1 you are referring to when you say control pin. Is that the RX pin? And what is the EN pin? Maxbotix also refers to the BW pins on all the LV's in the chain going to logic high, so should I just wire that to the 5v rail?
Logged

the land of sun+snow
Offline Offline
Faraday Member
**
Karma: 149
Posts: 2790
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I believe you cannot use the same pin to trigger both sonars, as they will ping simultaneously
and the waves will interfere. You also cannot let them free-run, as they will again interfere.

And if you use separate trigger pins then you might as well use the pulsewidth mode, rather
than the analog mode, as things will go faster. Most of the time, you will get a pulse out in
maybe 10-20 msec. With analog mode, as I think you know, you have to wait 50-msec for the
analog signals to stabilize.


Logged

Ontario, Ohio
Offline Offline
Full Member
***
Karma: 1
Posts: 205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oric Dan,
So are you saying that with both sensors in PWM mode, I could wire each sensor with RX to a digital pin to turn it on and just add a delay in the code so that they fire at different times? That way they they wouldn't read each other's ping. The code would be much simpler I think.
Logged

the land of sun+snow
Offline Offline
Faraday Member
**
Karma: 149
Posts: 2790
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Oric Dan,
So are you saying that with both sensors in PWM mode, I could wire each sensor with RX to a digital pin to turn it on and just add a delay in the code so that they fire at different times? That way they they wouldn't read each other's ping. The code would be much simpler I think.

RX is the trigger-in pin, and PW is the pulsewidth-out pin. You first trigger and read one sonar, and
then trigger and read the other. There is no overlap in pings. You actually don't need a delay in the
code, as you don't trigger the 2nd until the PW signal of the first has been read.

I believe there is a sketch on the Playground or somewheres for the Maxsonars that uses pulsein()
to read PW. Whenever I get to it, I plan to write a routine for my ServoTank that uses external
interrupts to read the PW pulses, so I don't have to wait on pulsein().

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@TeslaIaint:
@Oric:

My mistake, I mentioned the EN pin, but I meant BW pin.

When the sensors are chained together (read the app note I referenced, also described below), You only need to use one control pin on the arduino to drive however many sensors you have chained together. Each sensor will take 49msec to do a ranging, but the real nice thing about these sensors, especially analog output, is that you can read the result at any time, and it will be the most recent measurement. So in my code, I tickle the sensor array ONCE, then just read the analog pins no more frequently than 50msec (or whatever).

For chaining, you connect the arduino's control pin (whichever one you pick) to the first sensor's RX pin. Then connect the first sensor's TX pin to the second sensor's RX pin. Repeat this for however many sensors you have. Then the last sensor's TX pin is looped back to the first sensor's RX pin through a 1K resistor. On each sensor, the BW is indeed tied to +5V.

The downside to chaining N resistors is that the frequency you can check each sensor goes down. One sensor is 1/49msec, two is 1/98msec, ... 1/(N*49msec). Or roughly, 20Hz, 10Hz, 7Hz, 5Hz, etc.

@Oric:

You can certainly trigger two sensors with the same arduino control pin. BUT, it depends on how the sensors are arranged on your gadget, and in what environment they are used. I'm building a 4WD rover for long-distance outdoor use, and I could conceivably trigger sensor arrays on the front and rear simultaneously. If this was used indoors, no way.

I've only been using the analog signalling because that's so easy. However, if I were to use PWM output, then I'd most likely run that through an interruptable pin so my main code doesn't have to block waiting for the signal.
Logged

the land of sun+snow
Offline Offline
Faraday Member
**
Karma: 149
Posts: 2790
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@frmless_field:
Ok, you threw me off with your first post, saying "Right now I have two connected in parallel but
only one is reading with any accuracy ...". Wired in parallel is not the same as daisy-chaining.

I don't know if you've solved your problem by now, but looking at one of the appnotes on the
page mentioned, it says "Then just strobe the first sensor's RX pin and all of the sensors will read
the range in sequence".

In your original code, it looks like you're applying a very long pulse to the first RX pin, about
300-msec, whereas I think the RX pulse is supposed to be more like 20-usec.
Logged

Ontario, Ohio
Offline Offline
Full Member
***
Karma: 1
Posts: 205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
/*
/*
Two Maxbotix LV EZ1 sonic sensors wired in parallel
 
 */
const int sonarSensorPinL = 5;   //connected to left sonar pwm pin
const int sonarSensorPinR = 6;    //connected to right sonar pwm pin
const int sonarTriggerPinR = 7;   //connected to right sonar RX pin
const int sonarTriggerPinL = 8;   //connected to left sonar RX pin
long valueL = 0;
long valueR = 0;
int inchesL = 0;
int inchesR = 0;
unsigned int calval = 0;                  


void setup()
{
  Serial.begin(9600);
  pinMode(sonarTriggerPinL, OUTPUT);
  pinMode(sonarTriggerPinR, OUTPUT);
}

void loop()
{
  if (calval < 1)  {        // this calls the calibrate subroutine only once when the sketch begins
    calibrate ();            
  }
  calval = calval + 1;  
  // Read the value from each sensor pin
  digitalWrite(sonarTriggerPinR, HIGH);
  valueR = pulseIn(sonarSensorPinR, HIGH);
  inchesR = valueR / 147;     // 147 microeconds per inch
  Serial.print("inches right = ");
  Serial.println(inchesR);
  delayMicroseconds(20);                // can be any langth of delay as long as it's >= 20 microseconds according to data sheet
  digitalWrite(sonarTriggerPinR, LOW);  //turns off right sonic sensor so that it doesn't read from left sonic pulse
  delay(250);                                         //  delay for serial monitor

  digitalWrite(sonarTriggerPinL, HIGH);
  valueL = pulseIn(sonarSensorPinL, HIGH);
  inchesL = valueL / 147;     // 147 microeconds per inch
  Serial.print("inches left = ");
  Serial.println(inchesL);
  delayMicroseconds(20);               // can be any langth of delay as long as it's >= 20 microseconds according to data sheet                
  digitalWrite(sonarTriggerPinL, LOW);  //turns off left sonic sensor so that it doesn't read from right sonic pulse
  delay(250);                                        // delay for serial monitor
}

void calibrate ()                    
{
  digitalWrite(sonarTriggerPinR, HIGH);
  valueR = pulseIn(sonarSensorPinR, HIGH);
  delay(250);
  digitalWrite(sonarTriggerPinL, HIGH);
  valueL = pulseIn(sonarSensorPinL, HIGH);
  delay(250);

}




   This is my attempt at making two LV EZ1 sensors give reliable readings without interfering with each other. They are wired in parallel. For the inches to be more readable on the serial monitor, a longer delay would be better, but I wanted some feedback on this setup. In my final design, the serial monitor will be eliminated anyway. Also, I threw in a calibration subroutine. According to the data sheet, http://www.maxbotix.com/documents/MB1010_Datasheet.pdf, the sensor will calibrate once during start up, but I'm not sure that it would calibrate properly since I'm using the RX pins to trigger the sensor. That might be a question for Maxbotix tech support. Anyway, it can't hurt, and it only happens once per 65,536 loops before it rolls back to zero and re-calibrates (see unsigned int). For my purposes that would be just fine.
  Unfortunately, the only sonic sensor that I have is tied up with another project, but I have ordered two more. I won't be able to test this code until I receive them. The two sensors will be hooked up facing the same direction with about about 30 to 45 degrees offset. Any input is greatly appreciated.  edit: tested and working

« Last Edit: March 08, 2012, 10:37:53 pm by TeslaIaint » Logged

the land of sun+snow
Offline Offline
Faraday Member
**
Karma: 149
Posts: 2790
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@teslaint
Quote
Any input is greatly appreciated.

That's basically the code I would expect to see for 2 sonars wired in parallel, except I
believe the trigger pulses are supposed to be only 20-MICROsec long or so. Yours are between
20 and 50 MILLIsec.
Logged

Ontario, Ohio
Offline Offline
Full Member
***
Karma: 1
Posts: 205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks oric_dan,
Good point. I edited the code above. Can anybody foresee any other difficulties I might run into with this code?
Logged

the land of sun+snow
Offline Offline
Faraday Member
**
Karma: 149
Posts: 2790
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Good point. I edited the code above. Can anybody foresee any other difficulties I might run into with this code?

You will make many changes ONCE you actually try running it.

Also, looking back at the code posted in the first msg of this thread by the OP, he does the same thing,
and which I imagine was a major problem. On reading the datasheet, if you keeping holding the trigger pin
RX high, then the sonar will keep pinging continuously, which is exactly the wrong thing to do if the
first trigger is supposed to set off the daisy chain.
Logged

Ontario, Ohio
Offline Offline
Full Member
***
Karma: 1
Posts: 205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I will wire the two sensors separately with separate RX trigger pins. When I said "parallel", I meant parallel in respect to the + and - voltage rails. I have the two sonic sensors now, and if I get a chance tonight I'll wire them up and test the code. I hope it works. I'm getting frustrated with my little project haha. I also sent an email to Maxbotix asking them about calibration.
Logged

the land of sun+snow
Offline Offline
Faraday Member
**
Karma: 149
Posts: 2790
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I will wire the two sensors separately with separate RX trigger pins. When I said "parallel", I meant parallel in respect to the + and - voltage rails. I have the two sonic sensors now, and if I get a chance tonight I'll wire them up and test the code. I hope it works. I'm getting frustrated with my little project haha. I also sent an email to Maxbotix asking them about calibration.

Yours are also in parallel ... with respect to the signaling pins ... but in the 1st post, the OP said his were
also in parallel, but he actually has them daisy-chained.

Tell me how the measurement accuracy goes. My Maxsonars actually read about 2" too short on the
measurements, and I haven't figured out why as yet. I did pay attention to the business about having
an unobstructed view during powerup calibration. That idea sounds nice, but sort of a problem in
practice.
Logged

Ontario, Ohio
Offline Offline
Full Member
***
Karma: 1
Posts: 205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The above code posted my me is tested and working. Also, oric_dan is right about the measurements being off a bit, but my tests weren't exactly scientific.  Maybe If centimeters are used instead of inches, it might be closer. This mode filter, http://myarduinoproject.wordpress.com/2011/06/06/a-mode-filter-for-the-maxbotix-sensor/, also helps with the random distances that are obviously wrong.
Logged

Pages: [1] 2 3 4   Go Up
Jump to: