MKR 1010 and A02YYUW Waterproof Ultrasonic Sensor

Hello trying to use the ultrasonic sensor.

I have MKR 1010 wifi that has (?) UART in 13 and 14 and I can access I guess with serial1.

So I simply connect to 13 and 14 the RX and TX (and of course I give 3.3VDC (tried 5VDC too) and GND.

I get no sane results. When you read it is 4 bytes, first FF, then two values and last one is checksum. So here is the code but I get nonsense…

I open the serial1 with 9600 BAUD and the below is part of HTTP server thats why I print with client.print

do{

         for(int i=0;i<4;i++)

            {

               data\[i\]=Serial1.read();

               client.println(data\[i\]);

            }

        }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)

                {

                   client.print("distance=");

                   client.print(distance/10);

                   client.println("cm");

                }else 

                {

                   client.println("Below the lower limit");

                }

         }else client.println("ERROR");

Output is somthing like this

255 255 9 163 ERROR

255 9 163 171 9 255 9 163

Any ideas?

Please post complete code that compiles, runs and demonstrates the problem. Copy/paste directly from the IDE.

There are far too many errors in the snippet you posted. Where do all those backslash characters come from?

1 Like

The output is sort of OK.

You are getting FF, two values, 9 and 163 and 171, which is almost the checksum 172.

I've no idea if 9 and 163 are right or not.

doing a quick calculation I get (255+9+163)&0xff=0xAB or 171 decimal

maybe worth printing HEX as well as decimal values
post the full code!

make sure your Serial monitor baudrate is faster than the Serial1 - I always use 115200

/*
  My Program

 */

#include <SPI.h>
#include <WiFiNINA.h>
#include <Ultrasonic.h>
#include <Wire.h>

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = "";        // your network SSID (name)
char pass[] = "";    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;                 // your network key index number (needed only for WEP)
int status = WL_IDLE_STATUS;

unsigned char data[4]={};
float distance;
// define ultrasonic ranger data pin
#define RANGERPIN   3
// initialize ultrasonic library
Ultrasonic ultrasonic(RANGERPIN);

WiFiServer server(80);

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(19200);
  Serial1.begin(9600);
 // while (!Serial) {
//    ; // wait for serial port to connect. Needed for native USB port only
//  }

  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println(fv);
    Serial.println(WIFI_FIRMWARE_LATEST_VERSION);
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);

    // wait 5 seconds for connection:
    delay(5000);
  }
  server.begin();
  // you're connected now, so print out the status:
  printWifiStatus();

  
}


void loop() {

  char _buffer[7];
  int centimeters;
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("Reconnecting to WiFi...");
    WiFi.disconnect();
    WiFi.begin(ssid, pass);
    delay(5000); 
  }
  // listen for incoming clients
  WiFiClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an HTTP request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the HTTP request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard HTTP response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          client.println("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          //read the pushbutton value into a variable
          //int sensorVal = digitalRead(3);
          //print out the value of the pushbutton
          //client.println(sensorVal);
          // get distance in centimeters
          //centimeters = ultrasonic.MeasureInCentimeters();
          do{
             for(int i=0;i<4;i++)
                {
                   data[i]=Serial1.read();
                   client.println(data[i]);
                }
            }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)
                    {
                       client.print("distance=");
                       client.print(distance/10);
                       client.println("cm");
                    }else 
                    {
                       client.println("Below the lower limit");
                    }
             }else client.println("ERROR");
     }
         // client.print("Distance is: ");
         // client.print(distance);//0~400cm
         // client.println(" cm");
         // client.println("</html>");
          break;
         
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1000);

    // close the connection:
    client.stop();
    Serial.println("client disconnected");
  }
}


void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

interesting to know that checksum computes. Maybe then the rest of the code doesn’t proceed correct, when it reads the values, becuase when 1st byte is 0xFF it double prints output. However when it has two times the 0xFF it outputs the ERROR. The output is on browser whn I hit the IP, so maybe serial doesnt matter.

Utrasonic.h is there because I have also tried other ultrasonic sensor with similar code tha works (but it doesnt need UART but only pin 3)

you reading bytes at 9600 baud and printing textual information at 19200baud
you are probably overrunning the Serial1 input buffers and loosing information
try

  Serial.begin(115200);
  Serial1.begin(9600);

Did it but same. It is interesting that when first byte is 0XFF then we get two sets of values like this:

255 9 170 178 9 170 178 255. Does the do/while works? I took it from DFRobot site but should it work? And while does one more read?

(255+9+170)&0xFF= B2 or 178 decimal
looks like you are missing the following 255 or 0xFF

I would suggest you simplify your program
remove all the WiFi code and concentrate on getting reading the sensor data correct

Thanx for help so far. I ll try to concentrate to the read code, no need to remove the other code, it works with other sensor brand. I think the loop is wrong. in order to test the while loop needs to read till 0xFF, so it adds one more read.

I am not sure what serial1.flush does there, since it seems to work as an OUT statement, I don’t get it.

I think I ll just scan for 0xFF, then read next 3 bytes and just go for evaluation. I am not a programmer but I manage in the end :slight_smile: It was great help you saw that actually checksum adds, somehow I thought it way off (without calculating… )

HI it works now. One problem I have is that changes in distance are really really slow… It takes upto 2 minutes for the change to be shown in the program… It would be nice to know any ideas on this but I could possibly use it that way, I want to measure my oil tank. I double checked and read of the serial1 happens every on second.

EDIT: I think I need somehow to clear the UART buffer before reading. Any ideas?