Translating Lidar Lite I2C example to Teensy

Status
Not open for further replies.
LIDAR-Lite on T3.1 is now working at 10 ms (mostly)

After installing the new Wire.cpp, I am getting mostly 9 or 10 msec intervals without locking up, running for 10 minutes so far at least. To be more accurate, the output interval is always 9-12 msec when the range is fixed around 6 meters. If I wave my hand in front and then suddenly take it away, the first reading at the larger distance takes longer, for example 12 to 15 msec. The maximum interval I have seen so far is 15 msec. Ocasionally I get a "0" reading, which was true before as well, but no lockups so far.

EDIT: still working fine after running 9 hours overnight.

Code:
44, 10
45, 10
45, 10
43, 10
44, 10
44, 10
45, 10
45, 10
47, 11
51, 10
48, 10
598, 12

Stability in reading when pointing at a light-colored wall 3 meters away. This is after running for about 10 hours, not that it needs warm-up, but to show stability did not degrade after that long.
Code:
300, 10
300, 10
299, 10
300, 9
299, 11
300, 10
301, 9
300, 10
300, 9
300, 10
299, 10
300, 9
300, 10
299, 10
301, 10
300, 9
300, 10
300, 10
301, 10
300, 10
 
Last edited:
Just saw this updated WIRE library for LC posted: https://forum.pjrc.com/threads/21680-New-I2C-library-for-Teensy3?p=70345&viewfull=1#post70345

In reference to Paul's Message #90 : Reading about this support function I wondered if it would be useful to get the Lidar back on track?
Added resetBus() function:
•In the above case where the Master can't send a START because a Slave is holding the SDA low, this command will toggle the SCL line (up to 9 clock pulses), to try and get the Slave to release SDA. Once SDA is released the Master should be able to send new commands.
 
For the cases where Lidar is stuck (perhaps it dropped a clock internally or something), it should help. I would be interested to see the outcome. It should not require any effort, the I2C_AUTO_RETRY function will automatically try to unstick the bus in that case.

However the random pulsing that the Lidar does on SDA could cause other problems with arbitration. I did not spend any time looking into that yet. Given the descriptions above I kind of suspect it may take something more to make it reliable.
 
Using PaulS's new code from post #89 and new Wire.cpp library from post #88, I haven't seen a lockup yet. I modified his code to delay 250 usec instead of 50 usec, and also to track the maximum dT interval between readings. Over a 12 hour run, the maximum interval was 16 msec but by far the most common intervals are 9, 10, and 11 msec.
 
Last edited:
So, I thought I had this shown up. I integrated Paul's code into my sweeper code which drives a steeper and reads from the lidar. The lidar works fine for hours on end in this code with the stepper powered off and the stepper works great for sending the proper steps when I do not read from the lidar. When I applied power to the stepper the Lidar locks up after a couple dozen readings every time. Very frustrating. All this is using the same code and by applying power to the stepper I am turning on the 12v external power. I don't recall ever having to common the ground between the stepper driver and my processor before. That's the only thing I can think to be off here. The stepper is controlled through a pollution 4988 driver
 
care and feeding of LIDAR-Lite

It may be that the laser supply comes direct from the +5V input without regulation, so if you have RF noise on the power, that modulates the laser and causes inaccurate operation or no operation. A series inductor (even just a ferrite bead) in addition to some filter caps may help. The laser pulses are sub-microsecond so it is the high frequencies that count most, so I think adding a set of 1.0, 0.1 uF and smaller caps might have the most effect.

I also decided to shield the stray high-angle (scattered?) laser light with some black foil as shown here:
https://picasaweb.google.com/lh/photo/diAx1HgTlYxuR_hh1AMNIdMTjNZETYmyPJy0liipFm0?feat=directlink
 
Lidar output histograms

In case of interest, here are two histograms summarizing the data I see in two situations, a fixed target around 3.5 meters, and around 9 meters (I didn't actually measure the physical distance separately, but the numbers are about right). You can see how much scatter increases with distance. The closer target readings took 9 to 10 msec, and the more distant target readings took 14-15 msec. Obviously it doesn't take light 5 milliseconds to cover the extra 6 meters, I suppose it has to do with needing to accumulate more readings at the lower signal level to determine a value.

Lidar-352cm_View 2.pngLidar-935cm_View 2.png

Update: using a 25x75 mm patch of "REFLEXITE SOLAS" retroreflector as a target around 29 meters away, I get 2964 cm min, 2965 average, 2972 max readings over a period of about a minute, so the pk-pk noise is only 8 cm and the std.dev quite a bit less. This is the expensive, superbright micro-prismatic retroreflector material, no normal surface performs as well.
 
Last edited:
No problems with the new Wire.cpp for me, and it did fix the lockup which happened right away on the old Wire.cpp so it is clearly better from that point of view.
however I've only been testing this one case, the Lidar-Lite device.
 
I did see a lockup tonight using the new code, while monitoring with an IR camera and I noticed that the laser emission went off at the same time. Power cycling fixed it. If this wasn't just a bad breadboard wire connection, it means the Lidar had a total system lockup, not just the I2C interface module. Beginning to think the whole thing is just flaky.
 
Mine still locks up regularly while running it with a steeper motor. I'm still in the middle of investigating if it is SW or HW.
I do have a second on of these yet unopened but I am still hopeful it is software as this works with the recommended i2c library on my arduino with steppers running. I don't know if any one has looked into this library that is recommended as the Wire library does not really work with the Lidar.
it can be found here. http://www.dsscircuits.com/index.php/articles/66-arduino-i2c-master-library
my possible problems I believe right now are either noise from the stepper on the power line or Strange I2C messaging from the Lidar (i.e. pulling down the SDA line or something).
either way it locks up while waiting for a requestFrom call.
I was thinking I might add a time out in the Wire.ccp that Paul added during the While statements in this method.
I don't know if that the issue but was gonna try it tonight.
 
Proposed "non blocking" library for pulselight3d lidarlite

Hello,

I just wanted to share a personnal trial for a lidar lite library that avoid using the delay keyword for non blocking the loop function.
It was tested with arduino due and seems working pretty well.
I made a little modification to arduino 1.6.4 Wire library to allow using customized I2C rx and Tx timouts

Example Sketch
Code:
/* 

This sketch demonstrates getting measurement with the PulseLight3d Sensor by http://pulsedlight3d.com

It uses LidarLite library by Mathieu Peyrega (mathieu.peyrega@gmail.com) and slightly modified Wire library to allow
customized TX and RX timeouts on I2C calls

This sketch was tested only with Arduino Due

*/

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

LidarLiteClass theLidar;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  delay(50);
  //Wire.setTxTimeOut(5000);    //  Uncomment if using the slightly modified Wire library to allow custom I2C timeouts
  //Wire.setRxTimeOut(5000);    //
  Wire.begin();
  delay(50);
  
  theLidar.registerMeasurementBufferOverflowCallback(&onBufferOverFlowExample);
  theLidar.init();
}

void loop()
{
    theLidar.tick();
    
    /*  Uncomment to consume measurements as they show up otherwise the buffer overflow callback will be called
    while (theLidar.measurementIsAvailable())
    {
        LidarLitePoint point = theLidar.popOneMeasurementFromBuffer();
        Serial.println(point.range.val);
      
    }
    */
}

void onBufferOverFlowExample(LidarLitePoint point)
{
  LidarLitePoint oldestpoint = theLidar.popOneMeasurementFromBuffer();
  uint32_t sum = oldestpoint.range.val;
  uint32_t oldest_timestamp = oldestpoint.timestamp_us;
  uint32_t i = 1;
  
  while (theLidar.measurementIsAvailable())
  {
    ++i;
    sum += theLidar.popOneMeasurementFromBuffer().range.val;
  }
  
  sum += point.range.val;
  
  float mean_dist = sum / (float)(i+1);
  uint32_t delta_t = point.timestamp_us - oldest_timestamp;
  float frequency = (float)(1000000*i)/(float)delta_t;
  
  Serial.print("Mean distance\t:\t");
  Serial.println(mean_dist);
  Serial.print("Meas frequency\t:\t");
  Serial.println(frequency);
}

LidarLite.h
Code:
/*
 * LidarLite.h - PulseLight3d LidarLite library for Arduino Due
 * Copyright (c) 2015 Mathieu Peyrega <mathieu.peyrega@gmail.com>
 * All rights reserved.
 *
 * Version 1.0
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef _LIDARLITE_H_
#define _LIDARLITE_H_	1

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

#define	LIDARLITE_I2C_ADDRESS   (uint8_t)0x62

#define LIDARLITE_COMMAND_REGISTER (uint8_t)0x00
#define LIDARLITE_COMMAND_RESET_FPGA (uint8_t)0x00
#define LIDARLITE_COMMAND_START_MEASUREMENT (uint8_t)0x04

#define LIDARLITE_INTENSITY_DISTANCE_REGISTER (uint8_t)0x8e

//	LidarLite state machine status
#define LIDARLITE_MAX_STATES      6
#define LIDARLITE_STATE_UNKNOWN   (uint8_t)0x00
#define LIDARLITE_STATE_RESETTING (uint8_t)0x01
#define LIDARLITE_STATE_IDLE      (uint8_t)0x02
#define LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS (uint8_t)0x03
#define LIDARLITE_STATE_MEASUREMENT_COMPLETED   (uint8_t)0x04

#include <deque>

struct LidarLitePoint
{
	uint32_t timestamp_us = 0;
	union {uint16_t val; uint8_t raw[2]; } range = { 0 };
	uint8_t  intensity = 0;
};

class LidarLiteClass
{
	public:
		LidarLiteClass(uint16_t measurementbuffermaxsize = 100, uint8_t addr = LIDARLITE_I2C_ADDRESS, TwoWire& I2C_interface = Wire);
		void init();
		void tick();
		bool measurementIsAvailable(void);
		LidarLitePoint popOneMeasurementFromBuffer(void);
		
		void registerHardwareResetCallback(void(*hardware_reset_cb)(void));
		void registerMeasurementBufferOverflowCallback(void(*buffer_overflow_cb)(LidarLitePoint point));
		
	private:
	    uint8_t m_Addr;
		TwoWire& m_I2C_interface;
		uint8_t m_LidarLiteState;
		uint32_t m_SuccessfulMeasurements;
		uint32_t m_FailedMeasurements;
		uint32_t m_ResetCounts;
		uint32_t m_TimeOfLastTransitionToState[LIDARLITE_MAX_STATES];
		uint32_t m_TimeOfLastCallToStateHandler[LIDARLITE_MAX_STATES];
		uint32_t m_MaxTimeAllowedInState[LIDARLITE_MAX_STATES];
		uint32_t m_MinTimeAllowedInState[LIDARLITE_MAX_STATES];
		uint32_t m_MinTimeBetweenCallsToStateHandler[LIDARLITE_MAX_STATES];
		
		void (*m_onHarwareResetCallback)(void);
		void (*m_onMeasurementBufferOverflowCallback)(LidarLitePoint point);

		void onLidarStateUnknown(uint32_t now);
		void onLidarStateResetting(uint32_t now);
		void onLidarStateIdle(uint32_t now);
		void onLidarStateMeasurementInProgress(uint32_t now);
		void onLidarStateMeasurementCompleted(uint32_t now);
		
		bool isLidarLiteAlive(uint32_t &now);
		
		std::deque<LidarLitePoint> m_MeasurementsBuffer;
		uint16_t m_MeasurementBufferMaxSize;
		
};	//	class LidarLiteClass

#endif

LidarLite.cpp
Code:
/*
 * LidarLite.h - PulseLight3d LidarLite library for Arduino Due
 * Copyright (c) 2015 Mathieu Peyrega <mathieu.peyrega@gmail.com>
 * All rights reserved.
 *
 * Version 1.0
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
#include "LidarLite.h"

LidarLiteClass::LidarLiteClass(uint16_t measurementbuffermaxsize, uint8_t addr, TwoWire& I2C_interface)
:m_Addr(addr),
m_I2C_interface(I2C_interface),
m_LidarLiteState(LIDARLITE_STATE_IDLE),
m_SuccessfulMeasurements(0),
m_FailedMeasurements(0),
m_ResetCounts(0),
m_onHarwareResetCallback(0),
m_onMeasurementBufferOverflowCallback(0),
m_MeasurementBufferMaxSize(measurementbuffermaxsize)
{
}

void LidarLiteClass::init()
{
	m_LidarLiteState = LIDARLITE_STATE_IDLE;
	
	uint32_t now = micros();
	
	this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_UNKNOWN] = now;
	this->m_TimeOfLastCallToStateHandler[LIDARLITE_STATE_UNKNOWN] = 0;
	this->m_MaxTimeAllowedInState[LIDARLITE_STATE_UNKNOWN] = 10000;
	this->m_MinTimeAllowedInState[LIDARLITE_STATE_UNKNOWN] = 0;
	this->m_MinTimeBetweenCallsToStateHandler[LIDARLITE_STATE_UNKNOWN] = 50;
	
	this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_RESETTING] = now;
	this->m_TimeOfLastCallToStateHandler[LIDARLITE_STATE_RESETTING] = 0;
	this->m_MaxTimeAllowedInState[LIDARLITE_STATE_RESETTING] = 100000;
	this->m_MinTimeAllowedInState[LIDARLITE_STATE_RESETTING] = 1000;
	this->m_MinTimeBetweenCallsToStateHandler[LIDARLITE_STATE_RESETTING] = 2000;
	
	this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_IDLE] = now;
	this->m_TimeOfLastCallToStateHandler[LIDARLITE_STATE_IDLE] = 0;
	this->m_MaxTimeAllowedInState[LIDARLITE_STATE_IDLE] = 10000;
	this->m_MinTimeAllowedInState[LIDARLITE_STATE_IDLE] = 1000;
	this->m_MinTimeBetweenCallsToStateHandler[LIDARLITE_STATE_IDLE] = 500;
	
	this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS] = now;
	this->m_TimeOfLastCallToStateHandler[LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS] = 0;
	this->m_MaxTimeAllowedInState[LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS] = 25000;
	this->m_MinTimeAllowedInState[LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS] = 6000;
	this->m_MinTimeBetweenCallsToStateHandler[LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS] = 2000;
	
	this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_MEASUREMENT_COMPLETED] = now;
	this->m_TimeOfLastCallToStateHandler[LIDARLITE_STATE_MEASUREMENT_COMPLETED] = 0;
	this->m_MaxTimeAllowedInState[LIDARLITE_STATE_MEASUREMENT_COMPLETED] = 10000;
	this->m_MinTimeAllowedInState[LIDARLITE_STATE_MEASUREMENT_COMPLETED] = 500;
	this->m_MinTimeBetweenCallsToStateHandler[LIDARLITE_STATE_MEASUREMENT_COMPLETED] = 500;
}

void LidarLiteClass::tick()
{
	
	

	uint32_t now = 0;
	if (this->isLidarLiteAlive(now))   //	Test if we had no state transition for a long time
	{	                               //	which is a good clue of lidar lite hanging
	
		bool test1 = (now - this->m_TimeOfLastTransitionToState[this->m_LidarLiteState])  > this->m_MinTimeAllowedInState[this->m_LidarLiteState];
		bool test2 = (now - this->m_TimeOfLastCallToStateHandler[this->m_LidarLiteState]) > this->m_MinTimeBetweenCallsToStateHandler[this->m_LidarLiteState];
		bool test3 = (this->m_TimeOfLastCallToStateHandler[this->m_LidarLiteState] == 0);
		
		if (test1 && (test2 || test3))
		{
			this->m_TimeOfLastCallToStateHandler[this->m_LidarLiteState] = now;
			switch(this->m_LidarLiteState)
			{
				case LIDARLITE_STATE_UNKNOWN:
				this->onLidarStateUnknown(now);
				break;
				
				case LIDARLITE_STATE_RESETTING:
				this->onLidarStateResetting(now);
				break;
				
				case LIDARLITE_STATE_IDLE:
				this->onLidarStateIdle(now);
				break;
				
				case LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS:
				this->onLidarStateMeasurementInProgress(now);
				break;
				
				case LIDARLITE_STATE_MEASUREMENT_COMPLETED:
				this->onLidarStateMeasurementCompleted(now);
				default:
				break;
			}
		}
	}
}

void LidarLiteClass::registerHardwareResetCallback(void(*hardware_reset_cb)(void))
{
	this->m_onHarwareResetCallback = hardware_reset_cb;
}

void LidarLiteClass::registerMeasurementBufferOverflowCallback(void(*buffer_overflow_cb)(LidarLitePoint point))
{
	this->m_onMeasurementBufferOverflowCallback = buffer_overflow_cb;
}
		
void LidarLiteClass::onLidarStateUnknown(uint32_t now)
{
	// state transition
	this->m_LidarLiteState = LIDARLITE_STATE_RESETTING;
	this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_RESETTING] = now;
	++(this->m_ResetCounts);
}

void LidarLiteClass::onLidarStateResetting(uint32_t now)
{
	this->m_I2C_interface.beginTransmission(this->m_Addr);
	this->m_I2C_interface.write(LIDARLITE_COMMAND_REGISTER);
	this->m_I2C_interface.write(LIDARLITE_COMMAND_RESET_FPGA);
	if (this->m_I2C_interface.endTransmission() == 0)
	{
		//	Reset FPG command successful : state transition
		this->m_LidarLiteState = LIDARLITE_STATE_IDLE;
		this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_IDLE] = now;
	}
}

void LidarLiteClass::onLidarStateIdle(uint32_t now)
{
	//	when the trigger of a new measurement is successful, or at least seems
	//  successful from the returned values of I2C protocol the state will
	//	transition to LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS

	this->m_I2C_interface.beginTransmission(this->m_Addr);
	this->m_I2C_interface.write(LIDARLITE_COMMAND_REGISTER);
	this->m_I2C_interface.write(LIDARLITE_COMMAND_START_MEASUREMENT);
	if (this->m_I2C_interface.endTransmission() == 0)
	{
		//	Start measurement successful : state transition
		this->m_LidarLiteState = LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS;
		this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS] = now;
	}
}

void LidarLiteClass::onLidarStateMeasurementInProgress(uint32_t now)
{
	//	when a new measurement as been triggered for long enough, we try to read the
	//	result by setting the pointer to the result register
	
	this->m_I2C_interface.beginTransmission(this->m_Addr);
	this->m_I2C_interface.write(LIDARLITE_INTENSITY_DISTANCE_REGISTER);
	if (this->m_I2C_interface.endTransmission() == 0)
	{
		//	Measurement seems successful : state transition
		this->m_LidarLiteState = LIDARLITE_STATE_MEASUREMENT_COMPLETED;
		this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_MEASUREMENT_COMPLETED] = now;
	}
}

bool LidarLiteClass::measurementIsAvailable(void)
{
	return this->m_MeasurementsBuffer.size() != 0;
}

LidarLitePoint LidarLiteClass::popOneMeasurementFromBuffer(void)
{
	LidarLitePoint point = this->m_MeasurementsBuffer.front();
	this->m_MeasurementsBuffer.pop_front();
	return point;
}
		
void LidarLiteClass::onLidarStateMeasurementCompleted(uint32_t now)
{
	// request 3 bytes from LIDAR-Lite
	uint8_t readed = this->m_I2C_interface.requestFrom((int)this->m_Addr, (int)3);

	if (readed == 3 && this->m_I2C_interface.available() == 3)
	{
		LidarLitePoint point;
		point.timestamp_us = this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS];
		point.intensity = this->m_I2C_interface.read();
		point.range.raw[1] = this->m_I2C_interface.read();
		point.range.raw[0] = this->m_I2C_interface.read();

		++(this->m_SuccessfulMeasurements);
		
		if (this->m_MeasurementsBuffer.size() < this->m_MeasurementBufferMaxSize)
		{
			//	There is free space in buffer : add point
			this->m_MeasurementsBuffer.push_back(point);
		}
		else if (this->m_onMeasurementBufferOverflowCallback != 0)
		{
			//	Buffer is full and a user callback is provided
			this->m_onMeasurementBufferOverflowCallback(point);
		}
		else
		{
			//	Buffer is full and no user callback is provided : through away oldest measurements
			this->m_MeasurementsBuffer.pop_front();
			this->m_MeasurementsBuffer.push_back(point);
		}
		
		//	Measurement was successfully retrieved : state transition
		this->m_LidarLiteState = LIDARLITE_STATE_IDLE;
		this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_IDLE] = now;	
	}
	else
	{
		//	Measurement was successfully retrieved : no state transition
		++(this->m_FailedMeasurements);
	}
}

bool LidarLiteClass::isLidarLiteAlive(uint32_t &now)
{
	now = micros();
	uint32_t elapsed_time_in_state = now - m_TimeOfLastTransitionToState[this->m_LidarLiteState];
	if (elapsed_time_in_state > 2000000)	//	Max time without measurement : 2 s
	{
		if (this->m_onHarwareResetCallback != 0)
		{
			//Serial.println("LidarLite seems dead : should do hardware reset");
			this->m_onHarwareResetCallback();
		}
		else // default callback : warning message
		{
			Serial.println("LidarLite seems unresponsive : should do hardware reset but callback is not implemented");
		}
		return false;
	}
	else if ((elapsed_time_in_state > this->m_MaxTimeAllowedInState[this->m_LidarLiteState]) &&
         	 (this->m_LidarLiteState != LIDARLITE_STATE_UNKNOWN) &&
			 (this->m_LidarLiteState != LIDARLITE_STATE_RESETTING))
	{
		//	Triggering a FPGA reset = soft reset
		
		//Serial.print("LidarLite seems hanging :  triggering FPGA reset...");
		//Serial.println(this->m_LidarLiteState);

		this->m_LidarLiteState = LIDARLITE_STATE_UNKNOWN;
		this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_UNKNOWN] = now;		

		return true;
	}
	else
	{
		return true;
	}
}

Modified Wire.h
Code:
/*
 * TwoWire.h - TWI/I2C library for Arduino Due
 * Copyright (c) 2011 Cristian Maglie <c.maglie@arduino.cc>
 * All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef TwoWire_h
#define TwoWire_h

// Include Atmel CMSIS driver
#include <include/twi.h>

#include "Stream.h"
#include "variant.h"

#define BUFFER_LENGTH 32

class TwoWire : public Stream {
public:
	TwoWire(Twi *twi, void(*begin_cb)(void));
	void begin();
	void begin(uint8_t);
	void begin(int);
	void setClock(uint32_t);
	void beginTransmission(uint8_t);
	void beginTransmission(int);
	uint8_t endTransmission(void);
    uint8_t endTransmission(uint8_t);
	uint8_t requestFrom(uint8_t, uint8_t);
    uint8_t requestFrom(uint8_t, uint8_t, uint8_t);
	uint8_t requestFrom(int, int);
    uint8_t requestFrom(int, int, int);
	virtual size_t write(uint8_t);
	virtual size_t write(const uint8_t *, size_t);
	virtual int available(void);
	virtual int read(void);
	virtual int peek(void);
	virtual void flush(void);
	void onReceive(void(*)(int));
	void onRequest(void(*)(void));

	uint32_t getTxTimeOut(void) const;
	uint32_t getRxTimeOut(void) const;
	void setTxTimeOut(uint32_t timeout_us);
	void setRxTimeOut(uint32_t timeout_us);
	
    inline size_t write(unsigned long n) { return write((uint8_t)n); }
    inline size_t write(long n) { return write((uint8_t)n); }
    inline size_t write(unsigned int n) { return write((uint8_t)n); }
    inline size_t write(int n) { return write((uint8_t)n); }
    using Print::write;

	void onService(void);

private:
	// RX Buffer
	uint8_t rxBuffer[BUFFER_LENGTH];
	uint8_t rxBufferIndex;
	uint8_t rxBufferLength;

	// TX Buffer
	uint8_t txAddress;
	uint8_t txBuffer[BUFFER_LENGTH];
	uint8_t txBufferLength;

	// Service buffer
	uint8_t srvBuffer[BUFFER_LENGTH];
	uint8_t srvBufferIndex;
	uint8_t srvBufferLength;

	// Callback user functions
	void (*onRequestCallback)(void);
	void (*onReceiveCallback)(int);

	// Called before initialization
	void (*onBeginCallback)(void);

	// TWI instance
	Twi *twi;

	// TWI state
	enum TwoWireStatus {
		UNINITIALIZED,
		MASTER_IDLE,
		MASTER_SEND,
		MASTER_RECV,
		SLAVE_IDLE,
		SLAVE_RECV,
		SLAVE_SEND
	};
	TwoWireStatus status;

	// TWI clock frequency
	static const uint32_t TWI_CLOCK = 100000;
	uint32_t twiClock;

	// Timeouts (
	uint32_t RECV_TIMEOUT;
	uint32_t XMIT_TIMEOUT;
};

#if WIRE_INTERFACES_COUNT > 0
extern TwoWire Wire;
#endif
#if WIRE_INTERFACES_COUNT > 1
extern TwoWire Wire1;
#endif

#endif

Modified Wire.cpp
Code:
/*
 * TwoWire.h - TWI/I2C library for Arduino Due
 * Copyright (c) 2011 Cristian Maglie <c.maglie@arduino.cc>
 * All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

extern "C" {
#include <string.h>
}

#include "Wire.h"

static inline bool TWI_FailedAcknowledge(Twi *pTwi) {
	return pTwi->TWI_SR & TWI_SR_NACK;
}

static inline bool TWI_WaitTransferComplete(Twi *_twi, uint32_t _timeout) {
	uint32_t _status_reg = 0;
	while ((_status_reg & TWI_SR_TXCOMP) != TWI_SR_TXCOMP) {
		_status_reg = TWI_GetStatus(_twi);

		if (_status_reg & TWI_SR_NACK)
			return false;

		if (--_timeout == 0)
			return false;
	}
	return true;
}

static inline bool TWI_WaitByteSent(Twi *_twi, uint32_t _timeout) {
	uint32_t _status_reg = 0;
	while ((_status_reg & TWI_SR_TXRDY) != TWI_SR_TXRDY) {
		_status_reg = TWI_GetStatus(_twi);

		if (_status_reg & TWI_SR_NACK)
			return false;

		if (--_timeout == 0)
			return false;
	}

	return true;
}

static inline bool TWI_WaitByteReceived(Twi *_twi, uint32_t _timeout) {
	uint32_t _status_reg = 0;
	while ((_status_reg & TWI_SR_RXRDY) != TWI_SR_RXRDY) {
		_status_reg = TWI_GetStatus(_twi);

		if (_status_reg & TWI_SR_NACK)
			return false;

		if (--_timeout == 0)
			return false;
	}

	return true;
}

static inline bool TWI_STATUS_SVREAD(uint32_t status) {
	return (status & TWI_SR_SVREAD) == TWI_SR_SVREAD;
}

static inline bool TWI_STATUS_SVACC(uint32_t status) {
	return (status & TWI_SR_SVACC) == TWI_SR_SVACC;
}

static inline bool TWI_STATUS_GACC(uint32_t status) {
	return (status & TWI_SR_GACC) == TWI_SR_GACC;
}

static inline bool TWI_STATUS_EOSACC(uint32_t status) {
	return (status & TWI_SR_EOSACC) == TWI_SR_EOSACC;
}

static inline bool TWI_STATUS_NACK(uint32_t status) {
	return (status & TWI_SR_NACK) == TWI_SR_NACK;
}

TwoWire::TwoWire(Twi *_twi, void(*_beginCb)(void)) :
	twi(_twi), rxBufferIndex(0), rxBufferLength(0), txAddress(0),
			txBufferLength(0), srvBufferIndex(0), srvBufferLength(0), status(
					UNINITIALIZED), onBeginCallback(_beginCb), twiClock(TWI_CLOCK),RECV_TIMEOUT(100000), XMIT_TIMEOUT(100000) {
}

void TwoWire::begin(void) {
	if (onBeginCallback)
		onBeginCallback();

	// Disable PDC channel
	twi->TWI_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;

	TWI_ConfigureMaster(twi, twiClock, VARIANT_MCK);
	status = MASTER_IDLE;
}

uint32_t TwoWire::getTxTimeOut(void) const
{
	return this->XMIT_TIMEOUT;
}

uint32_t TwoWire::getRxTimeOut(void) const
{
	return this->RECV_TIMEOUT;
}

void TwoWire::setTxTimeOut(uint32_t timeout_us)
{
	this->XMIT_TIMEOUT = timeout_us;
}

void TwoWire::setRxTimeOut(uint32_t timeout_us)
{
	this->RECV_TIMEOUT = timeout_us;
}
	
void TwoWire::begin(uint8_t address) {
	if (onBeginCallback)
		onBeginCallback();

	// Disable PDC channel
	twi->TWI_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;

	TWI_ConfigureSlave(twi, address);
	status = SLAVE_IDLE;
	TWI_EnableIt(twi, TWI_IER_SVACC);
	//| TWI_IER_RXRDY | TWI_IER_TXRDY	| TWI_IER_TXCOMP);
}

void TwoWire::begin(int address) {
	begin((uint8_t) address);
}

void TwoWire::setClock(uint32_t frequency) {
	twiClock = frequency;
	TWI_SetClock(twi, twiClock, VARIANT_MCK);
}

uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) {
	if (quantity > BUFFER_LENGTH)
		quantity = BUFFER_LENGTH;

	// perform blocking read into buffer
	int readed = 0;
	TWI_StartRead(twi, address, 0, 0);
	do {
		// Stop condition must be set during the reception of last byte
		if (readed + 1 == quantity)
			TWI_SendSTOPCondition( twi);

		TWI_WaitByteReceived(twi, RECV_TIMEOUT);
		rxBuffer[readed++] = TWI_ReadByte(twi);
	} while (readed < quantity);
	TWI_WaitTransferComplete(twi, RECV_TIMEOUT);

	// set rx buffer iterator vars
	rxBufferIndex = 0;
	rxBufferLength = readed;

	return readed;
}

uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) {
	return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) true);
}

uint8_t TwoWire::requestFrom(int address, int quantity) {
	return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) true);
}

uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop) {
	return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) sendStop);
}

void TwoWire::beginTransmission(uint8_t address) {
	status = MASTER_SEND;

	// save address of target and empty buffer
	txAddress = address;
	txBufferLength = 0;
}

void TwoWire::beginTransmission(int address) {
	beginTransmission((uint8_t) address);
}

//
//	Originally, 'endTransmission' was an f(void) function.
//	It has been modified to take one parameter indicating
//	whether or not a STOP should be performed on the bus.
//	Calling endTransmission(false) allows a sketch to
//	perform a repeated start.
//
//	WARNING: Nothing in the library keeps track of whether
//	the bus tenure has been properly ended with a STOP. It
//	is very possible to leave the bus in a hung state if
//	no call to endTransmission(true) is made. Some I2C
//	devices will behave oddly if they do not see a STOP.
//
uint8_t TwoWire::endTransmission(uint8_t sendStop) {
	uint8_t error = 0;
	// transmit buffer (blocking)
	TWI_StartWrite(twi, txAddress, 0, 0, txBuffer[0]);
	if (!TWI_WaitByteSent(twi, XMIT_TIMEOUT))
		error = 2;	// error, got NACK on address transmit
	
	if (error == 0) {
		uint16_t sent = 1;
		while (sent < txBufferLength) {
			TWI_WriteByte(twi, txBuffer[sent++]);
			if (!TWI_WaitByteSent(twi, XMIT_TIMEOUT))
				error = 3;	// error, got NACK during data transmmit
		}
	}
	
	if (error == 0) {
		TWI_Stop(twi);
		if (!TWI_WaitTransferComplete(twi, XMIT_TIMEOUT))
			error = 4;	// error, finishing up
	}

	txBufferLength = 0;		// empty buffer
	status = MASTER_IDLE;
	return error;
}

//	This provides backwards compatibility with the original
//	definition, and expected behaviour, of endTransmission
//
uint8_t TwoWire::endTransmission(void)
{
	return endTransmission(true);
}

size_t TwoWire::write(uint8_t data) {
	if (status == MASTER_SEND) {
		if (txBufferLength >= BUFFER_LENGTH)
			return 0;
		txBuffer[txBufferLength++] = data;
		return 1;
	} else {
		if (srvBufferLength >= BUFFER_LENGTH)
			return 0;
		srvBuffer[srvBufferLength++] = data;
		return 1;
	}
}

size_t TwoWire::write(const uint8_t *data, size_t quantity) {
	if (status == MASTER_SEND) {
		for (size_t i = 0; i < quantity; ++i) {
			if (txBufferLength >= BUFFER_LENGTH)
				return i;
			txBuffer[txBufferLength++] = data[i];
		}
	} else {
		for (size_t i = 0; i < quantity; ++i) {
			if (srvBufferLength >= BUFFER_LENGTH)
				return i;
			srvBuffer[srvBufferLength++] = data[i];
		}
	}
	return quantity;
}

int TwoWire::available(void) {
	return rxBufferLength - rxBufferIndex;
}

int TwoWire::read(void) {
	if (rxBufferIndex < rxBufferLength)
		return rxBuffer[rxBufferIndex++];
	return -1;
}

int TwoWire::peek(void) {
	if (rxBufferIndex < rxBufferLength)
		return rxBuffer[rxBufferIndex];
	return -1;
}

void TwoWire::flush(void) {
	// Do nothing, use endTransmission(..) to force
	// data transfer.
}

void TwoWire::onReceive(void(*function)(int)) {
	onReceiveCallback = function;
}

void TwoWire::onRequest(void(*function)(void)) {
	onRequestCallback = function;
}

void TwoWire::onService(void) {
	// Retrieve interrupt status
	uint32_t sr = TWI_GetStatus(twi);

	if (status == SLAVE_IDLE && TWI_STATUS_SVACC(sr)) {
		TWI_DisableIt(twi, TWI_IDR_SVACC);
		TWI_EnableIt(twi, TWI_IER_RXRDY | TWI_IER_GACC | TWI_IER_NACK
				| TWI_IER_EOSACC | TWI_IER_SCL_WS | TWI_IER_TXCOMP);

		srvBufferLength = 0;
		srvBufferIndex = 0;

		// Detect if we should go into RECV or SEND status
		// SVREAD==1 means *master* reading -> SLAVE_SEND
		if (!TWI_STATUS_SVREAD(sr)) {
			status = SLAVE_RECV;
		} else {
			status = SLAVE_SEND;

			// Alert calling program to generate a response ASAP
			if (onRequestCallback)
				onRequestCallback();
			else
				// create a default 1-byte response
				write((uint8_t) 0);
		}
	}

	if (status != SLAVE_IDLE) {
		if (TWI_STATUS_TXCOMP(sr) && TWI_STATUS_EOSACC(sr)) {
			if (status == SLAVE_RECV && onReceiveCallback) {
				// Copy data into rxBuffer
				// (allows to receive another packet while the
				// user program reads actual data)
				for (uint8_t i = 0; i < srvBufferLength; ++i)
					rxBuffer[i] = srvBuffer[i];
				rxBufferIndex = 0;
				rxBufferLength = srvBufferLength;

				// Alert calling program
				onReceiveCallback( rxBufferLength);
			}

			// Transfer completed
			TWI_EnableIt(twi, TWI_SR_SVACC);
			TWI_DisableIt(twi, TWI_IDR_RXRDY | TWI_IDR_GACC | TWI_IDR_NACK
					| TWI_IDR_EOSACC | TWI_IDR_SCL_WS | TWI_IER_TXCOMP);
			status = SLAVE_IDLE;
		}
	}

	if (status == SLAVE_RECV) {
		if (TWI_STATUS_RXRDY(sr)) {
			if (srvBufferLength < BUFFER_LENGTH)
				srvBuffer[srvBufferLength++] = TWI_ReadByte(twi);
		}
	}

	if (status == SLAVE_SEND) {
		if (TWI_STATUS_TXRDY(sr) && !TWI_STATUS_NACK(sr)) {
			uint8_t c = 'x';
			if (srvBufferIndex < srvBufferLength)
				c = srvBuffer[srvBufferIndex++];
			TWI_WriteByte(twi, c);
		}
	}
}

#if WIRE_INTERFACES_COUNT > 0
static void Wire_Init(void) {
	pmc_enable_periph_clk(WIRE_INTERFACE_ID);
	PIO_Configure(
			g_APinDescription[PIN_WIRE_SDA].pPort,
			g_APinDescription[PIN_WIRE_SDA].ulPinType,
			g_APinDescription[PIN_WIRE_SDA].ulPin,
			g_APinDescription[PIN_WIRE_SDA].ulPinConfiguration);
	PIO_Configure(
			g_APinDescription[PIN_WIRE_SCL].pPort,
			g_APinDescription[PIN_WIRE_SCL].ulPinType,
			g_APinDescription[PIN_WIRE_SCL].ulPin,
			g_APinDescription[PIN_WIRE_SCL].ulPinConfiguration);

	NVIC_DisableIRQ(WIRE_ISR_ID);
	NVIC_ClearPendingIRQ(WIRE_ISR_ID);
	NVIC_SetPriority(WIRE_ISR_ID, 0);
	NVIC_EnableIRQ(WIRE_ISR_ID);
}

TwoWire Wire = TwoWire(WIRE_INTERFACE, Wire_Init);

void WIRE_ISR_HANDLER(void) {
	Wire.onService();
}
#endif

#if WIRE_INTERFACES_COUNT > 1
static void Wire1_Init(void) {
	pmc_enable_periph_clk(WIRE1_INTERFACE_ID);
	PIO_Configure(
			g_APinDescription[PIN_WIRE1_SDA].pPort,
			g_APinDescription[PIN_WIRE1_SDA].ulPinType,
			g_APinDescription[PIN_WIRE1_SDA].ulPin,
			g_APinDescription[PIN_WIRE1_SDA].ulPinConfiguration);
	PIO_Configure(
			g_APinDescription[PIN_WIRE1_SCL].pPort,
			g_APinDescription[PIN_WIRE1_SCL].ulPinType,
			g_APinDescription[PIN_WIRE1_SCL].ulPin,
			g_APinDescription[PIN_WIRE1_SCL].ulPinConfiguration);

	NVIC_DisableIRQ(WIRE1_ISR_ID);
	NVIC_ClearPendingIRQ(WIRE1_ISR_ID);
	NVIC_SetPriority(WIRE1_ISR_ID, 0);
	NVIC_EnableIRQ(WIRE1_ISR_ID);
}

TwoWire Wire1 = TwoWire(WIRE1_INTERFACE, Wire1_Init);

void WIRE1_ISR_HANDLER(void) {
	Wire1.onService();
}
#endif

please provide your feedback if testing...

Regards,

Mathieu
 
How quickly are you reading (how many output samples per second)? The problems seem to happen when you push the sensor towards its maximum rate near 100 samples per second. If you do only 10 readings per second, it gives you fewer problems.
 
On my Due, with stock Wire library and the following version 2 library and sketch, system hase been working "steadily" at about 120Hz (at least as reported by the sketch if i'm not wrong in the computations) for 6h.
I'm using an external Terminal TeraTerm to read the values from the serial link, I found that after some time, it seems that the serial window from Arduino IDE itself has some issues...
From time to time, I'm seeing some "reset message" and also, i've been trying to implement reading of other status words and found out some strange values... I'm wondering if the documentation is up to date.

I hope that other users will be able to test / adapt with other platforms) and report / improve this code... Maybe pulselight3d will provide support too.

Regards

Sketch : newLidarLib.ino version 2
Code:
/* 

This sketch demonstrates getting measurement with the PulseLight3d Sensor by http://pulsedlight3d.com

It uses LidarLite library by Mathieu Peyrega (mathieu.peyrega@gmail.com)
tests were performed with Arduino Dua and 1.6.4 standard Wire library
and also with a slightly modified Wire library to allow customized TX and RX timeouts on I2C calls

Version 2.0 : hardware reset callback

Pin 2 of LidarLite is linked to pin 28 of Due in order to provide a hardware reset when the device stops
responding

*/

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

LidarLiteClass theLidar; //  LidarLite Object with default parameters : linked to address 0x62 / I2C interface Wire / measurement buffer size : 100

void setup() {

  pinMode(28,OUTPUT);
  digitalWrite(28,HIGH);
  delay(50);
  
  Serial.begin(115200);
  delay(50);
  
  //Wire.setTxTimeOut(2000);    //  Uncomment if using the slightly modified Wire library to allow custom I2C timeouts
  //Wire.setRxTimeOut(2000);    //
  
  Wire.begin();
  delay(50);
  
  theLidar.registerMeasurementBufferOverflowCallback(&onBufferOverFlowExample);
  theLidar.registerHardwareResetCallback(&lidarHardwareReset);
}

void loop()
{
    theLidar.tick();
    
    /*  Uncomment to consume measurements as they show up otherwise the buffer overflow callback will be called
    while (theLidar.measurementIsAvailable())
    {
        LidarLitePoint point = theLidar.popOneMeasurementFromBuffer();
        Serial.println(point.range.val);
      
    }
    */
}

void onBufferOverFlowExample(LidarLitePoint point)
{
  LidarLitePoint oldestpoint = theLidar.popOneMeasurementFromBuffer();
  uint32_t sum = oldestpoint.range.val;
  uint32_t oldest_timestamp = oldestpoint.timestamp_us;
  uint32_t i = 1;
  uint16_t maxrange = sum;
  uint16_t minrange = sum;
  
  LidarLitePoint temp_point;
  
  while (theLidar.measurementIsAvailable())
  {
    ++i;
    temp_point = theLidar.popOneMeasurementFromBuffer();
    sum += temp_point.range.val;
    if (temp_point.range.val < minrange)
    {
      minrange = temp_point.range.val;
    }
    
    if (temp_point.range.val > maxrange)
    {
      maxrange = temp_point.range.val;
    }
  }
  
  sum += point.range.val;
  
  float mean_dist = sum / (float)(i+1);
  uint32_t delta_t = point.timestamp_us - oldest_timestamp;
  float frequency = (float)(1000000*i)/(float)delta_t;
  
  Serial.print("Mean distance\t:\t");
  Serial.print(mean_dist);
  Serial.print("\tMeas frequency\t:\t");
  Serial.print(frequency);
  Serial.print("\tMin range\t:\t");
  Serial.print(minrange);
  Serial.print("\tMax range\t:\t");
  Serial.println(maxrange);  
}

//  LidarHardwareReset : so far this callback is blocking due to the delay...
//  TODO : try implementing a non blocking mechanism
void lidarHardwareReset()
{
  Serial.println("Hardware Reset");
  digitalWrite(28,LOW);
  delay(50);
  digitalWrite(28,HIGH); 
  delay(50);
}

LidarLite.h
Code:
/*
 * LidarLite.h - PulseLight3d LidarLite library for Arduino Due
 * Copyright (c) 2015 Mathieu Peyrega <mathieu.peyrega@gmail.com>
 * All rights reserved.
 *
 * Version 2.0
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef _LIDARLITE_H_
#define _LIDARLITE_H_	1

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

#define	LIDARLITE_I2C_ADDRESS   (uint8_t)0x62

#define LIDARLITE_COMMAND_REGISTER (uint8_t)0x00
#define LIDARLITE_COMMAND_RESET_FPGA (uint8_t)0x00
#define LIDARLITE_COMMAND_START_MEASUREMENT (uint8_t)0x04
#define LIDARLITE_MAXACQUITION_REGISTER (uint8_t)0x02

//#define LIDARLITE_INTENSITY_DISTANCE_REGISTER (uint8_t)0x8e
#define LIDARLITE_INTENSITY_DISTANCE_REGISTER (uint8_t)0x81

//	LidarLite state machine status
#define LIDARLITE_MAX_STATES      5
#define LIDARLITE_STATE_UNKNOWN   (uint8_t)0x00
#define LIDARLITE_STATE_RESETTING (uint8_t)0x01
#define LIDARLITE_STATE_IDLE      (uint8_t)0x02
#define LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS (uint8_t)0x03
#define LIDARLITE_STATE_MEASUREMENT_COMPLETED   (uint8_t)0x04

#include <deque>

struct LidarLitePoint
{
	uint32_t timestamp_us = 0;
	union {uint16_t val; uint8_t raw[2]; } range = { 0 };
	uint8_t  intensity = 0;
};

class LidarLiteClass
{
	public:
		LidarLiteClass(uint16_t measurementbuffermaxsize = 100, uint8_t addr = LIDARLITE_I2C_ADDRESS, TwoWire& I2C_interface = Wire);

		void tick();
		void init();
		
		bool measurementIsAvailable(void);
		LidarLitePoint popOneMeasurementFromBuffer(void);
		
		void registerFPGAResetCallback(void(*FPGA_reset_cb)(void));
		void registerHardwareResetCallback(void(*hardware_reset_cb)(void));
		void registerMeasurementAvailableCallback(void(*onemeasurement_available_cb)(void));		
		void registerMeasurementBufferOverflowCallback(void(*buffer_overflow_cb)(LidarLitePoint unbuffered_point));
		void registerMeasurementMeasurementInvalidCallback(void(*measurement_invalid_cb)(void));
		
	private:
	    uint8_t m_Addr;
		TwoWire& m_I2C_interface;
		uint8_t m_LidarLiteState;
		uint32_t m_SuccessfulMeasurements;
		uint32_t m_FailedMeasurements;
		uint32_t m_ResetCounts;
		uint32_t m_TimeOfLastTransitionToState[LIDARLITE_MAX_STATES];
		uint32_t m_TimeOfLastCallToStateHandler[LIDARLITE_MAX_STATES];
		uint32_t m_MaxTimeAllowedInState[LIDARLITE_MAX_STATES];
		uint32_t m_MinTimeAllowedInState[LIDARLITE_MAX_STATES];
		uint32_t m_MinTimeBetweenCallsToStateHandler[LIDARLITE_MAX_STATES];
		
		void (*m_onFPGAResetCallback)(void);
		void (*m_onHarwareResetCallback)(void);
		void (*m_onMeasurementAvailableCallback)(void);
		void (*m_onMeasurementBufferOverflowCallback)(LidarLitePoint unbuffered_point);
		void (*m_onMeasurementInvalidCallback)(void);
		
		void onLidarStateUnknown();
		void onLidarStateResetting();
		void onLidarStateIdle();
		void onLidarStateMeasurementInProgress();
		void onLidarStateMeasurementCompleted();
		
		bool isLidarLiteAlive();
		
		std::deque<LidarLitePoint> m_MeasurementsBuffer;
		uint16_t m_MeasurementBufferMaxSize;
		
};	//	class LidarLiteClass

#endif

LidarLite.cpp
Code:
/*
 * LidarLite.h - PulseLight3d LidarLite library for Arduino Due
 * Copyright (c) 2015 Mathieu Peyrega <mathieu.peyrega@gmail.com>
 * All rights reserved.
 *
 * Version 2.0
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
#include "LidarLite.h"

LidarLiteClass::LidarLiteClass(uint16_t measurementbuffermaxsize, uint8_t addr, TwoWire& I2C_interface)
:m_Addr(addr),
m_I2C_interface(I2C_interface),
m_LidarLiteState(LIDARLITE_STATE_UNKNOWN),
m_SuccessfulMeasurements(0),
m_FailedMeasurements(0),
m_ResetCounts(0),
m_onFPGAResetCallback(0),
m_onHarwareResetCallback(0),
m_onMeasurementAvailableCallback(0),
m_onMeasurementBufferOverflowCallback(0),
m_onMeasurementInvalidCallback(0),
m_MeasurementBufferMaxSize(measurementbuffermaxsize)
{
}

void LidarLiteClass::init()
{
	++this->m_ResetCounts;
	if ((this->m_ResetCounts % 10 == 0) && this->m_onHarwareResetCallback != 0)
	{
		this->m_onHarwareResetCallback();
	}
	m_MeasurementsBuffer.clear();
	
	m_LidarLiteState = LIDARLITE_STATE_UNKNOWN;
	
	uint32_t now = micros();
	
	//	0
	this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_UNKNOWN] = now;
	this->m_TimeOfLastCallToStateHandler[LIDARLITE_STATE_UNKNOWN] = 0;
	this->m_MaxTimeAllowedInState[LIDARLITE_STATE_UNKNOWN] = 1000000;
	this->m_MinTimeAllowedInState[LIDARLITE_STATE_UNKNOWN] = 2500;
	this->m_MinTimeBetweenCallsToStateHandler[LIDARLITE_STATE_UNKNOWN] = 2500;
	
	//	1
	this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_RESETTING] = now;
	this->m_TimeOfLastCallToStateHandler[LIDARLITE_STATE_RESETTING] = 0;
	this->m_MaxTimeAllowedInState[LIDARLITE_STATE_RESETTING] = 5000;
	this->m_MinTimeAllowedInState[LIDARLITE_STATE_RESETTING] = 0;
	this->m_MinTimeBetweenCallsToStateHandler[LIDARLITE_STATE_RESETTING] = 1;
	
	//	2
	this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_IDLE] = now;
	this->m_TimeOfLastCallToStateHandler[LIDARLITE_STATE_IDLE] = 0;
	this->m_MaxTimeAllowedInState[LIDARLITE_STATE_IDLE] = 30000;	//	On Due, increasing this value seems to add stability with little impact on measurement frequency
	this->m_MinTimeAllowedInState[LIDARLITE_STATE_IDLE] = 10;//0; //10;
	this->m_MinTimeBetweenCallsToStateHandler[LIDARLITE_STATE_IDLE] = 50; //100; //500;
	
	//	3
	this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS] = now;
	this->m_TimeOfLastCallToStateHandler[LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS] = 0;
	this->m_MaxTimeAllowedInState[LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS] = 30000; //25000;
	this->m_MinTimeAllowedInState[LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS] = 50; //50; //100;
	this->m_MinTimeBetweenCallsToStateHandler[LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS] = 250; //250; //250;
	
	//	4
	this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_MEASUREMENT_COMPLETED] = now;
	this->m_TimeOfLastCallToStateHandler[LIDARLITE_STATE_MEASUREMENT_COMPLETED] = 0;
	this->m_MaxTimeAllowedInState[LIDARLITE_STATE_MEASUREMENT_COMPLETED] = 30000; //25000;
	this->m_MinTimeAllowedInState[LIDARLITE_STATE_MEASUREMENT_COMPLETED] = 100; //100;
	this->m_MinTimeBetweenCallsToStateHandler[LIDARLITE_STATE_MEASUREMENT_COMPLETED] = 250; //250;

	this->m_I2C_interface.beginTransmission(this->m_Addr);
	this->m_I2C_interface.write(LIDARLITE_COMMAND_REGISTER);
	this->m_I2C_interface.write(LIDARLITE_COMMAND_RESET_FPGA);
	//this->m_I2C_interface.write(LIDARLITE_MAXACQUITION_REGISTER);
	//this->m_I2C_interface.write(0x80);
	if (this->m_I2C_interface.endTransmission() == 0)
	{
		//	Reset FPGA command successful : state transition
		this->m_LidarLiteState = LIDARLITE_STATE_RESETTING;
		this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_RESETTING] = micros();
	}
}

void LidarLiteClass::tick()
{

	if (this->isLidarLiteAlive())   //	Test if we had no state transition for a long time
	{	                            //	which is a good clue of lidar lite hanging
		uint32_t now = micros();
		//bool test1 = (now - this->m_TimeOfLastTransitionToState[this->m_LidarLiteState])  > this->m_MinTimeAllowedInState[this->m_LidarLiteState];
		//bool test2 = (now - this->m_TimeOfLastCallToStateHandler[this->m_LidarLiteState]) > this->m_MinTimeBetweenCallsToStateHandler[this->m_LidarLiteState];
		//bool test3 = (this->m_TimeOfLastCallToStateHandler[this->m_LidarLiteState] == 0);
		
		//if (test1 && (test2 || test3))
		if (((now - this->m_TimeOfLastTransitionToState[this->m_LidarLiteState])  > this->m_MinTimeAllowedInState[this->m_LidarLiteState]) &&
		   (((now - this->m_TimeOfLastCallToStateHandler[this->m_LidarLiteState]) > this->m_MinTimeBetweenCallsToStateHandler[this->m_LidarLiteState]) ||
		   ((this->m_TimeOfLastCallToStateHandler[this->m_LidarLiteState] == 0))))	
		{
			this->m_TimeOfLastCallToStateHandler[this->m_LidarLiteState] = micros();
			switch(this->m_LidarLiteState)
			{
				case LIDARLITE_STATE_UNKNOWN:
				this->onLidarStateUnknown();
				break;
				
				case LIDARLITE_STATE_RESETTING:
				this->onLidarStateResetting();
				break;
				
				case LIDARLITE_STATE_IDLE:
				this->onLidarStateIdle();
				break;
				
				case LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS:
				this->onLidarStateMeasurementInProgress();
				break;
				
				case LIDARLITE_STATE_MEASUREMENT_COMPLETED:
				this->onLidarStateMeasurementCompleted();
				break;
				
				default:
				break;
			}
		}
	}
}

void LidarLiteClass::registerFPGAResetCallback(void(*FPGA_reset_cb)(void))
{
	this->m_onFPGAResetCallback = FPGA_reset_cb;
}
		
void LidarLiteClass::registerHardwareResetCallback(void(*hardware_reset_cb)(void))
{
	this->m_onHarwareResetCallback = hardware_reset_cb;
}

void LidarLiteClass::registerMeasurementAvailableCallback(void(*onemeasurement_available_cb)(void))
{
	this->m_onMeasurementAvailableCallback = onemeasurement_available_cb;
}
		
void LidarLiteClass::registerMeasurementBufferOverflowCallback(void(*buffer_overflow_cb)(LidarLitePoint unbuffered_point))
{
	this->m_onMeasurementBufferOverflowCallback = buffer_overflow_cb;
}

void LidarLiteClass::LidarLiteClass::registerMeasurementMeasurementInvalidCallback(void(*measurement_invalid_cb)(void))
{
	this->m_onMeasurementInvalidCallback = measurement_invalid_cb;
}
		
void LidarLiteClass::onLidarStateUnknown(void)
{
	this->init();
}

void LidarLiteClass::onLidarStateResetting(void)
{
	this->m_I2C_interface.beginTransmission(this->m_Addr);
	this->m_I2C_interface.write(LIDARLITE_MAXACQUITION_REGISTER);
	this->m_I2C_interface.write(0x80);
		
	if (this->m_I2C_interface.endTransmission() == 0)
	{	
		this->m_LidarLiteState = LIDARLITE_STATE_IDLE;
		this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_IDLE] = micros();
	}
}

void LidarLiteClass::onLidarStateIdle(void)
{
	//	when the trigger of a new measurement is successful, or at least seems
	//  successful from the returned values of I2C protocol the state will
	//	transition to LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS

	this->m_I2C_interface.beginTransmission(this->m_Addr);
	this->m_I2C_interface.write(LIDARLITE_COMMAND_REGISTER);
	this->m_I2C_interface.write(LIDARLITE_COMMAND_START_MEASUREMENT);
		
	if (this->m_I2C_interface.endTransmission() == 0)
	{
		//	Start measurement successful : state transition
		this->m_LidarLiteState = LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS;
		this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS] = micros();
	}
}

void LidarLiteClass::onLidarStateMeasurementInProgress(void)
{
	//	when a new measurement as been triggered for long enough, we try to read the
	//	result by setting the pointer to the result register
	
	this->m_I2C_interface.beginTransmission(this->m_Addr);
	this->m_I2C_interface.write(LIDARLITE_INTENSITY_DISTANCE_REGISTER);
	if (this->m_I2C_interface.endTransmission() == 0)
	{
		//	Measurement seems successful : state transition
		this->m_LidarLiteState = LIDARLITE_STATE_MEASUREMENT_COMPLETED;
		this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_MEASUREMENT_COMPLETED] = micros();
	}
}

bool LidarLiteClass::measurementIsAvailable(void)
{
	return this->m_MeasurementsBuffer.size() != 0;
}

LidarLitePoint LidarLiteClass::popOneMeasurementFromBuffer(void)
{
	LidarLitePoint point;
	if (this->m_MeasurementsBuffer.size() != 0)
	{
		point = this->m_MeasurementsBuffer.front();
		this->m_MeasurementsBuffer.pop_front();
	}
	else
	{
		Serial.println("LidarLiteClass Error : reading empty buffer");
	}
	return point;
}
		
/*		
void LidarLiteClass::onLidarStateMeasurementCompleted(void)
{
	// request 3 bytes from LIDAR-Lite
	uint8_t readed = this->m_I2C_interface.requestFrom((int)this->m_Addr, (int)3);

	if (readed == 3 && this->m_I2C_interface.available() == 3)
	{
		LidarLitePoint point;
		point.timestamp_us = this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS];
		point.intensity = this->m_I2C_interface.read();
		point.range.raw[1] = this->m_I2C_interface.read();
		point.range.raw[0] = this->m_I2C_interface.read();

		bool test1 = (point.range.raw[1]&0x80) != 0x80;
		bool test2 = point.range.val != 0;
		//bool test3 = point.range.val != 1023;
		//bool test4 = point.range.val != 2047;		
		if (test1 && test2)
		{
			++(this->m_SuccessfulMeasurements);
			
			if (this->m_MeasurementsBuffer.size() < this->m_MeasurementBufferMaxSize)
			{
				//	There is free space in buffer : add point
				this->m_MeasurementsBuffer.push_back(point);
			}
			else if (this->m_onMeasurementBufferOverflowCallback != 0)
			{
				//	Buffer is full and a user callback is provided
				this->m_onMeasurementBufferOverflowCallback(point);
			}
			else
			{
				//	Buffer is full and no user callback is provided : through away oldest measurements
				this->m_MeasurementsBuffer.pop_front();
				this->m_MeasurementsBuffer.push_back(point);
			}
			
			//	Measurement was successfully retrieved : state transition
			this->m_LidarLiteState = LIDARLITE_STATE_IDLE;
			this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_IDLE] = micros();	
		}
		else
		{
			if (this->m_onMeasurementInvalidCallback != 0)
			{
				this->m_onMeasurementInvalidCallback();
			}
			this->init();
		}
	}
	else
	{
		//	Measurement was not successfully retrieved : no state transition
		++(this->m_FailedMeasurements);
	}
}*/

void LidarLiteClass::onLidarStateMeasurementCompleted(void)
{
	// request 3 bytes from LIDAR-Lite
	uint8_t readed = this->m_I2C_interface.requestFrom((int)this->m_Addr, (int)16, false);

	if (readed == 16 && this->m_I2C_interface.available() == 16)
	{
		uint8_t data[13];
		LidarLitePoint point;
		for(int i=0;i<13;++i)
		{
			data[i] = this->m_I2C_interface.read();
		}
		point.timestamp_us = this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_MEASUREMENT_IN_PROGRESS];
		point.intensity = this->m_I2C_interface.read();
		point.range.raw[1] = this->m_I2C_interface.read();
		point.range.raw[0] = this->m_I2C_interface.read();

		bool test1 = (point.range.raw[1] & 0x80) != 0x80;
		bool test2 = point.range.val != 0;
		
		bool testHealth = ((data[0] & 0x01) == 0);
		bool testSignalIsValid = ((data[0] & 0x08) == 0);
		bool testEyeSafe = ((data[0] & 0x80) != 0);
		bool testMaxAcqCount = (data[1] == 0x80);

		if (test1 && test2 && testSignalIsValid)// && testHealth && testMaxAcqCount && testEyeSafe)
		{
			++(this->m_SuccessfulMeasurements);
			
			if (this->m_MeasurementsBuffer.size() < this->m_MeasurementBufferMaxSize)
			{
				//	There is free space in buffer : add point
				this->m_MeasurementsBuffer.push_back(point);
			}
			else if (this->m_onMeasurementBufferOverflowCallback != 0)
			{
				//	Buffer is full and a user callback is provided
				this->m_onMeasurementBufferOverflowCallback(point);
			}
			else
			{
				//	Buffer is full and no user callback is provided : through away oldest measurements
				this->m_MeasurementsBuffer.pop_front();
				this->m_MeasurementsBuffer.push_back(point);
			}
			
			//	Measurement was successfully retrieved : state transition
			this->m_LidarLiteState = LIDARLITE_STATE_IDLE;
			this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_IDLE] = micros();	
		}
		else
		{
			/*
			Serial.print("test1\t:\t");
			Serial.print(test1);
			Serial.print("\ttest2\t:\t");
			Serial.print(test2);
			Serial.print("\tSignalIsValid\t:\t");
			Serial.print(testSignalIsValid);
			Serial.print("\tMaxCount\t:\t");
			Serial.print(testMaxAcqCount);
			Serial.print("\tHealth\t:\t");
			Serial.print(testHealth);
			Serial.print("\tEyeSafe\t:\t");
			Serial.println(testEyeSafe);
			*/			
			if (this->m_onMeasurementInvalidCallback != 0)
			{
				this->m_onMeasurementInvalidCallback();
			}
			
			//this->init();
			//	Measurement was successfully retrieved even if invalid : state transition
			//this->m_LidarLiteState = LIDARLITE_STATE_IDLE;
			//this->m_TimeOfLastTransitionToState[LIDARLITE_STATE_IDLE] = micros();

		}
	}
	else
	{
		//	Measurement was not successfully retrieved : no state transition
		++(this->m_FailedMeasurements);
	}
}

bool LidarLiteClass::isLidarLiteAlive()
{
	uint32_t elapsed_time_in_state = micros() - m_TimeOfLastTransitionToState[this->m_LidarLiteState];
	if (this->m_LidarLiteState == LIDARLITE_STATE_UNKNOWN)
	{
		return true;
	}
	else if (elapsed_time_in_state > 2000000 )	//	Max time without measurement : 2 s
	{
		if (this->m_onHarwareResetCallback != 0)
		{
			this->m_onHarwareResetCallback();
			this->init();
		}
		else // default callback : warning message
		{
			Serial.println("LidarLite seems unresponsive : should do hardware reset but callback is not implemented");
			this->init();
		}
		return false;
	}
	else if ((elapsed_time_in_state > this->m_MaxTimeAllowedInState[this->m_LidarLiteState]) &&
			 (this->m_LidarLiteState != LIDARLITE_STATE_RESETTING))
	{
		if (this->m_onFPGAResetCallback != 0)
		{
			this->m_onFPGAResetCallback();
		}
		this->init();
		return false;
	}
	else
	{
		return true;
	}
}
 
compile problem

I think relatively few people have been using the C++ Standard Template Library on Teensy. Here's someone who tried; they got the same error as me, and so far there was no reply: https://forum.pjrc.com/threads/28528-Using-STL-provided-in-Teensyduino-in-Arduino-sketches
EDIT: One success reported with STL std::vector at https://forum.pjrc.com/threads/23467-Using-std-vector

Have you tried to compile this code with the Teensyduino IDE? I gather you haven't tried it with a Teensy? When selecting "Aduino Duemilanove" as the target while using Arduino 1.6.1 / Teensy 1.21 (on Windows 7), I get

Code:
In file included from newLidarLite.ino:17:0:
C:\Users\John\Documents\Arduino\libraries\LidarLite/LidarLite.h:50:17: fatal error: deque: No such file or directory
 #include <deque>

even after installing the code from http://andybrown.me.uk/wk/2011/01/15/the-standard-template-library-stl-for-avr-with-c-streams/ in the directory C:\Program Files (x86)\Arduino\hardware\tools\avr\include

If I target the Teensy 3.1, I get a different error:
Code:
C:\Users\John\AppData\Local\Temp\build7254943930283673273.tmp\LidarLite\LidarLite.cpp.o: In function `__gnu_cxx::new_allocator<LidarLitePoint*>::allocate(unsigned int, void const*)':
c:\program files (x86)\arduino\hardware\tools\arm\arm-none-eabi\include\c++\4.8.4\ext/new_allocator.h:102: undefined reference to `std::__throw_bad_alloc()'
collect2.exe: error: ld returned 1 exit status
 
Last edited:
progress; compiled anyway

Not yet tested, but I did get this to compile on T3.1. There was one missing piece I found from https://forum.pjrc.com/threads/23467-Using-std-vector?p=69787&viewfull=1#post69787

I had to insert this code in the LidarLite.cpp library code:
Code:
namespace std {
  void __throw_bad_alloc()
  {
    Serial.println("Unable to allocate memory");
  }

  void __throw_length_error( char const*e )
  {
    Serial.print("Length Error :");
    Serial.println(e);
  }
}
 
not much success yet on T.31

I got it to compile, but it is not quite working. I enabled the commented-out debug code in the LidarLite.cpp library method "onLidarStateMeasurementCompleted()", with result as below.

My main program:
Code:
/* 
uses LidarLite library by Mathieu Peyrega (mathieu.peyrega@gmail.com)
tests were performed with Arduino Due and 1.6.4 standard Wire library
and also with a slightly modified Wire library to allow customized TX and RX timeouts on I2C calls

Version 2.0 : hardware reset callback

Pin 2 of LidarLite is linked to pin ENA_OUT of T3.1 in order to provide a hardware reset when the device stops
responding
*/

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

#define ENA_OUT 23    // connect this pint to LidarLite "PWR_EN" (Pin 2, adjacent to red +5V line)

LidarLiteClass theLidar; //  LidarLite Object with default parameters : linked to address 0x62 / I2C interface Wire / measurement buffer size : 100

void setup() {

  pinMode(ENA_OUT,OUTPUT);
  digitalWrite(ENA_OUT,HIGH);
  delay(50);
  
  Serial.begin(115200);
  delay(2050);
  
  //Wire.setTxTimeOut(2000);    //  Uncomment if using the slightly modified Wire library to allow custom I2C timeouts
  //Wire.setRxTimeOut(2000);    //
  
  Wire.begin();
  delay(50);
  
  theLidar.registerMeasurementBufferOverflowCallback(&onBufferOverFlowExample);
  theLidar.registerHardwareResetCallback(&lidarHardwareReset);
  Serial.println("Starting LIDAR test...");
}

void loop()
{
    theLidar.tick();
    
    // Uncomment to consume measurements as they show up, otherwise the buffer overflow callback will be called
    while (theLidar.measurementIsAvailable())
    {
        LidarLitePoint point = theLidar.popOneMeasurementFromBuffer();
        Serial.println(point.range.val);
    }
   
}

void onBufferOverFlowExample(LidarLitePoint point)
{
  LidarLitePoint oldestpoint = theLidar.popOneMeasurementFromBuffer();
  uint32_t sum = oldestpoint.range.val;
  uint32_t oldest_timestamp = oldestpoint.timestamp_us;
  uint32_t i = 1;
  uint16_t maxrange = sum;
  uint16_t minrange = sum;
  
  LidarLitePoint temp_point;
  
  while (theLidar.measurementIsAvailable())
  {
    ++i;
    temp_point = theLidar.popOneMeasurementFromBuffer();
    sum += temp_point.range.val;
    if (temp_point.range.val < minrange)
    {
      minrange = temp_point.range.val;
    }
    
    if (temp_point.range.val > maxrange)
    {
      maxrange = temp_point.range.val;
    }
  }
  
  sum += point.range.val;
  
  float mean_dist = sum / (float)(i+1);
  uint32_t delta_t = point.timestamp_us - oldest_timestamp;
  float frequency = (float)(1000000*i)/(float)delta_t;
  
  Serial.print("Mean distance\t:\t");
  Serial.print(mean_dist);
  Serial.print("\tMeas frequency\t:\t");
  Serial.print(frequency);
  Serial.print("\tMin range\t:\t");
  Serial.print(minrange);
  Serial.print("\tMax range\t:\t");
  Serial.println(maxrange);  
}

//  LidarHardwareReset : so far this callback is blocking due to the delay...
//  TODO : try implementing a non blocking mechanism
void lidarHardwareReset()
{
  Serial.println("Hardware Reset");
  digitalWrite(ENA_OUT,LOW);
  delay(50);
  digitalWrite(ENA_OUT,HIGH); 
  delay(50);
}

Output (SCL, SDA and T3.1 pin 23 goes to the LidarLite "PWR_ENA" pin 2). It seems to take one measurement but then repeats that value continually; real reads always show at least a few cm of noise from one reading to the next.
Code:
Starting LIDAR test...
220
220
220
220
220
220
220
220
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	0	test2	:	1	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	1
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
220
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	0	test2	:	1	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	1
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	0	test2	:	1	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	1
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
220
220
220
220
220
220
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	0	test2	:	1	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	1
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
220
220
220
220
220
220
220
220
220
220
220
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	0	test2	:	1	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	1
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	0	test2	:	1	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	1
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
220
220
220
220
220
220
220
220
220
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	0	test2	:	1	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	1
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
220
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	0	test2	:	1	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	1
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
220
220
220
220
220
220
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	0	test2	:	1	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	1
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
test1	:	1	test2	:	0	SignalIsValid	:	1	MaxCount	:	0	Health	:	1	EyeSafe	:	0
Hardware Reset
 
Last edited:
My two Lidar-Lite (original version) will deliver results from 9 to 11 msec apart at close range, but 12-15 msec apart at longer ranges (more than 10 m). I suppose weaker signals cause the algorithm to take more samples to get a correlation peak. 500 Hz sounds great but I presume that is at the shorter ranges.
 
Status
Not open for further replies.
Back
Top