Communication Between 2 Ultrasonic Sensors

Hello guys, I’m still a newbie when it comes to microcontrollers and sensors so I need all the help that I could get. Thanks in advance for your replies. :slight_smile:

So here’s the thing. I have 2 ultrasonic sensors attached to separate microcontrollers. Thing is I have desoldered the receiver on the other one and transmitter on the other so what’s left is only the receiver and transmitter (see attached photo). I want the transmitter to constantly send ping and the receiver to just listen to that ping so that I could measure the distance between them. However, with the codes I have tried (see attached file), I only get constant 0in,0cm and with the other setup I get constant 1335in, 400-ish cm values. Is there something I’m missing out? Are there codes in the newping I should try?

Thanks!

Ultrasonic.jpg

RX.doc (27 KB)

TX.doc (27 KB)

ultratx.doc (27 KB)

ultrarx.doc (28 KB)

The ping requires you to know when it left the transmitter, so that you can see how long it took to arrive at the receiver.

How does your second controller know when the transmitter started transmitting?

I haven't thought of that tho. Doesn't ultrasonic sensors work that way? When you transmit a pulse, automatically the receiver would process that pulse as to where it came from with the aid of the board. If not, then shall I do a slave/writer setup to overcome that problem?

Anyway here is the inspiration of this query: https://www.youtube.com/watch?v=GZAU9mYeDYA

When you transmit a pulse, automatically the receiver would process that pulse as to where it came from with the aid of the board.

No that is not how it works.

You need the transmitter to send another signal to say a pulse is on its way by radio or IR. Then you can time how long the sound takes to arrive after that.

Hi, Text under YouTube;

(Concept does require the Transmitter on the Receiver Ping to be manually removed.)

Also

I don't have to original source code, but the code used for this demo is pretty simple. I quickly wrote new examples that provide similar output.

I downloaded the code supplied and it does nothing like what is on the monitor screen. The code does nothing. In feedback the guy is keen to say what he did hardware wise, but nothing about software. So I'd say he was speaking out his...

Tom... :) Check this one from same weeb.. https://www.youtube.com/watch?v=r1hi8ZlbEEI

Grumpy_Mike:
You need the transmitter to send another signal to say a pulse is on its way by radio or IR.

Uh yeah, I meant from the transmitter :slight_smile: Sorry for that. Thanks btw

TomGeorge:
I downloaded the code supplied and it does nothing like what is on the monitor screen.

I did that too, I have the same setup as him however I get the pulseIn values such as these (see attached photo). He also claims that pulseIn means “how long the sound is heard for”. I think its working and the two are actually communicating since when I unplug the tx side the values I get is zero. Is there any way I could convert that “time” to distance?

yes.jpg

Hi,
OPs pic…
6c3435a7f47c7b933f97c5fa07ed26c82652a900.jpg
But that is nothing like in the you-tube, the code is not even structured for the display layout shown in the you-tube.

Move on…
Use one sonar unit and bounce off the object, you will save yourself a UNO as well.

Tom… :o :o :o

Felt like a savage there (you can actually post pic already HAHA)

Anyway, my project is for a bot to follow something attached to that transmitter side so I can't actually give up on this. Thanks btw sir :)

so I can't actually give up on this.

Unless you have two signals being sent, one fast and the other the ultra sound you can't do it. You can not measure the distance from the signal amplitude or duration.

He also claims that pulseIn means "how long the sound is heard for"

Yes it is, it is nothing to do with distance. To my mind he simply doesn't know what he is talking about because what ever he measures is not a function of distance. It looks like he got some results and was so pleased to get numbers he thought they meant something else and did not test it correctly or thoroughly enough. The clue is when he says he lost the original code, that marks him down as an idiot to begin with.

There are at least two problems with the scheme as presented in the youtube video.

1) As previous posters have noted, the receiver somehow needs to know when the transmitter pulse was sent to calculate the time of flight.

2) The unmodified receiver won't detect a ping unless it has sent one.

There is detailed information on how the HC-SR04 works at this link: http://uglyduck.ath.cx/ep/archive/2014/01/Making_a_better_HC_SR04_Echo_Locator.html

In this thread I wrote some notes on how I modified a pair of HC-SR04s to perform communication from one site to another. The modification involves tapping into the "signal" net so your Arduino can detect received signal without the microcontroller on the HC-SR04 getting in the way which addresses problem 2 above.

To get around problem 1 you could use a RF or IR link as suggested above or you could implement a round trip scheme where the "slave" platform transmits an ultrasound burst when it detects an incoming pulse. The master would send a pulse and time the interval until it receives a return pulse from the slave platform. It's probably more complicated than this because one has to account for the inevitable echos from any ultrasonic transmission.

PS. Of course a third problem with the video is that the code doesn't appear to implement anything like the video shows.

Thank you so much for your replies and pointing out the problems in this setup.

In efforts to learn more about this

MrMark: To get around problem 1 you could use a RF or IR link as suggested above or you could implement a round trip scheme where the "slave" platform transmits an ultrasound burst when it detects an incoming pulse.

I explored a lil bit and stumbled upon this project and it was also very similar to what I'm doing. My question now is how do you interface a RF module with such ultrasonic sensor to tell your receiver the time of flight?

dXmod: My question now is how do you interface a RF module with such ultrasonic sensor to tell your receiver the time of flight?

You don't: the RF and US receivers are both connected to the Arduino.

A little update on this one.

I have actually got the distance between the two ultrasonic sensors but it is in wired mode. However, given the circumstance that I need to do it wirelessly, I bought an additional 433Mhz RF modules. How do I do it? Thanks

Edit: Since I've referred to this thread for persons asking similar questions, note that this approach didn't work, see post #20 for working synchronization scheme . . .

The simplest scheme that comes to mind is to have the transmitter on for some period, turn it off and simultaneously send your ultrasonic ping. The receive side, of course measures the time between the RF off and the ultrasound ping detected. Appropriate parameters to start are something like 49 mS RF on/1 mS RF off with an ultrasound ping every 100 mS (10 pulses per second) on the falling edge of RF transmit.

The rational for this approach comes from the fact that the cheap 433 MHz receivers tend to output random garbage when no signal is present for more than a few milliseconds hence you need to transmit a signal to "capture" the receiver. By transmitting almost all the time, you suppress the random garbage and don't have to deal with it in software. The timing of the rising edge of the receiver output is going to be somewhat affected by the receiver gain control, so I'd expect the timing of the falling edge to be more predictable.

A drawback of this approach is that it only supports one transmit node, since it does not relinquish the RF channel.

Hi, Don't forget, this will only give you distance information, not direction.

Tom.... :)

Yeah sir, it's for distance purposes only.

If it's not too much to ask, can you give me a sample code for me to follow? Most of the cpdes I see does send a character. How can I get the ping simultaneously sent. I'm sorry I'm so new to this

Edit: Since I’ve referred to this thread for persons asking similar questions, note that this approach didn’t work, see post #20 for working synchronization scheme . . .

dXmod:
Most of the codes I see send a character. How can I get the ping simultaneously sent.

We can’t actually send the ping simultaneously, but we can send it immediately after the RF signal.

The common libraries do send characters or character strings, but for this application I think we just need “transmit on” and “transmit off” with the understanding that the ultrasound ping is sent at the transition from on to off. For that we just use digitalWrite() to send and digitalRead() to receive.

I’ve adapted, but not compiled or tested, the example code from the NewPing example to illustrate the idea as follows.

Transmit Node Code:

// Untested example code for the transmit node of one way ultrasonic ranging.
#include <NewPing.h>

#define TRIGGER_PIN  12
#define ECHO_PIN     11
#define RF_TX_PIN    8
#define MAX_DISTANCE 200

int pingTime;

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

void setup() {
  Serial.begin(115200);
  pinMode(RF_TX_PIN, OUTPUT);
  digitalWrite(RF_TX_PIN, HIGH);
}

void loop() {
  delay(50);                      // Wait (at least) 50 mS between pings
  digitalWrite(RF_TX_PIN, LOW);   // Stop transmitting RF to indicate TX is sending ping
  pingTime = sonar.ping();        // Send ping (will get a response, but TX doesn't use it)
  digitalWrite(RF_TX_PIN, HIGH);  // Start transmitting RF to indicate "idle" state
  Serial.println(pingTime);       // Print time just to show activity
}

Receive Node Code:

// Untested example code for the receive node of one way ultrasonic ranging.
#include <NewPing.h>

#define TRIGGER_PIN  12
#define ECHO_PIN     11
#define RF_RX_PIN    8
#define MAX_DISTANCE 200

int pingTime;

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

void setup() {
  Serial.begin(115200);
  pinMode(RF_RX_PIN, INPUT);
}

void loop() {
  if (digitalRead(RF_RX_PIN) == LOW)  // Wait for RF signal indicating ping sent from TX node
  {
    // RX node has Ultrasound transmit hardware disabled so doesn't send anything.
    // If RF synchronization is right, it should see the ping sent by the TX node
    pingTime = sonar.ping();
    Serial.println(pingTime);       // Print one-way transit time which should be proportional to range
  }
}

There’s an implicit assumption in this that the delays in “sonar.ping” are essentially the same for TX and RX node. Another unknown is the delay and delay uncertainty introduced by the RF link; my expectation is that this is no worse than a few hundred microseconds.

Hi,

I tried the code you have sent and made some modifications to it to the extent of my learning but still I get 0 as my values. In my wired setup tho, I did not use NewPing as my resource lib rather this:

        const int trigPin = 2;
    const int echoPin = 4;

    void setup() {
      // initialize serial communication:
      Serial.begin(9600);
    }

    void loop()
    {
      // establish variables for duration of the ping, 
      // and the distance result in inches and centimeters:
      long duration, inches, cm;

      // The sensor is triggered by a HIGH pulse of 10 or more microseconds.
      // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
      pinMode(trigPin, OUTPUT);
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);

      // Read the signal from the sensor: a HIGH pulse whose
      // duration is the time (in microseconds) from the sending
      // of the ping to the reception of its echo off of an object.
      pinMode(echoPin, INPUT);
      duration = pulseIn(echoPin, HIGH);

      // convert the time into a distance
      inches = microsecondsToInches(duration);
      cm = microsecondsToCentimeters(duration);
      
      Serial.print(inches);
      Serial.print("in, ");
      Serial.print(cm);
      Serial.print("cm");
      Serial.println();
      
      delay(220);
    }

    long microsecondsToInches(long microseconds)
    {
      // According to Parallax's datasheet for the PING))), there are
      // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
      // second).  This gives the distance travelled by the ping, outbound
      // and return, so we divide by 2 to get the distance of the obstacle.
      // See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
      return microseconds / 74 ;
    }

    long microsecondsToCentimeters(long microseconds)
    {
      // The speed of sound is 340 m/s or 29 microseconds per centimeter.
      // The ping travels out and back, so to find the distance of the
      // object we take half of the distance travelled.
      return microseconds / 29;
    }

What I did was just get the common pins trig, echo, vcc and gnd connected to each other. Also, I can't get an accurate data under 220 delay with this code.

I've breadboarded a proof of concept setup and have run into a problem with the 433 MHz synchronization scheme I proposed up thread. It seems that if the transmitter remains on most of the time, the receiver only outputs a high level for about 30 mS per my observations. Since the ping repetition interval is longer than that, the receiver has lost interest by the time the real sync pulse comes across.

This means we'll need a more sophisticated signaling scheme. I'll start with trying something like th Manchester library sync sequence, but don't have the time to do so at the moment. The scheme will be to send a sequence of fixed with pulses and trigger on the trailing edge of an extra wide pulse. On the sending side it would be sending a sequence like [0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1] at 500 uS intervals.

MrMark:
It seems that if the transmitter remains on most of the time, the receiver only outputs a high level for about 30 mS per my observations. Since the ping repetition interval is longer than that, the receiver has lost interest by the time the real sync pulse comes across.

Yes I think so too. Though I’m not familiar with the Manchester sync that you are saying.

I’ve found something that could help maybe, however, forget about the distance first and think about the time delay. Here: Make Your Suitcase Haul Itself Around with Robot Luggage! - YouTube (11:50 for the working principle)

Correct me if I’m wrong but what he did was to send a request first from the receiver side to the transmitter side. Upon receiving, the transmitter sends a ping and then measures the time delay.

Question is how did they do the timing? Would it be the same if I used RF instead of a zigbee module?