Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 6 1 2 3 ... LastLast
Results 1 to 25 of 139

Thread: Translating Lidar Lite I2C example to Teensy

  1. #1

    Translating Lidar Lite I2C example to Teensy

    I am trying to implement this Lidar Lite sketch for Arduino (based on the 'Arduino I2C Master Library' from DSS Circuits). Since this uses features beyond the basic Wire library, i am trying to implement it with the I2C T3 library. Not sure how to mimic the ability to handle Ack detection as well as the combined write read operation. Please see the lidar lite example below.

    Code:
    #include <I2C.h>
    #define    LIDARLite_ADDRESS   0x62          // Default I2C Address of LIDAR-Lite.
    #define    RegisterMeasure     0x00          // Register to write to initiate ranging.
    #define    MeasureValue        0x04          // Value to initiate ranging.
    #define    RegisterHighLowB    0x8f          // Register to get both High and Low bytes in 1 call.
    
    
    void setup(){
      Serial.begin(9600); //Opens serial connection at 9600bps.     
      I2c.begin(); // Opens & joins the irc bus as master
      delay(100); // Waits to make sure everything is powered up before sending or receiving data  
      I2c.timeOut(50); // Sets a timeout to ensure no locking up of sketch if I2C communication fails
    }
    
    void loop(){
      // Write 0x04 to register 0x00
      uint8_t nackack = 100; // Setup variable to hold ACK/NACK resopnses     
      while (nackack != 0){ // While NACK keep going (i.e. continue polling until sucess message (ACK) is received )
        nackack = I2c.write(LIDARLite_ADDRESS,RegisterMeasure, MeasureValue); // Write 0x04 to 0x00
        delay(1); // Wait 1 ms to prevent overpolling
      }
    
      byte distanceArray[2]; // array to store distance bytes from read function
      
      // Read 2byte distance from register 0x8f
      nackack = 100; // Setup variable to hold ACK/NACK resopnses     
      while (nackack != 0){ // While NACK keep going (i.e. continue polling until sucess message (ACK) is received )
        nackack = I2c.read(LIDARLite_ADDRESS,RegisterHighLowB, 2, distanceArray); // Read 2 Bytes from LIDAR-Lite Address and store in array
        delay(1); // Wait 1 ms to prevent overpolling
      }
      int distance = (distanceArray[0] << 8) + distanceArray[1];  // Shift high byte [0] 8 to the left and add low byte [1] to create 16-bit int
      
      // Print Distance
      Serial.println(distance);
    }

  2. #2
    I have an almost working solution, the only problem is the communication will stop responding after some amount of time, usually within a minute or two.

    Code:
    #include <i2c_t3.h>
    #define    LIDARLite_ADDRESS   0x62          // Default I2C Address of LIDAR-Lite.
    #define    RegisterMeasure     0x00          // Register to write to initiate ranging.
    #define    MeasureValue        0x04          // Value to initiate ranging.
    #define    RegisterHighLowB    0x8f          // Register to get both High and Low bytes in 1 call.
    
    elapsedMillis sincePrint;
    
    void setup()
    {
      Wire.begin(); // join i2c bus
      Serial1.begin(115200); // start serial communication at 9600bps
    }
    
    
    void loop(){
      int out ;
      Serial1.print(sincePrint);
      sincePrint = 0;
      Serial1.print(">");
      Serial1.println(out = readDistance());
      if (out == 0){
        delay(5000);
      }
    }
    
    int readDistance(){
      uint8_t nackack = 100; // Setup variable to hold ACK/NACK resopnses     
      while (nackack != 0){ // While NACK keep going (i.e. continue polling until sucess message (ACK) is received )
       delay(1); // Wait 1 ms to prevent overpolling
        Wire.beginTransmission(LIDARLite_ADDRESS);
        Wire.write(RegisterMeasure);
        Wire.write(MeasureValue);
        nackack = Wire.endTransmission(I2C_STOP,10000);
        if (nackack!=0){
            Serial1.print("A");
            }
        
      }
    
     
      nackack = 100;
      uint8_t trys = 0;
      while (nackack != 0){ 
        if (trys>30){
          return 0 ;
        }
        trys++;
      delay(1);
        Wire.beginTransmission(LIDARLite_ADDRESS);
        Wire.write(RegisterHighLowB);
        nackack = Wire.endTransmission(I2C_STOP,10000);
        if (nackack!=0){
          Serial1.print("C");
          continue;
        }
        Wire.requestFrom(LIDARLite_ADDRESS,2,I2C_STOP,10000);
      }
      while (Wire.available()<2){
        Serial1.print("D");
        delay(1);
      }
    
      int reading = Wire.readByte() ;
      reading = reading << 8;
      reading |= Wire.readByte();
      return reading;
     
    }

  3. #3
    Senior Member
    Join Date
    Jan 2013
    Posts
    966
    How have you connected the sensor to the Teensy ?

  4. #4
    Quote Originally Posted by Headroom View Post
    How have you connected the sensor to the Teensy ?
    For testing I have the Teensy powered by USB and the Lidar wires connected in a breadboard with the teensy.
    Lidar -- Teensy
    5v -> Vin
    SDA -> SDA0(18)
    SCL -> SCL0(19)
    GND -> GND (first pin top row)
    pwr en // NC
    Mode // NC

  5. #5
    Senior Member
    Join Date
    Jan 2013
    Posts
    966
    Are you using pull-up resistors ?

  6. #6
    I am now, and everything is working great. Using 4.5k resistors between the 3.3v pin and SCL0 and SDA0. Thanks!
    Edit .. almost great ... it froze up again .. the Lidar never acking the second read operation (Serial keeps printing "C");
    Last edited by dmhummel; 03-14-2015 at 01:26 PM.

  7. #7
    Senior Member
    Join Date
    Jan 2013
    Posts
    966
    The LIDAR Lite requires 5V signals.
    The Teensy outputs incl. the I2C pins are only 3.3V signals.

    I'd say you need a logic level converter from 3.3V to 5 V for this to work reliably. You can find several of these, starting with the one on the DSS circuits website. Adafruit sell some as well. Some of them already have pull-up resistors on board so you don't need any additional pull-ups.

  8. #8
    I ran the I2C through an I2C safe logic level converter sparkfun and still fails after a short while. I also dug out an Arduino Uno, loaded the lidar example code and it ran flawlessly for hours.

  9. #9
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,174
    What hardware is needed to run this test?

  10. #10
    It appears the Lidar Lite I2C does operate at 3.3v (also works at 5v).

    Testing so far requires only a Teensy 3.1 and a Lidar Lite unit.

  11. #11
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,174
    Where's the best place to buy one? (in the USA)

  12. #12
    Senior Member
    Join Date
    Jan 2013
    Posts
    966
    Found this on the LIDAR-Lite website after digging a little more. That stuff should in the spec sheet, not somewhere in a FAQ.

    I2C

    The I2C lines are 3.3v. They're setup for 3.3v and 5v operation (5v is converted to 3.3v and the sensor has an interal 4.7K ohm pullup resistor). If you're using a 5v system with only our sensor on the I2C then the 4.7K pullup may be adequate, however if you have multiple sensors on the I2C you may want to use a lower resistance pullup.

    So you are correct. You don't need a level shifter and You may not need a pullup resistor. I am assuming you have all of this on a bread board and your I2C wires are not a meter long ?

    It's time to take out the oscilloscope and the logic analyzer!
    Last edited by Headroom; 03-14-2015 at 06:49 PM.

  13. #13
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,174
    This thing probably draws a large current when the emitter is turned on, so some attention to the power supply would also be wise.

    If those don't work, maybe I'll have to get one of these and test it here.

  14. #14
    Paul,
    I got mine from http://www.trossenrobotics.com/lidar-lite , great guys. Also Sparkfun carries it.
    Headroom,
    I am rather new at this, and haven't quite accumulated that much fancy stuff. I used second teensy and a small LCD display as a very primitive logic analyzer, but my second teensy stopped working, so maybe its time . The nature of this working great for minutes and then degrading and freezing randomly makes me wonder how hard it will be to diagnose.
    Last edited by dmhummel; 03-14-2015 at 07:11 PM.

  15. #15
    Senior Member
    Join Date
    Jan 2013
    Posts
    966
    Looking through your code I see that you don't make use of the return codes of the library functions. My suggestion would be that you serial.print these if they return errors to get a better under standing what happens.

  16. #16
    I think I may have found something. When I plug the Lidar Lite into the 5v Vin (usually powered by USB, but even other sources that can provide more current), the voltage suddenly drops to 4.2-4.4v . The Lidar only draws 80ma at most which seems inline with expectations for this kind of device. How could it still be effecting the voltage so much (even when it is not activated or if I2C is disconnected)? It does this on the Arduino as well, but it doesn't seem to cause issues on that device.

    This is bad, right?

  17. #17
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    595
    This is a very cool widget. I've got a scope and logic analyzer, but I only just ordered one of these lidar-lite devices today from Sparkfun with free shipping, so might take a week or more to get here.

  18. #18
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    595
    Quote Originally Posted by dmhummel View Post
    I think I may have found something. When I plug the Lidar Lite into the 5v Vin (usually powered by USB, but even other sources that can provide more current), the voltage suddenly drops to 4.2-4.4v [...]
    This is bad, right?
    Right. Usually this is caused by an inferior (cheap) USB cable that uses too-small conductors to save money on copper, with a high resistance and thus voltage drop between the source and the load. Sellers often get away with this because most cell phones will still charge through a high-resistance cable, it just takes longer. But USB-powered devices that need a fixed minimum current to work, like a USB hard drive, Raspberry Pi board, LIDAR Lite, etc. will choke if powered from such a cable, regardless of how good the actual supply is.

    See if you can find a shorter, thicker and/or more expensive USB cable. see for example http://www.yoctopuce.com/EN/article/...s-size-matters
    Last edited by JBeale; 03-14-2015 at 08:20 PM.

  19. #19
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,174
    I'm holding off buying one of these, at least for now.

    If the problems remain when it has solid 5V power, please let me know?

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

    more info from diydrones forum

    This may be relevant. Looks like it puts spikes on the +5V supply, and it also has some I2C glitches. Teensy runs at a much faster clock rate than an ATmega-type Arduino and it may be sensitive to fast glitches an Arduino would miss.

    http://diydrones.com/profiles/blogs/...-lidar-lite-90

    Comment by Randy on January 23, 2015 at 5:59pm
    Yes, it's supported in AC3.2. There are a couple of things to be careful of though, it very seriously interferes with the GPS unless a separate BEC is used to power it (as shown on the wiki). Also we've found it needs a cap attached between the 5V and GND lines to reduce the interference.
    We've also recently found that it can cause little blips on the I2C line as it internally switches from a measuring mode to a communication mode. We haven't noticed any inflight issues caused by these I2C glitches and we think these will be fixed in future version of the lidar.

  21. #21
    Thanks everyone for the help - Im new, have too much to learn and really appreciate it. Paul, also thank you for bringing such an affordable and well featured board. I blew up my first teensy with this Lidar (perhaps because of the voltage spikes?) and could afford to risk breaking another. This Lidar is so damn accurate when its working

    I do now have the Lidar running at 5.2v, isolated and with a .1uf capacitor on power. While it may have helped, it did not resolve the I2C issue. Sooner or later, I see the data start to get strange(5x the noise and some completely invalid data) as well as slower overall response times... soon then it never response with an ack. I slowed down the rate of I2C polling to give more consistent response time (I can get it stable at 20ms) and this leads to a longer life, but within 20 minutes it will still fail. I would think the Lidar is completely defective, but it does work on my Uno. Open to try anything any one suggests.

    Code:
    #include <i2c_t3.h>
    #define    LIDARLite_ADDRESS   0x62          // Default I2C Address of LIDAR-Lite.
    #define    RegisterMeasure     0x00          // Register to write to initiate ranging.
    #define    MeasureValue        0x04          // Value to initiate ranging.
    #define    RegisterHighLowB    0x8f          // Register to get both High and Low bytes in 1 call.
    
    elapsedMillis sincePrint;
    
    void setup()
    {
      //Wire.begin(); // join i2c bus
      Wire.begin(I2C_MASTER, 0, I2C_PINS_18_19, I2C_PULLUP_EXT, I2C_RATE_100, I2C_OP_MODE_DMA );
      Serial1.begin(115200); 
      pinMode(13,OUTPUT);
      digitalWrite(13, HIGH);
      delay(100);  // give the lidar time to startup
    }
    
    
    void loop(){
      int out ;
      Serial1.print(sincePrint);
      sincePrint = 0;
    
      Serial1.print(">");
      Serial1.println(out = readDistance());
    
      if (out == 0){
        Serial1.println("Getting sick");
      }
    
    }
    
    int readDistance(){
      uint8_t nackack = 100; // Setup variable to hold ACK/NACK resopnses     
      while (nackack != 0){ // While NACK keep going (i.e. continue polling until sucess message (ACK) is received )
       // Wait 1 ms to prevent overpolling
        Wire.beginTransmission(LIDARLite_ADDRESS);
        Wire.write(RegisterMeasure);
        Wire.write(MeasureValue);
        nackack = Wire.endTransmission(I2C_STOP,1000);
        if (nackack!=0){
            Serial1.print("A");
            Serial1.print(nackack);
            }
      }
      delay(18);
      nackack = 100;
      uint8_t trys = 0;
      while (nackack != 0){ 
    
        Wire.beginTransmission(LIDARLite_ADDRESS);
        Wire.write(RegisterHighLowB);
        nackack = Wire.endTransmission(I2C_STOP,1000);
        delay(1);
        if (nackack!=0){
          Serial1.print("C");
          Serial1.print(nackack);
              delay(1);
          continue;
        }
        Wire.requestFrom(LIDARLite_ADDRESS,2,I2C_STOP,1000);
      }
    
      int reading = Wire.readByte() ;
      reading = reading << 8;
      reading |= Wire.readByte();
      return reading;
     
    }
    Last edited by dmhummel; 03-15-2015 at 04:39 AM.

  22. #22
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,174
    Alright then, I've ordered one from Sparkfun.

  23. #23
    Quote Originally Posted by PaulStoffregen View Post
    Alright then, I've ordered one from Sparkfun.
    Awesome! I will move on to the next part of my project and wait for news.
    Last note, running a primitive version with no polling using the Wire.h library also fails over time.

  24. #24
    Senior Member
    Join Date
    Jan 2013
    Posts
    966
    I still say that you need to look at what errors are returned from the library functions aand in which part of the code.

  25. #25
    Quote Originally Posted by Headroom View Post
    I still say that you need to look at what errors are returned from the library functions aand in which part of the code.
    When the device stops responding, 95% of the time it gets stuck in the part of the code that prints "C" with the error code "4". This, according to the I2C library is a catch all error code "Other Error". It is not the Lidar responding with a NACK code.

Posting Permissions

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