A02YUWW sensor for speed measurement

You can remove most serial prints; they are mostly there to show you what is happening and what is measured.

For just the measuring, I would keep it as is and only adjust how often it is updated. How often do you want to the speed to be displayed in the serial monitor? Every second?

Thinking about it, have look how the timeout is implemented in the receive routine.

Every time that something happens (a byte is received) a 'timer' is updated. When a byte isn't received in time, action is taken.

For the updating of serial monitor, you can use the same principle. Only difference is that the "something happens" is when it's time to update the serial monitor. The action in this case will be the sending of the data and the update of the 'timer'.

It will look something like

if millis - last display update time greater than update interval
  send speed
  set last update time to millis

Implement it after you calculated the speed.

Give it a try, let us know if you don't get it right.

I tried to use the code but couldn't write it properly so after sometime showing checksum error

When I used the code you used in your Arduino the serial monitor is printing gibberish though I have set the baud rate accurately in serial monitor

Show your code. I have no idea what you have done.

That contradicts post #23.

That code is a simulator for your sensor. It does not print to serial monitor.

It reacts on the status change of the reading of the sensor.

If it was not implemented like that, you would see something like

Waiting
Waiting
Waiting
In progress
In progress 
In progress 
Complete
Waiting
Waiting
In progress
In progress 
In progress 
Complete
...
...
Waiting
Waiting
In progress
In progress 
In progress 
Complete
...
...
Waiting
Waiting
In progress
In progress 
In progress 
Complete
...
...

You will still get data from your sensor and every time a packet is received it will print the speed.

Can I write that code before printing serial monitor speed and distance

If distance= lastdistance;
{
break;
else
Serial.print("\tDistance=");
Serial.ptint(distance)
}

Something like that, yes.

break is used in for-loops and while-loops; there were no loops in my code so it will not work in my code.

There should not be a semicolon after an if.

= is an assignment; to compare, use ==. There is also not equal, !=.

With that in mind

if (distance != lastdistance)
{
  Serial.print((F"\tDistance="));
  Serial.println(distance)
}

now it is not showing speed and distance even I move the object, well tell me one thing if i wanted to display the distance and speed in a 16x2 lcd will it spam in every 10ms?
My original plan is to feed the speed and distance to a lcd panel in every 1 second and when speed is high than a certain amount it will blink an led.

As I do not know how you changed it, I don't know what is wrong. Please post YOUR full code.

Something like that yes, unless you get that compare sorted. Or use a millis() based approach as suggested if you want to display every second.

We have power failures galore in the area at the moment (over 12 hours already) so can't be of much help at this stage.

// Include the Software Serial library
#include <SoftwareSerial.h>

// Define connections to sensor
int pinRX = 10;
int pinTX = 11;

// Array to store incoming serial data
const uint8_t messageSize = 4;
unsigned char data_buffer[messageSize];
const unsigned long eventinterval = 1000;
unsigned long previoustime=0;

// Integer to store distance
int distance = 0;
int lastDistance = 0;

// Object to represent software serial port
SoftwareSerial mySerial(pinRX, pinTX);
// for sterretje's setup, comment out above and uncomment below
//#define mySerial Serial1

// receive timeout
const uint32_t a02yuwwTimeout = 400;
// header byte
const uint8_t headerByte = 0xff;
// possible results of a02yuww receive function
enum class RECEIVERESULT
{
  COMPLETE,    // data available
  WAITING,     // wait for header
  INPROGRESS,  // receive in progress (header received but not yet required number of bytes)
  CSERROR,     // checksum error
  TIMEOUT,     // timeout
};

void setup()
{
  // Set up serial monitor
  Serial.begin(115200);
  // Set up software serial port
  mySerial.begin(9600);
}


void loop()
{
  unsigned long currenttime= millis();
  // remember previous result of readSensor
  static RECEIVERESULT lastRR;
  // remember last time that we succesfully received a packet
  static uint32_t lastTime;

  // read the a02yuww sensor
  RECEIVERESULT rr = readSensor();
  // if there was a change in the result
  if (rr != lastRR)
  {
    printReceiveResult(rr);
  }
  lastRR = rr;
  if (rr == RECEIVERESULT::COMPLETE)
  {
    // time that data was received
    uint32_t receivedTime = millis();

    // print the received data
    printData();

    // calculate distance
    distance = (data_buffer[1] << 8) + data_buffer[2];
    
    if(currenttime - previoustime >= eventinterval)
    {
    Serial.print(F("\tDistance = "));
    Serial.print(distance);
    previoustime=currenttime;
    }
   

  

    // at overflow of the timing (49 days)
    if (receivedTime < lastTime)
    {
      Serial.println(F("Timing overflow; packet ignored"));
    }
    else
    {
      long speed = (distance - lastDistance) * 1000L / (long)(receivedTime - lastTime);
    
       if(currenttime - previoustime >= eventinterval)
    {
      Serial.print(F("\tSpeed = "));
      Serial.println(speed);
      previoustime=currenttime;
      
    }
    lastDistance = distance;
    lastTime = receivedTime;
  }
  }
}
/*
  read a02yuww sensor
  Returns:
    receive status (RECEIVERESULT)
*/
RECEIVERESULT readSensor()
{
  // flag to indicate if header byte was received
  static bool receiveInProgress = false;
  // where to store received byte
  static uint8_t index = 0;
  // time that last byte was received
  static uint32_t lastReceivedTime;

  // clear the buffer if we haven't received the header byte
  if (receiveInProgress == false)
  {
    memset(data_buffer, 0, sizeof(data_buffer));
  }

  // if there is no sensor byte
  if (mySerial.available() == 0)
  {
    // indicate that we don't have a reading yet
    if (receiveInProgress == false)
    {
      return RECEIVERESULT::WAITING;
    }
    else
    {
      // if we did not get the next byte in time
      if (millis() - lastReceivedTime > a02yuwwTimeout)
      {
        // reset local variables
        receiveInProgress = false;
        index = 0;
        return RECEIVERESULT::TIMEOUT;
      }
      else
      {
        return RECEIVERESULT::INPROGRESS;
      }
    }
  }

  // read an available byte and store in buffer
  data_buffer[index++] = mySerial.read();
  lastReceivedTime = millis();

  // check for packet header character 0xff
  if (receiveInProgress == false)
  {
    if (data_buffer[0] == headerByte)
    {
      // indicate that we've got the header byte
      receiveInProgress = true;
      return RECEIVERESULT::INPROGRESS;
    }

    // reset index if it was not the header byte
    index = 0;
    return RECEIVERESULT::WAITING;
  }

  // if we're waiting for the other bytes
  if (receiveInProgress == true)
  {
    // if we haven't received all bytes yet
    if (index == messageSize)
    {
      // clear local variables
      index = 0;
      receiveInProgress = false;

      // calculate checksum
      uint8_t cs = data_buffer[0] + data_buffer[1] + data_buffer[2];
      // if checksum is valid
      if (data_buffer[3] == cs)
      {
        return RECEIVERESULT::COMPLETE;
      }
      else
      {
        return RECEIVERESULT::CSERROR;
      }
    }
    else
    {
      return RECEIVERESULT::INPROGRESS;
    }
  }
  return RECEIVERESULT::WAITING;
}

/*
  print human readible RECEIVERESULT
  In:
    receive result
*/
void printReceiveResult(RECEIVERESULT r)
{
  switch (r)
  {
    case RECEIVERESULT::COMPLETE:
      Serial.println(F("Complete"));
      break;
    case RECEIVERESULT::WAITING:
      Serial.println(F("Waiting for header"));
      break;
    case RECEIVERESULT::INPROGRESS:
      Serial.println(F("Receive in progress"));
      break;
    case RECEIVERESULT::CSERROR:
      Serial.println(F("...........................................Checksum error"));
      break;
    case RECEIVERESULT::TIMEOUT:
      Serial.println(F("...........................................Timeout"));
      break;
  }
}

/*
  print received data
*/
void printData()
{
  for (uint8_t cnt = 0; cnt < sizeof(data_buffer); cnt++)
  {
    if (data_buffer[cnt] < 0x10)
    {
      Serial.print(F("0"));
    }
    Serial.print(data_buffer[cnt], HEX);
    Serial.print(F(" "));
  }
  Serial.println();
}


Tried using millis function and showing this type of thing

[code]
// Include the Software Serial library
#include <SoftwareSerial.h>

// Define connections to sensor
int pinRX = 10;
int pinTX = 11;

// Array to store incoming serial data
const uint8_t messageSize = 4;
unsigned char data_buffer[messageSize];
const unsigned long eventinterval = 1000;
unsigned long previoustime=0;

// Integer to store distance
int distance = 0;
int lastDistance = 0;

// Object to represent software serial port
SoftwareSerial mySerial(pinRX, pinTX);
// for sterretje's setup, comment out above and uncomment below
//#define mySerial Serial1

// receive timeout
const uint32_t a02yuwwTimeout = 400;
// header byte
const uint8_t headerByte = 0xff;
// possible results of a02yuww receive function
enum class RECEIVERESULT
{
  COMPLETE,    // data available
  WAITING,     // wait for header
  INPROGRESS,  // receive in progress (header received but not yet required number of bytes)
  CSERROR,     // checksum error
  TIMEOUT,     // timeout
};

void setup()
{
  // Set up serial monitor
  Serial.begin(115200);
  // Set up software serial port
  mySerial.begin(9600);
}


void loop()
{
  unsigned long currenttime= millis();
  // remember previous result of readSensor
  static RECEIVERESULT lastRR;
  // remember last time that we succesfully received a packet
  static uint32_t lastTime;

  // read the a02yuww sensor
  RECEIVERESULT rr = readSensor();
  // if there was a change in the result
  if (rr != lastRR)
  {
    printReceiveResult(rr);
  }
  lastRR = rr;
  if (rr == RECEIVERESULT::COMPLETE)
  {
    // time that data was received
    uint32_t receivedTime = millis();

    // print the received data
    printData();

    // calculate distance
    distance = (data_buffer[1] << 8) + data_buffer[2];
  }
    
    if(currenttime - previoustime >= eventinterval)
    {
    Serial.print(F("\tDistance = "));
    Serial.print(distance);
    previoustime=currenttime;
    
   

  

    // at overflow of the timing (49 days)
    if (receivedTime < lastTime)
    {
      Serial.println(F("Timing overflow; packet ignored"));
    }
    else
    {
      long speed = (distance - lastDistance) * 1000L / (long)(receivedTime - lastTime);
    
       if(currenttime - previoustime >= eventinterval)
    {
      Serial.print(F("\tSpeed = "));
      Serial.println(speed);
      previoustime=currenttime;
      
    }
    lastDistance = distance;
    lastTime = receivedTime;
  }
  }
}

/*
  read a02yuww sensor
  Returns:
    receive status (RECEIVERESULT)
*/
RECEIVERESULT readSensor()
{
  // flag to indicate if header byte was received
  static bool receiveInProgress = false;
  // where to store received byte
  static uint8_t index = 0;
  // time that last byte was received
  static uint32_t lastReceivedTime;

  // clear the buffer if we haven't received the header byte
  if (receiveInProgress == false)
  {
    memset(data_buffer, 0, sizeof(data_buffer));
  }

  // if there is no sensor byte
  if (mySerial.available() == 0)
  {
    // indicate that we don't have a reading yet
    if (receiveInProgress == false)
    {
      return RECEIVERESULT::WAITING;
    }
    else
    {
      // if we did not get the next byte in time
      if (millis() - lastReceivedTime > a02yuwwTimeout)
      {
        // reset local variables
        receiveInProgress = false;
        index = 0;
        return RECEIVERESULT::TIMEOUT;
      }
      else
      {
        return RECEIVERESULT::INPROGRESS;
      }
    }
  }

  // read an available byte and store in buffer
  data_buffer[index++] = mySerial.read();
  lastReceivedTime = millis();

  // check for packet header character 0xff
  if (receiveInProgress == false)
  {
    if (data_buffer[0] == headerByte)
    {
      // indicate that we've got the header byte
      receiveInProgress = true;
      return RECEIVERESULT::INPROGRESS;
    }

    // reset index if it was not the header byte
    index = 0;
    return RECEIVERESULT::WAITING;
  }

  // if we're waiting for the other bytes
  if (receiveInProgress == true)
  {
    // if we haven't received all bytes yet
    if (index == messageSize)
    {
      // clear local variables
      index = 0;
      receiveInProgress = false;

      // calculate checksum
      uint8_t cs = data_buffer[0] + data_buffer[1] + data_buffer[2];
      // if checksum is valid
      if (data_buffer[3] == cs)
      {
        return RECEIVERESULT::COMPLETE;
      }
      else
      {
        return RECEIVERESULT::CSERROR;
      }
    }
    else
    {
      return RECEIVERESULT::INPROGRESS;
    }
  }
  return RECEIVERESULT::WAITING;
}

/*
  print human readible RECEIVERESULT
  In:
    receive result
*/
void printReceiveResult(RECEIVERESULT r)
{
  switch (r)
  {
    case RECEIVERESULT::COMPLETE:
      
      break;
    case RECEIVERESULT::WAITING:
      
      break;
    case RECEIVERESULT::INPROGRESS:
      
      break;
    case RECEIVERESULT::CSERROR:
      
      break;
    case RECEIVERESULT::TIMEOUT:
      
      break;
  }
}


[/code]


is there any other way to just print disance and speed with 1000ms time interval?

Not behind a PC but what is wrong with it in your opinion?

I will look at your other code tomorrow; might be a musplaced { or }.

Removed all other print datas so showing this error,yes I also thought about missplacing {} but couldn't solve it logically, anyways will wait for you review

For the second code (post #38), you have removed the printData() function. So you can't call it. Below has fixed the errors and warning but might not do what you want.

For the first code (post #37), you have

    if (currenttime - previoustime >= eventinterval) { <==============
      Serial.print(F("\tDistance = "));
      Serial.print(distance);
      previoustime = currenttime;
    }

    // at overflow of the timing (49 days)
    if (receivedTime < lastTime) {
      Serial.println(F("Timing overflow; packet ignored"));
    } else {
      long speed = (distance - lastDistance) * 1000L / (long)(receivedTime - lastTime);

      if (currenttime - previoustime >= eventinterval) { <==============
        Serial.print(F("\tSpeed = "));
        Serial.println(speed);
        previoustime = currenttime;
      }

If the first marked line evaluates to true, you reset previoustime. So the second marked line will never evaluate to true.

Now it's bed time, I will try to rework my code tomorrow to get your 1 second display update. What does it need to show? Speed? Distance? Speed and distance? Anything else.

Okay I will try again to correct it, i need both speed and distance with 1second interval

At what speed (on average) does the water rise and fall in cm per minute? What is the size and shape of the container?

It's a hexagonal container of 1meter by 800mm approx , approximately level should not drop more than 10cm/min

You now have stripped all debug information by removing the serial prints. I would have expected that you just commented them out so it would be easier to get them back when needed. I suggest a different way where you can easily enable and disable it; that saves you a lot of work if you ever need to debug again.

Add the below (so called) macros at the top of your code

// for debugging via serial port, uncomment below line
//#define DEBUG

#ifdef DEBUG
#define DEBUGPRINT(...) Serial.print(__VA_ARGS__)
#define DEBUGPRINT(...) Serial.println(__VA_ARGS__)
#else
#define DEBUGPRINT(...)
#define DEBUGPRINTLN(...)
#endif

For all serial prints that are used for debugging, you can replace Serial.print by DEBUGPRINT and Serial.println by DEBUGPRINTLN.

The above disables the debug output. If you need the debug output, uncomment #define DEBUG as shown below

// for debugging via serial port, uncomment below line
#define DEBUG

To take care of the 1 second update, I suggest that you use a function that handles that.

/*
  update the display
  In:
    distance to display
    speed to display
*/
void updateDisplay(int dist, long sp)
{
  // last time that display was updated  
  static uint32_t lastUpdateTime;

  // if it's time to update the display
  if (millis() - lastUpdateTime >= displayInterval)
  {
    // refresh the time
    lastUpdateTime += displayInterval;
    // display the result
    Serial.println(millis());
    Serial.print(F(">>Distance = "));
    Serial.println(dist);
    Serial.print(F(">>Speed = "));
    Serial.println(sp);
  }
}

Once you want to use your LCD, you can adjust this function to print to the LCD.

You call this from loop; we will only do this if a reading (distance and speed) was completed). For this I've added a flag at the beginning of loop().

void loop()
{
  // remember previous result of readSensor
  static RECEIVERESULT lastRR;
  // remember last time that we succesfully received a packet
  static uint32_t lastReceiveTime;

  // indicate if a reading is complete (both distance and speed)
  bool readingComplete = false;

We set this flag when we have calculated the speed.

    else
    {
      speed = (distance - lastDistance) * 1000L / (long)(receivedTime - lastReceiveTime);
      readingComplete = true;
      DEBUGPRINT(F("\tSpeed = "));
      DEBUGPRINTLN(speed);
    }

Note:
speed is now a global variable.

And we call the updateDisplay() at the end of loop()

  // only if we have done the full calculation
  if (readingComplete == true)
  {
    // update the display (if needed)
    updateDisplay(distance, speed);
  }

The full code

// for debugging via serial port, uncomment below line
//#define DEBUG

#ifdef DEBUG
#define DEBUGPRINT(...) Serial.print(__VA_ARGS__)
#define DEBUGPRINT(...) Serial.println(__VA_ARGS__)
#else
#define DEBUGPRINT(...)
#define DEBUGPRINTLN(...)
#endif


// Include the Software Serial library
#include <SoftwareSerial.h>

// Define connections to sensor
int pinRX = 10;
int pinTX = 11;

// Array to store incoming serial data
const uint8_t messageSize = 4;
unsigned char data_buffer[messageSize];

// Integer to store distance
int distance = 0;
int lastDistance = 0;
// Long integer to store speed
long speed;

// Object to represent software serial port
SoftwareSerial mySerial(pinRX, pinTX);
//#define mySerial Serial1

// receive timeout
const uint32_t a02yuwwTimeout = 400;
// header byte
const uint8_t headerByte = 0xff;
// possible results of a02yuww receive function
enum class RECEIVERESULT
{
  COMPLETE,    // data available
  WAITING,     // wait for header
  INPROGRESS,  // receive in progress (header received but not yet required number of bytes)
  CSERROR,     // checksum error
  TIMEOUT,     // timeout
};

// time between display updates
const uint32_t displayInterval = 1000;

void setup()
{
  // Set up serial monitor
  Serial.begin(115200);
  // Set up software serial port
  mySerial.begin(9600);
}

void loop()
{
  // remember previous result of readSensor
  static RECEIVERESULT lastRR;
  // remember last time that we succesfully received a packet
  static uint32_t lastReceiveTime;

  // indicate if a reading is complete (both distance and speed)
  bool readingComplete = false;

  // read the a02yuww sensor
  RECEIVERESULT rr = readSensor();

  // if there was a change in the result
  if (rr != lastRR)
  {
    printReceiveResult(rr);
  }
  lastRR = rr;
  if (rr == RECEIVERESULT::COMPLETE)
  {
    // time that data was received
    uint32_t receivedTime = millis();

    // print the received data
    printData();

    // calculate distance
    distance = (data_buffer[1] << 8) + data_buffer[2];
    DEBUGPRINT(F("\tDistance = "));
    DEBUGPRINT(distance);
    DEBUGPRINT(F(" / "));
    DEBUGPRINTLN(lastDistance);

    DEBUGPRINT(F("\tDelta distance = "));
    DEBUGPRINTLN(distance - lastDistance);

    DEBUGPRINT(F("\tTime = "));
    DEBUGPRINT(receivedTime);
    DEBUGPRINT(F(" / "));
    DEBUGPRINTLN(lastReceiveTime);
    DEBUGPRINT(F("\tDelta time = "));
    DEBUGPRINTLN(receivedTime - lastReceiveTime);

    // at overflow of the timing (49 days)
    if (receivedTime < lastReceiveTime)
    {
      Serial.println(F("Timing overflow; packet ignored"));
    }
    else
    {
      speed = (distance - lastDistance) * 1000L / (long)(receivedTime - lastReceiveTime);
      readingComplete = true;
      DEBUGPRINT(F("\tSpeed = "));
      DEBUGPRINTLN(speed);
    }

    lastDistance = distance;
    lastReceiveTime = receivedTime;
  }

  // only if we have done the full calculation
  if (readingComplete == true)
  {
    // update the display (if needed)
    updateDisplay(distance, speed);
  }
}

/*
  read a02yuww sensor
  Returns:
    receive status (RECEIVERESULT)
*/
RECEIVERESULT readSensor()
{
  // flag to indicate if header byte was received
  static bool receiveInProgress = false;
  // where to store received byte
  static uint8_t index = 0;
  // time that last byte was received
  static uint32_t lastReceivedTime;

  // clear the buffer if we haven't received the header byte
  if (receiveInProgress == false)
  {
    memset(data_buffer, 0, sizeof(data_buffer));
  }

  // if there is no sensor byte
  if (mySerial.available() == 0)
  {
    // indicate that we don't have a reading yet
    if (receiveInProgress == false)
    {
      return RECEIVERESULT::WAITING;
    }
    else
    {
      // if we did not get the next byte in time
      if (millis() - lastReceivedTime > a02yuwwTimeout)
      {
        // reset local variables
        receiveInProgress = false;
        index = 0;
        return RECEIVERESULT::TIMEOUT;
      }
      else
      {
        return RECEIVERESULT::INPROGRESS;
      }
    }
  }

  // read an available byte and store in buffer
  data_buffer[index++] = mySerial.read();
  lastReceivedTime = millis();

  // check for packet header character 0xff
  if (receiveInProgress == false)
  {
    if (data_buffer[0] == headerByte)
    {
      // indicate that we've got the header byte
      receiveInProgress = true;
      return RECEIVERESULT::INPROGRESS;
    }

    // reset index if it was not the header byte
    index = 0;
    return RECEIVERESULT::WAITING;
  }

  // if we're waiting for the other bytes
  if (receiveInProgress == true)
  {
    // if we haven't received all bytes yet
    if (index == messageSize)
    {
      // clear local variables
      index = 0;
      receiveInProgress = false;

      // calculate checksum
      uint8_t cs = data_buffer[0] + data_buffer[1] + data_buffer[2];
      // if checksum is valid
      if (data_buffer[3] == cs)
      {
        return RECEIVERESULT::COMPLETE;
      }
      else
      {
        return RECEIVERESULT::CSERROR;
      }
    }
    else
    {
      return RECEIVERESULT::INPROGRESS;
    }
  }
  return RECEIVERESULT::WAITING;
}

/*
  print human readible RECEIVERESULT
  In:
    receive result
*/
void printReceiveResult(RECEIVERESULT r)
{
  switch (r)
  {
    case RECEIVERESULT::COMPLETE:
      DEBUGPRINTLN(F("Complete"));
      break;
    case RECEIVERESULT::WAITING:
      DEBUGPRINTLN(F("Waiting for header"));
      break;
    case RECEIVERESULT::INPROGRESS:
      DEBUGPRINTLN(F("Receive in progress"));
      break;
    case RECEIVERESULT::CSERROR:
      DEBUGPRINTLN(F("...........................................Checksum error"));
      break;
    case RECEIVERESULT::TIMEOUT:
      DEBUGPRINTLN(F("...........................................Timeout"));
      break;
  }
}

/*
  print received data
*/
void printData()
{
  for (uint8_t cnt = 0; cnt < sizeof(data_buffer); cnt++)
  {
    if (data_buffer[cnt] < 0x10)
    {
      DEBUGPRINT(F("0"));
    }
    DEBUGPRINT(data_buffer[cnt], HEX);
    DEBUGPRINT(F(" "));
  }
  DEBUGPRINTLN();
}

/*
  update the display
  In:
    distance to display
    speed to display
*/
void updateDisplay(int dist, long sp)
{
  // last time that display was updated
  static uint32_t lastUpdateTime;

  // if it's time to update the display
  if (millis() - lastUpdateTime >= displayInterval)
  {
    // refresh the time
    lastUpdateTime += displayInterval;
    // display the result
    Serial.println(millis());
    Serial.print(F(">>Distance = "));
    Serial.println(dist);
    Serial.print(F(">>Speed = "));
    Serial.println(sp);
  }
}

Typical output without debug

5227052
>>Distance = 410
>>Speed = -99
5228052
>>Distance = 310
>>Speed = -100
5229052
>>Distance = 410
>>Speed = 100
5230053
>>Distance = 510
>>Speed = 100
5231053
>>Distance = 610
>>Speed = 100
5232054
>>Distance = 710
>>Speed = 99