A02YYUW distance sensor reliability problems

Hi everybody,

Iam using 2 of the mentioned A02YYUW ultrasonic distance sensors.
They are currently connected via this I2C to dual UART board attached to an Arduino Mega R3, but I had the same problems with Serial/SoftwareSerial as well.

Iam getting good looking data but then for multiple seconds at a time the sensors will send garbage data. It happens with both of them, sometimes at the same time.

Now my wiring is all positively affixed and it happens when everything is laying still. The sensors are supplied with 5v from the Arduino, which is supplied by a 6s Lipo and a DC to DC Voltage Converter to 5V.
So there is enough current and the correct voltage.

My sketch is slightly changed version of the linked DFRobot-Wiki version.
Here is the part responsible for one of the sensors, the other is of course the same just with the different serial interface.
I already added the extra debug output of the 4 bytes.
Data should look like this:
Header has to have 255, then the measurement, then checksum.

 do {
    for (int i = 0; i < 4; i++) {
      sonarDataLinks[i] = iicSerial1.read();
    }
    Serial.print("Data Left: ");

    Serial.print(sonarDataLinks[0]);
    Serial.print(sonarDataLinks[1]);
    Serial.print(sonarDataLinks[2]);
    Serial.println(sonarDataLinks[3]);

  } while (iicSerial1.read() == 0xff);
  iicSerial1.flush();
 if (sonarDataLinks[0] == 0xff) {
    int sum;
    sum = (sonarDataLinks[0] + sonarDataLinks[1] + sonarDataLinks[2]) & 0x00FF;
    if (sum == sonarDataLinks[3]) {
      sonarHeightLinks = (sonarDataLinks[1] << 8) + sonarDataLinks[2];
      Serial.println(sonarHeightLinks);
    }
    Serial.print("error L");

instead of measurements i get multiple seconds of this:

16:43:51.209 -> Data Right: 0000
16:43:51.332 -> Data Left: 0000
16:43:51.332 -> Data Right: 0000
16:43:51.473 -> Data Left: 0000
16:43:51.473 -> Data Right: 0000
16:43:51.552 -> Data Left: 0000
16:43:51.552 -> Data Right: 0000
16:43:51.691 -> Data Left: 0000
16:43:51.691 -> Data Right: 0000
16:43:51.816 -> Data Left: 0000
16:43:51.816 -> Data Right: 0000

and this:

16:43:52.523 -> Data Left: 84653255
16:43:52.565 -> Data Right: 84653255
16:43:52.565 -> Data Right: 84653255
16:43:52.646 -> Data Left: 46532558
16:43:52.690 -> Data Right: 46532558
16:43:52.777 -> Data Left: 5325580
16:43:52.777 -> Data Right: 5325580
16:43:52.895 -> Data Left: 0532558

and then somtimes correct data:

16:45:27.279 -> Data Right: 25585057
16:45:27.279 -> distance - 2098.00
16:45:27.418 -> Data Right: 25585057
16:45:27.418 -> distance - 2098.00

I dont know what my next step is, so Iam looking for ideas to solve this issue, I cant really believe both sensors are broken. I dont see an issue with the software because it even happens with the DFR sketch and the cabling/connection are all solid.

Just to combat the idea that the problem is the rest of my sketch that i didnt post, here is the result with the reference DFRobot sketch:

17:07:51.388 -> distance=209.90cm
17:07:51.495 -> distance=209.90cm
17:07:51.630 -> distance=209.90cm
17:07:51.712 -> distance=209.90cm
17:07:51.849 -> distance=209.90cm
17:07:51.927 -> distance=209.90cm
17:07:57.400 -> distance=209.50cm       // 
17:08:02.296 -> ERROR                             //    <-- 5 second delay! 
17:08:06.162 -> distance=209.50cm      // 
17:08:06.275 -> distance=209.50cm
17:08:06.400 -> distance=209.50cm
17:08:06.486 -> distance=209.50cm
17:08:06.592 -> distance=209.50cm

the 5 second delay comes because there is no data byte that looks like the expected header for the entire time so its not reaching any Serial.print.
Same result using that on an Arduino Uno with software serial.

Post your complete sketch, a wiring diagram, and a brief description of the operation.

Make a sketch that only prints the sensor output without calculations. Data errors can be caused by calculations with a zero in a denominator or multiplier, reading the wrong pin, assuming a pins output... and more.

Sketch is linked but here:

/*
  *@File  : DFRobot_Distance_A02.ino 
  *@Brief : This example use A02YYUW ultrasonic sensor to measure distance
  *         With initialization completed, We can get distance value 
  *@Copyright [DFRobot](https://www.dfrobot.com),2016         
  *           GUN Lesser General Pulic License
  *@version V1.0           
  *@data  2019-8-28
*/

#include <SoftwareSerial.h>

SoftwareSerial mySerial(11,10); // RX, TX
unsigned char data[4]={};
float distance;

void setup()
{
 Serial.begin(57600);
 mySerial.begin(9600); 
}

void loop()
{
    do{
     for(int i=0;i<4;i++)
     {
       data[i]=mySerial.read();
     }
  }while(mySerial.read()==0xff);

  mySerial.flush();

  if(data[0]==0xff)
    {
      int sum;
      sum=(data[0]+data[1]+data[2])&0x00FF;
      if(sum==data[3])
      {
        distance=(data[1]<<8)+data[2];
        if(distance>30)
          {
           Serial.print("distance=");
           Serial.print(distance/10);
           Serial.println("cm");
          }else 
             {
               Serial.println("Below the lower limit");
             }
      }else Serial.println("ERROR");
     }
     delay(100);
}

There i nothing to the wiring, the errors also occur if I supply the arduino via USB, I2C UART adapter is on 5v and the Ultrasonic Sensor too, SDA/SCL to the adapter, RX/TX from Sensor on RX/TX on adapter.

If the wiring was wrong I could not get data.

Show a wiring diagram.

If found the problem and also a solution, to everyone finding this in the future having problems with the A02 Sensor: The solution on DFRobot is bad, as you can see the header data (255) is in the data but not in the correct position. Instead of shifting it to the left or right they read again and again, always running in the same error until it gets corrected by accident, which can take a long time.

I then found a library for the sensor in wich the implementation is so bad that it takes 200ms to read a value out of 4bytes.

I now implemented my own solution which accounts for misaligned header data, is shorter than using the library and also 195ms faster.

  if (iicSerial1.available() > 3 && iicSerial1.peek() == 0xff) {
    for (int i = 0; i < 4; i++) {
      data[i] = iicSerial1.read();
    }
    height = (data[1] << 8) + data[2];
  } else if (iicSerial1.available() > 3 && iicSerial1.peek() != 0xff) {
    iicSerial1.read();
  }

You only read from serial if there are 4Bytes available (Header Data Data Checksum), also you check if the header is actually in the right position, if thats not the case you consume unusable bytes in the else if branch.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.