NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.7

You are right. I need to revisit that. I might need to extend that timeout. I have seen these specific sensors work over 2m (to a flat wall).

Haven't seen cross-talk in my testing yet, but I haven't done anything too stressing. This is for a large robot, so the sensors will be about 20-50 cm apart, more or less radially pointing outward.

For collision avoidance I am hoping that a false positive from a simultaneous ping would not necessarily be a bad thing. If I receive my neighbor's ping from a tilted surface nearby (which I still need to avoid), that is better than not seeing anything. I hope that the first echo sensed causes the pin to go low, and I get the "conservative" estimate of distance to a nearby obstacle.

Teckel, I've received a Due and downloaded NewPing (you asked earlier in the thread). The immediate issues are that it includes "avr/io.h" and "avr/interrupt.h", neither of which seem to have obvious counterparts for the ARM due.

With those headers missing, the following lines become issues:

C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In constructor 'NewPing::NewPing(uint8_t, uint8_t, int)':
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:19: error: cannot convert 'volatile RwReg*' to 'volatile uint8_t*' in assignment
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:20: error: cannot convert 'volatile RoReg*' to 'volatile uint8_t*' in assignment
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:22: error: 'portModeRegister' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_us(unsigned int, void (*)())':
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:151: error: 'OCR2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:152: error: 'TIMSK2' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:152: error: 'OCIE2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_ms(long unsigned int, void (*)())':
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:167: error: 'OCR2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:168: error: 'TIMSK2' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:168: error: 'OCIE2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_stop()':
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:177: error: 'TIMSK2' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:177: error: 'OCIE2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_setup()':
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:195: error: 'ASSR' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:195: error: 'AS2' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:196: error: 'TCCR2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:196: error: 'WGM21' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:197: error: 'TCCR2B' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:197: error: 'CS22' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:198: error: 'TCNT2' was not declared in this scope

jmXCA:
Teckel, I've received a Due and downloaded NewPing (you asked earlier in the thread). The immediate issues are that it includes "avr/io.h" and "avr/interrupt.h", neither of which seem to have obvious counterparts for the ARM due.

With those headers missing, the following lines become issues:

C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In constructor 'NewPing::NewPing(uint8_t, uint8_t, int)':

SNIP

Ok, so in a pinch I quickly hacked this to work on the DUE (NO TIMERS YET). I'm new to Arduino so these changes probably have some side effect I'm not aware of (ie, I'm not sure why digitalWrite and pinMode functions weren't used in the first place - maybe just to avoid function calls?)
1) In NewPing.h:
-if'defd the AVR includes
#ifndef arm
#include <avr/io.h>
#include <avr/interrupt.h>
#ifndef arm

-added 2 members to NewPing class
uint8_t _triggerPin;
uint8_t _echoPin;

2) In NewPing.cpp:
-Added these 2 lines in the constructor
_triggerPin = trigger_pin;
_echoPin = echo_pin;

-Commented out the portModeRegister line

-Change any lines like "*_triggerMode |= _triggerBit; // Set trigger pin to output."
to: pinMode(_triggerPin,OUTPUT);

-And finally a new ping_trigger()
#ifdef arm
boolean NewPing::ping_trigger() {
#if DISABLE_ONE_PIN != true
pinMode(_triggerPin, OUTPUT);
#endif
digitalWrite(_triggerPin, LOW);
delayMicroseconds(4); // Wait for pin to go low, testing shows it needs 4uS to work every time.
digitalWrite(_triggerPin, HIGH);
delayMicroseconds(10); // Wait long enough for the sensor to realize the trigger pin is high. Sensor specs say to wait 10uS.
digitalWrite(_triggerPin, LOW);

#if DISABLE_ONE_PIN != true
pinMode(_triggerPin, INPUT);
#endif

_max_time = micros() + MAX_SENSOR_DELAY; // Set a timeout for the ping to trigger.
while ((digitalRead(_echoPin) == HIGH) && (micros() <= _max_time)) {}
while (!(digitalRead(_echoPin) == HIGH)) // Wait for ping to start.
if (micros() > _max_time) return false; // Something went wrong, abort.

_max_time = micros() + _maxEchoTime; // Ping started, set the timeout.
return true; // Ping started successfully.
}
#else
//old ping_trigger() goes here
#endif

jmXCA:
Teckel, I've received a Due and downloaded NewPing (you asked earlier in the thread). The immediate issues are that it includes "avr/io.h" and "avr/interrupt.h", neither of which seem to have obvious counterparts for the ARM due.

With those headers missing, the following lines become issues:

C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In constructor 'NewPing::NewPing(uint8_t, uint8_t, int)':

C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:19: error: cannot convert 'volatile RwReg*' to 'volatile uint8_t*' in assignment
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:20: error: cannot convert 'volatile RoReg*' to 'volatile uint8_t*' in assignment
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:22: error: 'portModeRegister' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_us(unsigned int, void ()())':
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:151: error: 'OCR2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:152: error: 'TIMSK2' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:152: error: 'OCIE2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_ms(long unsigned int, void (
)())':
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:167: error: 'OCR2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:168: error: 'TIMSK2' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:168: error: 'OCIE2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_stop()':
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:177: error: 'TIMSK2' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:177: error: 'OCIE2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_setup()':
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:195: error: 'ASSR' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:195: error: 'AS2' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:196: error: 'TCCR2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:196: error: 'WGM21' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:197: error: 'TCCR2B' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:197: error: 'CS22' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:198: error: 'TCNT2' was not declared in this scope

The Due will not currently work with the NewPing library. NewPing uses all low-level port register calls which are specific to the 8 bit ATmega processors. I've been working on a new version that will work with the Teensy 3.0 that's similar to the Due as they both use 32 bit microcontrollers. I don't plan on getting a Due as the Teensy 3.0 offers similar capability but in a MUCH smaller size and only costs $19. But, this update should also work with the Due in the basic non-timer interrupt methods.

The code you listed in your following post is similar to my development library for the non-8-bit ATmega microcontrollers. Instead of timer interrupt methods, pin interrupt should be the method of choice for the Due. I know for the Teensy 3.0 every pin can be an external pin interrupt, which makes it ULTRA convenient . I think the Due isn't quite as advanced in this area, which makes it a little more of an issue to implement, or will be somewhat limited.

You'll soon find that most advanced libraries won't work with the Due. Only simple libraries that don't do any lower-level commands will work. For size and speed, many libraries have adopted very specific 8 bit ATmega compatibility. So, expect to find many libraries that won't work with the Due.

Tim

Hi Tim.

Thanks for a great library!

I have a problem though that you might have some ideas on what I've done wrong.
When using your lib (v1.5) together with an Ethernet shield, I can't get 3 sensors to work properly.

E.g:

  • If I use 3 HC-SR04 sensors and a Mega 2560 with your example code with an sonar array, they all work fine, but if I just add an Ethernet shield to the Mega, 2 of the sensors give bad readings (like 4 cm instead of 90-150cm). The same wiring is used and no code is changed, just added the Ethernet shield (i.e. not messed with Timer2 and don't use the tone lib)

  • The Ethernet shield works, e.g. can just load other code (e.g. web server code, NTP client etc) without even removing the connected sensors and it works fine, i.e. it's not the Ethernet shield itself (have also tried with another Ethernet shield with same result)

  • I've stayed away from the 50-53 pins (used by Ethernet shield+HW ss pin) and the PWM pins. Currently using pin 30-35 (it's the middle HC-SR04 that gives OK readings when Ethernet shield is connected)

  • Tried with stuff like disabling SD SPI interface, pin 4, and setting pin 53 to output without any luck.

  • Using Arduino 1.0.2 IDE

Any ideas?

Thanks in advance!!
/Magnus

gandalf50:
Hi Tim.

Thanks for a great library!

I have a problem though that you might have some ideas on what I've done wrong.
When using your lib (v1.5) together with an Ethernet shield, I can't get 3 sensors to work properly.

E.g:

  • If I use 3 HC-SR04 sensors and a Mega 2560 with your example code with an sonar array, they all work fine, but if I just add an Ethernet shield to the Mega, 2 of the sensors give bad readings (like 4 cm instead of 90-150cm). The same wiring is used and no code is changed, just added the Ethernet shield (i.e. not messed with Timer2 and don't use the tone lib)

  • The Ethernet shield works, e.g. can just load other code (e.g. web server code, NTP client etc) without even removing the connected sensors and it works fine, i.e. it's not the Ethernet shield itself (have also tried with another Ethernet shield with same result)

  • I've stayed away from the 50-53 pins (used by Ethernet shield+HW ss pin) and the PWM pins. Currently using pin 30-35 (it's the middle HC-SR04 that gives OK readings when Ethernet shield is connected)

  • Tried with stuff like disabling SD SPI interface, pin 4, and setting pin 53 to output without any luck.

  • Using Arduino 1.0.2 IDE

Any ideas?

Thanks in advance!!
/Magnus

First, try using different pins for the sensors that are not working. It sounds like a conflict. If that doesn't work, you're going to need to provide some code so I know exactly how you're using NewPing. Not even sure what method of NewPing you're using, timer interrupt method or standard? At least part of the code would be helpful (maybe all of it).

Tim

Sounds good, I'll try some more with other pin configs.

I didn't provide the code since I have this problem with e.g. your example code with the sonar array and 3 sensors. I.e. your code with "This example code was used to successfully communicate with 15 ultrasonic sensors". Let me know if you still want the code (only updated the SONAR_NUM and objects in the sonar array).

Do you know if someone got multiple sensor working together with an Ethernet shield on the Mega 2560?

Brg,
/Magnus

gandalf50:
Sounds good, I'll try some more with other pin configs.

I didn't provide the code since I have this problem with e.g. your example code with the sonar array and 3 sensors. I.e. your code with "This example code was used to successfully communicate with 15 ultrasonic sensors". Let me know if you still want the code (only updated the SONAR_NUM and objects in the sonar array).

Do you know if someone got multiple sensor working together with an Ethernet shield on the Mega 2560?

Brg,
/Magnus

The code is always helpful, even if it's basically the same as the sample. I've seen several times that a little change was made and that was causing the problem.

Tim

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*_

gandalf50:
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:

#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

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

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...

oigres666:
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...

#define SONAR_NUM       4 // Number of sensors.

gandalf50:
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

cyclegadget:

oigres666:
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...

#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?? :cold_sweat:
Thank u!

oigres666:

cyclegadget:

oigres666:
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...

#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?? :cold_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

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: RGB Shield used to "output" range

Youtube of it running: HC-SR04 on a digispark w/ RGB shield - YouTube

rainierez:
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:

#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

teckel:

oigres666:

cyclegadget:

oigres666:
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...

#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?? :cold_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!!!

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:

#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!