Manual mode/calibration

I’m trying to get the ping sonar to work with some manual conditions. When I hold the sonar about 1.5m away from the bottom of my water tank and turn on a small pump to get some movement, the sonar readings go from the accurate 1.5m to 9m (seen in the picture). I was given the suggestion of setting the Arduino code to manual and limiting the scan range. I’m not sure how to go between auto and manual mode. I’ve attached my Arduino UNO code that I’m using. Any help would be greatly appreciated. Once this issue is solved ill update this on any future problems.

#include "ping1d.h"
#include "SoftwareSerial.h"

//static const uint8_t arduinoRxPin = 19; //Serial1 rx WHITE   MEGA
//static const uint8_t arduinoTxPin = 18; //Serial1 tx GREEN   MEAG
static const uint8_t arduinoRxPin = 9; //Serial1 rx WHITE    UNO
static const uint8_t arduinoTxPin = 10; //Serial1 tx GREEN    UNO

SoftwareSerial Serialping = SoftwareSerial(arduinoRxPin, arduinoTxPin);
static Ping1D ping { Serialping };
static const uint8_t ledPin = 13;

void setup(){
  pinMode(ledPin, OUTPUT);
//  Serial.println("Blue Robotics ping1d-simple.ino");
  while (!ping.initialize()) {
    Serial.println("\nFailed to initialize!");
    Serial.println(" tx, green");
    Serial.println(" rx, white");
  ping.set_mode_auto(0);                   // manual mode (0) auto (1)
  Serial.print("Mode: ");
  ping.set_speed_of_sound(1500000);         // 1500000 water, 343000 air
  Serial.print("Speed of sound: ");
  ping.set_range(1000,600);              // scanable range start at 1000mm (1m) with a length of 600mm (.6m) and a max dist 1600mm (1.6m)
  Serial.print("Scanable range start: ");
  Serial.print("Scanable range length: ");
  ping.set_ping_interval(1000);            // delay between pulses 1000ms = 1s
  Serial.print("Ping interval: ");

void loop(){
  if (ping.update()) {
    Serial.print("Distance: ");
    Serial.print("\tConfidence: ");
  } else {
    Serial.println("No update received!");
  // Toggle the LED to show that the program is running
  digitalWrite(ledPin, !digitalRead(ledPin));

Hi @mhg2000, welcome to the forum :slight_smile:

I believe your code is correct for setting the device to manual mode, but you’ll also want to send the set_range message to specify the distance range you want to limit the scans to :slight_smile:

I’ve copied the contents of your text file into a code block, so the code is visible directly in the post. You can read more about that in the Formatting a Post/Comment section of the “How to Use the Blue Robotics Forums” post :slight_smile:

I’m using the ping.set_range(1000,600) but it doesn’t seem to respond to this. I’ve also tried changing the speed of sound setting to air and I’m still not getting any positive readings. Also, how do you reset the settings after you applied the Arduino code? I thought manual would allow any changes and auto you couldn’t

Apologies - not sure why I didn’t see that in your original post.

I’ve just run a couple of tests and there’s apparently a minimum scan_length of 1000mm. Try using ping.set_range(1000, 1000), or ping.set_range(600, 1000), or ping.set_range(800, 1000) (depending on which direction you’d prefer the extra range to be searched) :slight_smile:

I’ve made a pull request here to update that description in the protocol docs, so it’s clearer in future, although there’s some possibility that limit isn’t intended to be implemented the way it is in the firmware, in which case we might update the firmware instead.

Note that if a command isn’t working it should be sending back a nack, which should have a message in it that should help explain why the command didn’t work (in this case the message is “range too short”).

The settings get set to default values when the Ping starts up. If you’re talking about keeping it powered then I suppose if you wanted to you could write an Arduino program that saves the current settings before it runs, and then restores them again at the end, but otherwise it will just keep the settings until next time you change them (or until the Ping restarts).

As per the protocol specification, manual mode allows manually setting the gain and the scan range, whereas auto mode sets those values automatically. All the other values are already set manually.

Following up on this, that has now been merged, so the protocol docs are updated to specify the minimum length of 1000mm :slight_smile:

I’ve done the range edits but I think my gain is now having an issue. As I start my pump to circulate water in my tank (keeping it at a constant 1.3 m) I get the correct reading of where I have my sensor placed. About a couple of minutes later my values start to drop off and the reported confidence interval decreases (attached picture). The red line is where the values start to drop off. Even when I stop the pump so water returns to a still state the incorrect values continue and do not recover.

I’m not sure why this would happen, unless after a couple of minutes the tank water reaches an equilibrium with the pump and starts flowing differently, which may affect the signal echoes around the tank or something.

Is it possible to connect the Ping to a computer, and view the live profile with Ping Viewer? That could help show if the signal is poor/noisy, and would also help determine the best gain setting for the different water conditions it needs to operate in.

From your screenshot it seems like the distance values at the end are in fact going back down - do you have a longer sample?

More generally, if I’ve understood correctly you mentioned that the sensor is at 1.3m, but your distance results are showing 1.1m-1.2m. I’m curious,

  • is your current setup different to what was the case when you took the screenshot, or
  • is the sensor just actually at more like the distances being measured, or
  • is the thing you’re measuring distance to a soft material, or curved shape, or
  • is your speed of sound just set incorrectly for the water you’re measuring in?

I’ve got it working better but I’m trying to adjust the gain setting and before the Arduino library had an update the function I was using was “ping.set_gain_index(#)” after the update no longer works. What is the changed gain setting message?

Assuming you’re talking about the very recent update to the library, we didn’t realise there were some un-tested changes in there so it’s currently not working. If the other changes have helped solve some issues for you then it may be worth correcting the names manually like this person did, but otherwise we’d recommend sticking with 0.0.2 while we properly fix the issues with the new version.

Alternatively you could switch to using ping-cpp, although that requires implementing the relevant bindings for Arduino, as discussed here.