Pages: 1 ... 21 22 [23] 24 25 ... 34   Go Down
Author Topic: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5  (Read 115853 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sure, here it is:
// ---------------------------------------------------------------------------
// This example code was used to successfully communicate with 15 ultrasonic sensors. You can adjust
// the number of sensors in your project by changing SONAR_NUM and the number of NewPing objects in the
// "sonar" array. You also need to change the pins for each sensor for the NewPing objects. Each sensor
// is pinged at 33ms intervals. So, one cycle of all sensors takes 495ms (33 * 15 = 495ms). The results
// are sent to the "oneSensorCycle" function which currently just displays the distance data. Your project
// would normally process the sensor results in this function (for example, decide if a robot needs to
// turn and call the turn function). Keep in mind this example is event-driven. Your complete sketch needs
// to be written so there's no "delay" commands and the loop() cycles at faster than a 33ms rate. If other
// processes take longer than 33ms, you'll need to increase PING_INTERVAL so it doesn't get behind.
// ---------------------------------------------------------------------------
#include <NewPing.h>

#define SONAR_NUM     3 // Number of sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 33 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).

unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM];         // Where the ping distances are stored.
uint8_t currentSensor = 0;          // Keeps track of which sensor is active.

NewPing sonar[SONAR_NUM] = {     // Sensor object array.
  NewPing(22, 23, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping. // OK
  NewPing(24, 25, MAX_DISTANCE), // NOK
  NewPing(34, 35, MAX_DISTANCE)  // OK
};

  void setup() {
    Serial.begin(115200);
    pingTimer[0] = millis() + 75;           // First ping starts at 75ms, gives time for the Arduino to chill before starting.
    for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
      pingTimer = pingTimer[i - 1] + PING_INTERVAL;
  }

void loop() {
  for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
    if (millis() >= pingTimer) {         // Is it this sensor's time to ping?
      pingTimer += PING_INTERVAL * SONAR_NUM;  // Set next time this sensor will be pinged.
      if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
      sonar[currentSensor].timer_stop();          // Make sure previous timer is canceled before starting a new ping (insurance).
      currentSensor = i;                          // Sensor being accessed.
      cm[currentSensor] = 0;                      // Make distance zero in case there's no ping echo for this sensor.
      sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
    }
  }
  // Other code that *DOESN'T* analyze ping results can go here.
}

void echoCheck() { // If ping received, set the sensor distance to array.
  if (sonar[currentSensor].check_timer())
    cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
}

void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
  // The following code would be replaced with your code that does something with the ping results.
  for (uint8_t i = 0; i < SONAR_NUM; i++) {
    Serial.print(i);
    Serial.print("=");
    Serial.print(cm);
    Serial.print("cm ");
  }
  Serial.println();
}


Now two of the sensors work fine with the ethernet shield, using the pins above. Without the ethernet shield all 3 works.
I've looked at the 2560 pinout, but it didn't help figuring this out. Also tried several pin configs. I've also tried initializing the Ethernet shield (i.e. setting IP addr etc), but no luck (and tried with the 1.0 IDE as well).

Only the 3 sensors are wired to the Mega (power via USB).

I'll try with an UNO with an Ethernet shield and an Arduino Ethernet.

  /Magnus
Logged

Toledo, OH
Offline Offline
God Member
*****
Karma: 36
Posts: 510
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Now two of the sensors work fine with the ethernet shield, using the pins above. Without the ethernet shield all 3 works.
I've looked at the 2560 pinout, but it didn't help figuring this out. Also tried several pin configs. I've also tried initializing the Ethernet shield (i.e. setting IP addr etc), but no luck (and tried with the 1.0 IDE as well).

Only the 3 sensors are wired to the Mega (power via USB).

I'll try with an UNO with an Ethernet shield and an Arduino Ethernet.

  /Magnus

I don't see any Ethernet code in that sketch.  Does it fail just as is?  What exactly happens?

The first thing you should ALWAYS try is to use different pins.  Also, switch the sensors to see if the problem follows the sensors or the pins.  My guess is that there's a conflict with the pins you are using.  Using different pins is so simple that you should always try this first.

Try totally different pins and see if anything changes.  If so, the conflict is with the Ethernet or SD library.

I'd also try to slow down the pings, change PING_INTERVAL 33  to PING_INTERVAL 250 and see if that does anything.

Finally, I'd try to not use a timer interrupt method of pinging as it could be just a simple timing issue with multiple libraries competing for CPU cycles.  So instead of using ping_timer() just do a convention ping of each sensor.  Here's a sketch that does just that to your 3 sensors:

Code:
#include <NewPing.h>

#define SONAR_NUM       3 // Number of sensors.
#define MAX_DISTANCE  200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 250 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).

NewPing sonar[SONAR_NUM] = {     // Sensor object array.
  NewPing(22, 23, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
  NewPing(24, 25, MAX_DISTANCE),
  NewPing(34, 35, MAX_DISTANCE)
};

void setup() {
  Serial.begin(115200);
}

void loop() {
  for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
    unsigned int cm = sonar[i].ping_cm();
    Serial.print(i);
    Serial.print("=");
    Serial.print(cm);
    Serial.print("cm ");
  }
  Serial.println();
  delay(PING_INTERVAL);
}

Tim
« Last Edit: January 31, 2013, 05:01:06 pm by teckel » Logged

Arduino - Teensy - Raspberry Pi
My libraries: NewPing - LCDBitmap - toneAC - NewTone - TimerFreeTone

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

I solved it!

External power is needed to the Arduino, i.e. just powering via USB is not enough to get good results when multiple ping sensors and an Ethernet shield are used.
This is regardless if an Mega or an Uno are used, or if the PC have 1 or 2 PSUs.

  //Magnus
Logged

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

Hi everyone! I have a question... if I use 4 ultrasonic sensors and I want to send the data to Processing for transforming the data to OSC, can I use the 15 sensors sketch but with 4?? I don't know how can i do it...
Logged

Greenville, IL
Offline Offline
Edison Member
*
Karma: 15
Posts: 1330
Warning Novice on board! 0 to 1 chance of errors!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi everyone! I have a question... if I use 4 ultrasonic sensors and I want to send the data to Processing for transforming the data to OSC, can I use the 15 sensors sketch but with 4?? I don't know how can i do it...

Code:
#define SONAR_NUM       4 // Number of sensors.
Logged


Toledo, OH
Offline Offline
God Member
*****
Karma: 36
Posts: 510
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I solved it!

External power is needed to the Arduino, i.e. just powering via USB is not enough to get good results when multiple ping sensors and an Ethernet shield are used.
This is regardless if an Mega or an Uno are used, or if the PC have 1 or 2 PSUs.

  //Magnus


Interesting!  My ultrasonic sensors only use a couple mA each, while the Arduino Uno uses 60 mA (I'd guess the Mega uses more).  I wouldn't think that just the sensors would put your USB or the voltage regulator over the top.  Have you measured what kind of current it's using?  It just seems very unlikely that it's within a couple mA of going over the top and the sensors draw enough current to do it.  I guess it's possible, just doesn't seem likely.

Tim
Logged

Arduino - Teensy - Raspberry Pi
My libraries: NewPing - LCDBitmap - toneAC - NewTone - TimerFreeTone

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

Hi everyone! I have a question... if I use 4 ultrasonic sensors and I want to send the data to Processing for transforming the data to OSC, can I use the 15 sensors sketch but with 4?? I don't know how can i do it...

Code:
#define SONAR_NUM       4 // Number of sensors.
yeah, I know that, but i want to know how to send to processing, How can processing read this data???.... coz from processing i can transform the data to OSC...or am I wrong?? smiley-roll-sweat
Thank u!
Logged

Toledo, OH
Offline Offline
God Member
*****
Karma: 36
Posts: 510
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi everyone! I have a question... if I use 4 ultrasonic sensors and I want to send the data to Processing for transforming the data to OSC, can I use the 15 sensors sketch but with 4?? I don't know how can i do it...

Code:
#define SONAR_NUM       4 // Number of sensors.
yeah, I know that, but i want to know how to send to processing, How can processing read this data???.... coz from processing i can transform the data to OSC...or am I wrong?? smiley-roll-sweat
Thank u!

What do you mean by "i want to know how to send to processing"?  What is "processing"?  What is "OSC"?

The sketch pings the sensors and stores the values in the cm[] array.  In the pingResult() function the contents of the cm[] array are output via serial.  If you want to send that data to something else, whatever "processing" and "OSC" is, you would simply replace the contents of the pingResults() function with whatever you wanted to do with the results.  We have no idea what you want to do with the results, but the data is there for you to do whatever you want with it.  The pingResults() function is where you should do your magic with the results.

I have a post with help and alternative code for the 15 sensor sketch.

Tim
Logged

Arduino - Teensy - Raspberry Pi
My libraries: NewPing - LCDBitmap - toneAC - NewTone - TimerFreeTone

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Just used this on a project I was building against my digispark. I removed the timer stuff since I didn't need them and it wouldn't compile against it. But anyway. worked great and was better than me trying to futz with timing all day long. Thanks!!

DigiStump's forum post for the project: http://digistump.com/board/index.php/topic,299.0.html

Youtube of it running:
Logged

Toledo, OH
Offline Offline
God Member
*****
Karma: 36
Posts: 510
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Just used this on a project I was building against my digispark. I removed the timer stuff since I didn't need them and it wouldn't compile against it. But anyway. worked great and was better than me trying to futz with timing all day long. Thanks!!

I think the digispark uses the ATtiny85, that would make sense that it wouldn't work with the timer stuff.  I believe I've modified my development code to detect the ATtiny processors and not use the timer interrupt stuff.  The standard ping(), ping_cm(), ping_in(), ping_median() methods should still work just fine on the ATtiny.

If program space is also a problem with the limited memory on the ATtiny, you could reduce the compiled size by optimizing your sketch a little.  Here's a suggestion:

Code:
#include <NewPing.h>

#define TRIGGER_PIN 3
#define ECHO_PIN 5
#define RED_PIN 0
#define GREEN_PIN 1
#define BLUE_PIN 4
#define MAX_DISTANCE 60

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

void setup() {
  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);
}

void loop() {
  uint8_t distance = sonar.ping_cm();
  
  if (distance) {
    uint8_t greenValue = map(distance, 1, MAX_DISTANCE, 0, 255);  //Map the distance range to a range of 0 to 255 to the pwm value for the Green LED
    uint8_t redValue = 255 - greenValue;
    analogWrite(GREEN_PIN, greenValue);
    analogWrite(RED_PIN, redValue);
    digitalWrite(BLUE_PIN, LOW);
  } else {
    //Out of range, turn the LED blue
    digitalWrite(GREEN_PIN, LOW);
    digitalWrite(RED_PIN, LOW);    
    digitalWrite(BLUE_PIN, HIGH);
  }
  delay(50);
}

This would use quite a bit less sketch size and reduce the memory usage as well by using defines and right-sized variables.

On a side note, the digispark is under-powered and overpriced. For a couple dollars more you can get a Teensy 2.0 which is practically the same size and a full ATmega microcontroller so you have a ton of available pins (actually, it has more pins than an Arduino Uno).  For just $3 more you can also get the Teensy 3.0 which is a 96 MHz 32-bit microcontroller, but still works with Arduino IDE.

Tim
« Last Edit: February 06, 2013, 03:08:00 pm by teckel » Logged

Arduino - Teensy - Raspberry Pi
My libraries: NewPing - LCDBitmap - toneAC - NewTone - TimerFreeTone

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

Hi everyone! I have a question... if I use 4 ultrasonic sensors and I want to send the data to Processing for transforming the data to OSC, can I use the 15 sensors sketch but with 4?? I don't know how can i do it...

Code:
#define SONAR_NUM       4 // Number of sensors.
yeah, I know that, but i want to know how to send to processing, How can processing read this data???.... coz from processing i can transform the data to OSC...or am I wrong?? smiley-roll-sweat
Thank u!

What do you mean by "i want to know how to send to processing"?  What is "processing"?  What is "OSC"?

The sketch pings the sensors and stores the values in the cm[] array.  In the pingResult() function the contents of the cm[] array are output via serial.  If you want to send that data to something else, whatever "processing" and "OSC" is, you would simply replace the contents of the pingResults() function with whatever you wanted to do with the results.  We have no idea what you want to do with the results, but the data is there for you to do whatever you want with it.  The pingResults() function is where you should do your magic with the results.

I have a post with help and alternative code for the 15 sensor sketch.

Tim
First of all, thank you for answering Tim! Processing is a language like, java, C++, etc... and OSC it's a protocol like MIDI for controlling a virtual instrument or whatever in your computer... My project is with 4 ultrasonic sensors to get the results and transform them into OSC so you can control eg. Ableton Live or whatever, moving your hands you can change a synth's parameters in real time.... Your code works perfectly for my 4 sensors! Now with your advice I'm going to try "play" with the data... Maybe I could obviate "Processing" and finding a library for Arduino which I can handle OSC... hahahaha sorry I'm rambling...
Anyway Thanks for ur code again!!!
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I think the digispark uses the ATtiny85, that would make sense that it wouldn't work with the timer stuff.  I believe I've modified my development code to detect the ATtiny processors and not use the timer interrupt stuff.  The standard ping(), ping_cm(), ping_in(), ping_median() methods should still work just fine on the ATtiny.

If program space is also a problem with the limited memory on the ATtiny, you could reduce the compiled size by optimizing your sketch a little.  Here's a suggestion:

Code:
#include <NewPing.h>

#define TRIGGER_PIN 3
#define ECHO_PIN 5
#define RED_PIN 0
#define GREEN_PIN 1
#define BLUE_PIN 4
#define MAX_DISTANCE 60

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

void setup() {
  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);
}

void loop() {
  uint8_t distance = sonar.ping_cm();
  
  if (distance) {
    uint8_t greenValue = map(distance, 1, MAX_DISTANCE, 0, 255);  //Map the distance range to a range of 0 to 255 to the pwm value for the Green LED
    uint8_t redValue = 255 - greenValue;
    analogWrite(GREEN_PIN, greenValue);
    analogWrite(RED_PIN, redValue);
    digitalWrite(BLUE_PIN, LOW);
  } else {
    //Out of range, turn the LED blue
    digitalWrite(GREEN_PIN, LOW);
    digitalWrite(RED_PIN, LOW);    
    digitalWrite(BLUE_PIN, HIGH);
  }
  delay(50);
}

This would use quite a bit less sketch size and reduce the memory usage as well by using defines and right-sized variables.

On a side note, the digispark is under-powered and overpriced. For a couple dollars more you can get a Teensy 2.0 which is practically the same size and a full ATmega microcontroller so you have a ton of available pins (actually, it has more pins than an Arduino Uno).  For just $3 more you can also get the Teensy 3.0 which is a 96 MHz 32-bit microcontroller, but still works with Arduino IDE.

Tim

Great stuff, I'm a hardware junky that knows enough code to be stupid with it. so seeing someone that knows how to make it effecient is alway a bonus. Thanks for cleaning that up a ton. I will have a go with that and let you know.

Again Thanks!
« Last Edit: February 07, 2013, 04:59:29 pm by rainierez » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The new code you updated works great but if I leave the timer functions in the cpp then it won't compile. :/ I get this in the IDE

Code:
...\Arduino\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_us(unsigned int, void (*)())':
...\Arduino\libraries\NewPing\NewPing.cpp:151: error: 'OCR2A' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:152: error: 'TIMSK2' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:152: error: 'OCIE2A' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_ms(long unsigned int, void (*)())':
...\Arduino\libraries\NewPing\NewPing.cpp:167: error: 'OCR2A' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:168: error: 'TIMSK2' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:168: error: 'OCIE2A' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_stop()':
...\Arduino\libraries\NewPing\NewPing.cpp:177: error: 'TIMSK2' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:177: error: 'OCIE2A' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_setup()':
...\Arduino\libraries\NewPing\NewPing.cpp:195: error: 'ASSR' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:195: error: 'AS2' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:196: error: 'TCCR2A' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:196: error: 'WGM21' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:197: error: 'TCCR2B' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:197: error: 'CS22' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:198: error: 'TCNT2' was not declared in this scope
Logged

Toledo, OH
Offline Offline
God Member
*****
Karma: 36
Posts: 510
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The new code you updated works great but if I leave the timer functions in the cpp then it won't compile. :/ I get this in the IDE

Yes, v1.5 of NewPing that you're running is not designed for the ATtiny.  My development version now detects the ATtiny and automatically removes the timer stuff.  In other words, you'll need to comment out the timer stuff in the library till I release version 1.6 of NewPing.

Tim
Logged

Arduino - Teensy - Raspberry Pi
My libraries: NewPing - LCDBitmap - toneAC - NewTone - TimerFreeTone

Greece
Offline Offline
Full Member
***
Karma: 2
Posts: 172
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,

I would like to ask if it is possibly to read the cm with decimal like 10.4 cm e.t.c.

Thank in advance.

Best regards,
Tasos
Logged

Pages: 1 ... 21 22 [23] 24 25 ... 34   Go Up
Jump to: