SEN0366 returning Cache data

Allllrrriiightt, this time I actually have code to share. So I'm currently testing the SEN0366 Laser Distance sensor. What I've noticed is in a standard sketch it generally updates the distance measured within a half a second but still reports cache data. When putting a standalone button to record data it would first show the cache than the new data. A workaround I found was to put a for loop for about 15 times and record the highest data output as in case when it bugs out it returns a 4.

HardwareSerial mySerial(2);

//Infared Laser Serial
uint8_t Com[4] = {0x80, 0x06, 0x03, 0x77};
uint8_t OFFCom[5] = {0x80, 0x06, 0x05, 0x00, 0x75};

float CacheDistance = 0;

void setup() {
  Serial.begin(115200);
  mySerial.begin(9600, SERIAL_8N1);
  mySerial.write(Com, 4);
}

int readN(uint8_t *buf, size_t len) {
  size_t offset = 0, left = len;
  long curr = millis();
  while (left) {
    if (mySerial.available()) {
      buf[offset++] = mySerial.read();
      left--;
    }
    if (millis() - curr > 150) {
      break;
    } 
  } 
  return offset;
}

uint8_t getCS(uint8_t *buf) {
  uint8_t cs = 0;
  for (int i = 0; i < 10; i++)
  {
    cs = cs + buf[i];
  }
  cs = ~cs + 1;
  return cs;
}

bool recvData(uint8_t *buf) {
  long curr = millis();
  bool ret = false;
  uint8_t ch;
  while (!ret) {
    if (millis() - curr > 100) {
      break;
    } 

    if (readN(&ch, 1) != 1) {
      continue;
    }

    if (ch == 0x80) {
      buf[0] = ch;
      if (readN(&ch, 1) == 1) {
        if (ch == 0x06) {
          buf[1] = ch;
          if (readN(&ch, 1) == 1) {
            if (ch == 0x83) {
              buf[2] = ch;
              if (readN(&buf[3], 8) == 8) {
                if (getCS(buf) == buf[10]) {
                  ret = 1;
                }
              }
            }
          }
        }
      }
    }
  }
  return ret;
}

float getDistance() {
  float distance = 0;
  uint8_t data[11] = {0};
  if (recvData(data)) {
    if (data[3] == 'E' && data[4] == 'R' && data[5] == 'R') {
      //Serial.println("Out of range");
      return -1;
    } else {
      distance = (data[3] - 0x30) * 100 + (data[4] - 0x30) * 10 + (data[5] - 0x30) * 1 + (data[7] - 0x30) * 0.1 + (data[8] - 0x30) * 0.01 + (data[9] - 0x30) * 0.001;
      //      distance = atof(data[3]);
      return distance;
    }
  } else {
    return -2;
  }
}

void printDistance(float Distance) {
  if (Distance == -1) {
    //Serial.println("  Out of range  ");
  } else {
    if (Distance == -2) {
      //Serial.println(" Invalid Data!  ");
    } else {
      if (Distance < 1) {
        //Serial.print(Distance, 1);
        //Serial.println("CM");
      } else {
        //Serial.print(Distance, 3);
        //Serial.println("M");
      }
    }
  }
  CacheDistance = Distance * 3.28;
}

void LockMode() {
  mySerial.write(Com, 4);
  delay(10);
  printDistance(getDistance());
  if (CacheDistance < 0) {
    CacheDistance = 0;
  }
  mySerial.write(OFFCom, 5);
}

I would be using a for loop for the LockMode function, and only then does it return good data. Any ideas? Tried reading the cache but that doesn't seem to work and I don't see any serial commands that could clear the cache and I would prefer not to do a total shutdown and start up over and over to read distances.

What cache?

The sensor comes with it's own cache it seems, it's serial write is 0x80, 0x06, 0x07, 0x73, but doing that just returns the same distance over and over. Doesn't seem like they noted any serial commands to clear the cache.

Can you provide a link to the sensor documentation?

This is the Serial commands, and this link is DFRobot's general wiki Infrared Laser Rangefinder Arduino Wiki - DFRobot

The cache operation seems straightforward, it holds the data from the last measure command given.

So it's likely you are just breaking the protocol somehow. However you have not explained why you believe the data isn't "good".

Clearing the cache doesn't sound like a useful operation.

Try writing a test sketch that only issues the command and reads the cache. Nothing else.

Or, run a library or manufacturer example sketch if you have one.

I have tried running the manufacturer sketch, infact the code I'm currently using is their previous code for this sensor which it seems they have updated. When running this code in it's own sketch after a few reads it updates the distance. When setting the serial to read the cache it just sends out one distance no matter if it changes.

In your code, do you send the 'read' command, prior to every read of the cache?

What does that for loop do? If you have one working sketch you are almost all the way there.

Now that we are talking about a working and non-working sketch, you should post and identify each.

I would use a for loop, should've been more specific and run it for about 15 times to where the new distance is set. I will try reading the cache instead of serial write and see if that makes any difference.

Seems like this was the solution my dumb brain put write instead of read, after setting it to read and putting in void setup a for loop for 8 as it seems it initially stores a value, it works flawlessly.

1 Like

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