Connecting Arduino Nano 33 IoT with a02yyuw (serial issues)

When I try to connect the a02yyuw (ultrasonic waterproof sensor) to my Nano 33 IoT it does not seem to work properly.

This is the code: unsigned char data[4]={};
float distance;

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

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

  Serial1.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 
             {
               
             }
      }else { 
        Serial.println("Error");
}
     }
     delay(100);
}

It seems like a big topic of discussion was using Serial1 as opposed to the SoftwareSerial.h library which is not available for the Nano 33 IoT. Even from all of this it does not seem to work. Does anyone have advice on where to go from here? I also wanted to note that I am using the RX TX pins (1 and 0 respectively) and everything else is connected properly I think (5V to D22 and GND)

What does work properly mean?

sorry, it simply means that it does not work as intended (i.e., prints "error")

Based on the data format specified in A02YYUW Waterproof Ultrasonic Sensor Wiki - DFRobot, I would first read data till you find 0xFF. I also think that your code is based on that link.

Once you have the 0xFF in the first data byte, you can populate the remainder of the data array with the data that you receive.

Once you have received 4 data bytes, you can verify the checksum and when the checksum matches you can calculate the distance and print it.

unsigned char data[4] = {};
int16_t distance;

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

void loop()
{
  // keep track of number of received bytes
  static uint8_t messageIndex;

  // if there is data
  if (Serial1.available())
  {
    // read and store
    data[messageIndex] = Serial1.read();

    // debug
    Serial.print(F("Got "));
    if (data[messageIndex] < 0x10)
    {
      Serial.println(F("0"));
    }
    Serial.println(data[messageIndex]);

    // wait till we get have the header byte before incrementing the index
    if (data[0] == 0xFF)
    {
      messageIndex++;
    }
  }

  // if we got 4 bytes
  if (messageIndex == sizeof(data))
  {
    // calculate checksum
    int sum = (data[0] + data[1] + data[2]) & 0x00FF;

    // verify checksum
    if (sum == data[3])
    {
      distance = (data[1] << 8) + data[2];
      Serial.print(F("Calculated distance = "));
      Serial.println(distance);
    }
    else
    {
      Serial.println(F("Checksum error"));
    }

    // clear the data
    memset(data, 0, sizeof(data));
  }
}

I'm not 100% sure where your code goes wrong, I think it's the while-loop because it does a read() and throws the 0xFF away.

There also seems to be a bug in the code. distance is declared as a float and a float is 4 bytes. In the above code I have declared it as an 16-bit integer.

If the above does not work, you can run the below sketch which will simply print received bytes and provides the timing. Post the output here.

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

void loop()
{
  static int cnt;

  if (Serial1.available())
  {
    Serial.print(millis());
    Serial.print(F("\t"));
    byte b = Serial1.read();
    if (b < 0x10)
    {
      Serial.print(F("0"));
    }
    Serial.println(b);

    cnt++;
  }

//  if (cnt >= 25)
//  {
//    for (;;) {}
//  }
}

If you're using IDE 2.x, you can enable the commented lines at the end so you only get 25 lines. For IDE 2.x, make the serial monitor as big as possible to make it easier to copy (disable scrolling will also help).

I can not test as I need to setup a second Arduino to simulate your sensor. Both codes do compile.

Thank you for your help, but it still does not seem to work. A big issue seems to lie in the fact that condition Serial1.available() does not return true for some reason. I test it against an else statement which prints out. Do you know why this may be? At first I thought it was an issue with the sensor, but it worked with a test arduino uno. Could this be something with the board? Do you know if there is any way to test if the serial ports work? Thanks

Possibly wiring issue. Please draw a wiring diagram and post it here.

The below will test if Serial1 works. Disconnect the sensor and connect Rx and Tx on the Nano33 IoT together. Run the following sketch

void setup()
{
  Serial.begin(57600);
  Serial1.begin(9600);

}

void loop()
{
  if(Serial.available())
  {
    Serial1.write(Serial.read());
  }


  if(Serial1.available())
  {
    Serial.write(Serial1.read());
  }
}

In serial monitor, type something. What you typed should be echoed back to the serial monitor.

Here is the wiring that I followed:



Not sure how helpful the picture is but the blue wire is located at the RX0, Green is on the pin labelled TX1, Red is on the 5V (according to the nanos pinout on the website), and the black is on GND
Also, i tested the code that you gave to test the serial ports and they worked!

The blue wire is the Rx of the sensor and needs to be connected to the Tx of the Arduino; the green wire is the Tx of the sensor and needs to be connected to the Rx of the Arduino.

Your sensor can be powered with 5V or 3.3V. If you power it with 5V its Tx signal will more than likely be 5V as well which can damage the Nano. Power it with 3.3V.