garmin / LIDARLite_Arduino_Library

High-performance optical distance sensing.
Apache License 2.0
181 stars 84 forks source link

lidar lite v3 API cause interrupt function wrong #5

Closed linzha0 closed 7 years ago

linzha0 commented 7 years ago

Hi, I am use arduino nano board to do project which collects range data of Lidar Lite V3 and time period from micro optical sensor.

Here is the code:

#include <Wire.h>
#include "LIDARLite.h"

LIDARLite myLidarLite;

volatile bool encoder_flag = false;
volatile unsigned long Time = 0;
volatile int Duration = 0;
volatile unsigned long LastTime = 0; 

void encoderTick(){
  encoder_flag = true;
}

void setup() {
  pinMode(3, INPUT);//monitor optical sensor read

  attachInterrupt(digitalPinToInterrupt(3), encoderTick, CHANGE);

  Serial.begin(115200);
  myLidarLite.begin(0,true);  
  myLidarLite.configure(0);
}

void loop() {

  if(encoder_flag){
    encoder_flag =false;

    /****record this encoder time****/
    Time = millis();
    Duration = Time-LastTime;
    LastTime = Time;

    Serial.println(Duration);  
  }

  //int d =myLidarLite.distance();

}

Basically, the photo sensor will trig a interrupt as soon as something cover it or leave it. Then the Lidar rotate 360 degree I will get 30 time durations by optical sensor. 28 of them should be almost close, 29th is small and 30th is large to determine the zero position. Because most of covers are the normal size and one is small then normal size and one is larger than normal size. As you can see the code, without int d =myLidarLite.distance(), the durations lists below:

7 8 7 7 6 8 6 9 6 8 6 8 6 9 6 8 6 8 8 7 7 7 7 7 8 7 7 7 3 11
Then I add int d =myLidarLite.distance(), the durations become ruleless and even not periodic. like this:

8 4 13 9 4 6 8 8 7 9 7 7 10 3 7 12 7 8 9 3 7 10 5 3 7 8 5 9 4 12

Obviously, this Lidar API cause interrupt function process inaccurate so that time duration calculations are wrong. Is that lidar API take too much time so that interrupts process wrong? Any suggestions will be appreciated. Thanks for your help.

linzha0 commented 7 years ago

I put time record : Time = millis(); in the interrupt, it's same result.
Then i use ShortRangeHighSpeed example and put time record : Time = millis(); in the interrupt,it's works fine. Juts got problem to use myLidarLite.distance().

Lauszus commented 7 years ago

@CrazyPopLin the Lidar code is not using any interrupts. Your problem is due to the fact that the distance operations is blocking at these lines: https://github.com/garmin/LIDARLite_v3_Arduino_Library/blob/master/src/LIDARLite.cpp#L243-L266, as it simply waits until the data is ready.

Another option would be init the measurement manually: https://github.com/garmin/LIDARLite_v3_Arduino_Library/blob/master/src/LIDARLite.cpp#L171-L180 and then read the busy flag in your loop. And finally read the distance measurement when data is actually ready.

I did the same for my flight controller: https://github.com/Lauszus/LaunchPadFlightController/blob/Lidar/src/LidarLiteV3.c#L68-L98, as I did not want it to block my main loop.

linzha0 commented 7 years ago

@Lauszus ,thanks for your help.

AlexisTM commented 7 years ago

You can also use my own library which is meant to be asynchronous. LidarEnhanced