2

Problem

I've been trying to a create a receiver and transmitter beacon for a following robot, but have not been able to sync my two SRF02s to one another.

Any advice?

Code

#include <SoftwareSerial.h>  
SoftwareSerial mySerial(10,11); // RX, TX 

void SendCmd(unsigned char address,unsigned char cmd)
{
  mySerial.write(address);//set the address of SRF02(factory default is 0) 
  mySerial.write(cmd);//send the command to SRF02
}
void setup(void)
{
  Serial.begin(9600);
  mySerial.begin(9600);
  Serial.println("SRF02 TEST!");
}
void loop(void)
{
  unsigned long t3;
  unsigned long t1=micros();//time tx command issued
  SendCmd(1, 0x5C);//send pulse with transmitter
  unsigned long t2=micros();//time rx command issued
  SendCmd(2, 0x5B);//listen for pulse returns results in microsconds





 while(mySerial.available() < 2)//if two bytes were received
  {}
    t3 = mySerial.read()<<8;//receive high byte (overwrites previous reading) and shift high byte to be high 8 bits
    t3 |= mySerial.read();// receive low byte as lower 8 bits
    unsigned long Tm = t3 + t2 - t1;//total amt of microseconds between pulse and reading
    unsigned long Dist = (Tm/29); //converting microseconds to cm
    Serial.print(t3); // print the reading
    Serial.println("cm");
    //Serial.print(tm);
    //Serial.println("ms");


  delay(250); // wait to read the output 



}

Output#

enter image description here

3
  • Your distances seem implausible, so you need to investigate. Try printing out the components of the delay, both measured on the Arduino and on the sensor. Also consider that sound will travel a fair fraction of a meter during the time it takes to send the second command, and see if the software serial output routines buffer or block until the data is actually sent. Preferably, for precise timing you should use discrete strobe signals and hardware timers, not serial commands and software., Nov 28, 2015 at 22:53
  • 1
    How far apart are your 2 SRF02's? Also, when debugging print the data in a raw form as well as (or instead of) processed -- ie, print out t1, t2, t3 as well as Dist Nov 29, 2015 at 0:57
  • theyre roughly 15 cm apart
    – Umbus
    Nov 29, 2015 at 1:32

2 Answers 2

1

theyre roughly 15 cm apart

15cm substantially less than the time it takes to send the second device its command at 9600 baud (2 bytes, probably 20 bits counting framing, around 72 cm)

As a result you are likely missing the pulse, and perhaps catching some timeout, or even a cached response string from a next-to previous command which measured the previous pulse, including the time between pulses.

To operate that close, you will need to either use dedicated trigger/detect wires, or start the receiver before you transmit and try to subtract the delay from the time you started the receiver until the time when you transmit.

Beware that usage of software serial, as well as buffering of serial in general may introduce variable latency in your timestamping of the serial communications. Ideally for something like this you would use a non-buffered implementation - the timing of serial data itself is potentially precise to a fraction of the baud rate, though we don't know how it is implemented on the sensor end.

1
  • void setup() { //Choose 9600 baudrate Serial.begin(9600); } int x; //Byte int n; //Number of available bytes void loop() { //Address Serial.write(2); //calls address of srf02 - 0x02 Serial.write(0x51); //Send Pulse from 0x00 - no ranging takes place n = Serial.available(); if(n > 0){ for (int i = 0 ; i < n; i++){ unsigned long x = Serial.read(); Serial.print(x,DEC); } Serial.println(); } delay(1000); } This is another code with just serial.writes. do you think i'm better off implementing something like this?
    – Umbus
    Nov 29, 2015 at 4:19
1

I don't think what you are trying to do is possible with those modules.

I think what you are trying to do is transmit a 40KHz pulse on one module and find out when it arrives at the other module. Unfortunately that is not going to be possible with serially attached modules - simply because it takes longer to transfer the serial data than it does for the ultrasound pulse to travel between the two modules. That's why you're seeing such big values - you're actually measuring the amount of time it takes to transfer the serial data, not the sound.

For those modules to work they have to transmit a pulse themselves and then listen for that pulse and they return the difference between those two events. The timing for that is all done internally to the module and the results are returned through serial. Trying to perform the individual operations through serial is just not going to happen.

A better solution would be to modify an HC-SR04 module. De-solder the transmitter from the board and re-connect it with some wires - that is then your remote module. You can do the same with the receiver module if you want it remote from the board if you like. Then you interface the HC-SR04 direct to the Arduino and use it as you normally would.


Edit:

Ok, so it seems there is a method of using them (AKA "Fake" sensing - idiotic name if ever there was one) that could be made to work if it's done precisely right.

However, doing it precisely right, as you have seen, is not easy. Timing is critical. Timing of when you send instructions, and how you determine exactly when an instruction has been sent.

You would be much better off using a real hardware UART than software serial. That would mean upgrading your board to one with more than one hardware UART since you are using the only one the Uno has for your serial monitor.

I would also recommend not using the Arduino's Serial object(s) for this since they impose their own buffering and asynchronous transfer of data which will really really mess with your timing. Instead you should manually manipulate the registers directly - that way you can know exactly when the final bit of the serial commands have reached the ultrasound module.

You should also send the command to the receiver first before the transmitter. Did you know that at 9600 baud it takes about 2ms to transfer two bytes? In that time sound will have travelled about 68cm. If you start the receiver first then start the transmitter the receiver will be running when the sound wave reaches it, as opposed to when the sound wave is somewhere in the next room. Then of course you have to take into account the time between starting the two properly, and that all comes back down to knowing your timing exactly.

5
  • So what you're saying is that I would have to create a continuously pulsing transmitter at 40KHz and use the receivers in their standard mode? If that is the case am I covering the transmitting transducers on the receiver modules, but still sending a pulse to time the events between sending and receiving?
    – Umbus
    Nov 28, 2015 at 23:42
  • Actually this is not true. I suspect it as well, but a quick lookup of the parts suggests that bistatic operation is a supported usage mode. I join your concern about the latency of serial communication, but while suboptimal there are perhaps ways of working around it, for example starting the receiver first and determining a (with care potentially fairly constant) serial message delay to subtract. Nov 28, 2015 at 23:53
  • @ChrisStratton I see what the "Fake" mode does now. That's really an incredibly stupid thing to call it...! So yes, it could be possible if you do it absolutely perfectly correctly and time everything precisely. Far from ideal though, especially on an Arduino that has so many variables - you'd be best off a) using a hardware UART, and b) not using the Arduino's Serial object with its asynchronous transmission.
    – Majenko
    Nov 29, 2015 at 0:02
  • Probably better to use I2C instead of Serial. However, note that error due to Serial latency should be less than 70 cm (the distance sound travels in the time taken to transmit 2 Serial bytes at 9600 bps), but the data shown varies rather more than that; and anyhow, variability due to that latency ought to be negligible, so it seems to me Serial latency isn't likely to be the problem, but something else. Nov 29, 2015 at 1:06
  • But if i want to make a wirelss receiver and transmitter beacon, I am not able to used I2C correct?
    – Umbus
    Nov 29, 2015 at 1:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.