Forum Rule: Always post complete source code & details to reproduce any issue!
Page 5 of 6 FirstFirst ... 3 4 5 6 LastLast
Results 101 to 125 of 139

Thread: Translating Lidar Lite I2C example to Teensy

  1. #101
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    676

    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 by JBeale; 04-10-2015 at 01:44 PM. Reason: add data

  2. #102
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,697
    Just saw this updated WIRE library for LC posted: https://forum.pjrc.com/threads/21680...ll=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.

  3. #103
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    425
    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.

  4. #104
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    676
    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 by JBeale; 04-11-2015 at 02:46 AM.

  5. #105
    Junior Member
    Join Date
    Jan 2014
    Posts
    11
    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

  6. #106
    The LIDAR lite is sensitive for unclear input power. I am using 6800 uF capacitor on 5V

  7. #107
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    676

    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/phot...eat=directlink

  8. #108
    Junior Member
    Join Date
    Jan 2014
    Posts
    11
    Thanks, I'll give that a go.

  9. #109
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    676

    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.

    Click image for larger version. 

Name:	Lidar-352cm_View 2.png 
Views:	119 
Size:	22.4 KB 
ID:	4078Click image for larger version. 

Name:	Lidar-935cm_View 2.png 
Views:	213 
Size:	21.6 KB 
ID:	4079

    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 by JBeale; 04-16-2015 at 03:52 PM.

  10. #110
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,562
    Sounds like the modified Wire.cpp is looking good to put into Teensyduino 1.23 ?!

  11. #111
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    676
    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.

  12. #112
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    676
    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.

  13. #113
    Junior Member
    Join Date
    Jan 2014
    Posts
    11
    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...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.

  14. #114
    Senior Member
    Join Date
    Nov 2012
    Posts
    412
    Since we had a "Hydra smart power supply" laying around we used it for power isolation between the Lidar lite sensor, the CPU and the servo.
    Our "top secret" drone radar detector works fine.


    http://www.chrobotics.com/shop/hydra

  15. #115
    Sounds interesting anything we can use with DroneScan?

  16. #116
    Junior Member
    Join Date
    Jun 2015
    Posts
    2

    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

  17. #117
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    676
    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.

  18. #118
    Junior Member
    Join Date
    Jun 2015
    Posts
    2
    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;
    	}
    }

  19. #119
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    676

    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...duino-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...ith-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 by JBeale; 06-04-2015 at 04:38 PM.

  20. #120
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    676

    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...ll=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);
      }
    }

  21. #121
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    676

    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 by JBeale; 06-05-2015 at 05:02 AM.

  22. #122
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    676
    FYI if anyone else has trouble with their LIDAR-Lite. I now have two units. If my experience is anything to go by, there are "good" units and "bad" units, for example:
    https://forum.sparkfun.com/viewtopic...182609#p182609

  23. #123
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,421
    Another FYI - They are coming out with newer version http://pulsedlight3d.com/ which is supposed to be able to sample at 500hz. I pre-ordered one which shipped Friday. So I will now have one of each.

  24. #124
    Senior Member
    Join Date
    Jan 2013
    Posts
    966
    Let's hope they've got their I2C bus problems under control.

  25. #125
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    676
    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •