Lidar-Lite v3 return always zero with raspberry pi 3

Kristaps,

Any luck fixing this?

Hi,

If the kernel upgrade causes the I2C driver to force repeated starts, then there is not much to be done to use the LIDAR-Lite v3 since it does not support repeated starts at this time.

Therefore, the two main options would be:

  1. Use a previous kernel that does not have this issue (forced repeated starts). Older versions are available here.
  2. Apply a kernel patch to this kernel to remove this issue.

We figure option #1 is the simplest for more people, as #2 requires quite a bit of more knowledge and work.

Sincerely,

Third long-term option – they (engineers/manufacturers) should fix Lidars’ I2C chip in next iteration, as I2C protocol explicitly allows combined R/W. It’s in the spec (and it’s faster + mitigates clock stretching issues).

@krookdfinger I’ll try to dip my hands in this issue tomorrow. This needs to be fixed in kernel module.

This is stupid.

Best,
Kristaps Karlsons

Hi,

The manufacturer of the LIDAR-Lite are looking into accepting repeated starts with the device, but the patch may still take a while.

Sincerely,

it’s unbelievable look like there is no responsibility behind open source product, manufacturer don’t care about their product and Kerner has been updated and no one in the world can run their Lidar lite v3 on Raspberry Pi, I really appreciate if someone can resolve this issue

I fixed it by downgrade my kernel to an old one 4.4.38
on this link I learnt how to do it.

Hey,

Thanks for the good link on the upgrade/downgrade for the kernel. We are certain this will help users who are less knowledgeable about kernel downgrades (or even patching!) to be able to use their LIDAR-Lite v3 properly.

As for your other comments, I’m not too sure what to say. I have a feeling that the repeated start feature of the I2C specification, which was meant to allow a master in a multiple master setup to keep control over the bus, has started to be used by default as a way to save sending a stop condition in single master buses, too. While that is not wrong, it is possible for slaves to require a stop condition in some cases (and sometimes with good reason). This answer here is quite detailed about this. Here’s an excerpt of the answer:

This is most likely the same design idea that went towards the LIDAR-Lite’s handling of I2C communications.

Concerning the kernel patch, well, if it really does force repeated starts (no matter what is requested) - which seems to be the case currently - it most likely needs to be reported as an issue and it can then be patched quickly.

The manufacturer most certainly care about their product, but these things do not change quickly or easily. It must be especially difficult to justify a design change (read: cost/time/effort) to fix something that is not broken and is instead an external issue (other entity’s products/code using repeated starts).

Sincerely,

Thanks Scharette for your descriptive comment, I’m actually new to this so I find that link really easy to use and I though it’s good to share with others.

Taghvaei rocks. I can confirm that this procedure worked on a SD card with the most recent version of Stretch. I have great sadness that I needed to lobotomize my kernel to get the Garmin to work, but great happiness that it is now working.

Hi,

We are glad to have another confirmation that the procedure works.

As for patching the kernel, if you read the post above, you will notice this is a bug in the kernel code that was introduced recently: the code no longer allows you to choose between start/stop and repeated starts. It simply always uses repeated starts no matter what is asked.

So, you are in fact providing help to the kernel, not lobotomizing it! :stuck_out_tongue:

Good luck with your project!

Sincerely,

Does anybody know how to git the version of the file just prior to November 27, 2016?

Have cloned the latest kernel . But, having troubles finding any version of the file other than the latest/head.

Tried using ‘git show’ for the file name but only see the head.

The person who changed the driver, Noralf Trønnes, suggested trying a device overlay and gave the following link:

github.com/raspberrypi/linux/bl … EADME#L699

Bruce

  • The answer is…

Edit /boot/config.txt

Scroll to the bottom of the file.

Add the line:
dtoverlay=i2c_bcm2708

Save the file and reboot.

Done!

The change uses a different driver. It is the driver used in previous versions of Raspberry Pi.

Hi Bruce!

Thanks for the info. That is some good news.

Sincerely,

What happened to my post saying that this is now fixed.

It only requires an edit to a simple file.

Built current version of Raspbian Stretch. It does work with the mod I mentioned above.

Bruce

Hey Bruce,

Not sure what you mean. Would it be this post:

Otherwise, thanks again for confirming this. I am certain it will help many people in the future.

As a side note, the newer version of this product, the LLV3HP RB-Pli-17] will now support repeated starts.

Sincerely,

This overlay change in config.txt doesn’t seem to work on the latest Pi3 B+ and latest Raspian.
There are no BCM2708 chip any more, can the new chip handle the old i2c driver?
And if not, is it really possible to downgrade the kernel anymore?

Good point concerning the BCM2708. We do not know about compatibility between the older driver

The best would be to contact the maintainer of the I2C driver for Raspbian and see with them what the best alternative would be (or if the drivers can simply work with start-command-stop properly and not always use repeated starts).

It should be mentioned that if code calls the drivers for I2C operations requesting no repeated starts (i.e.: full start-instructions-stop commands) and the drivers still uses repeated starts regardless, that should most likely be considered a bug of the drivers.

Not sure concerning kernel downgrades.

Here is my little test program working succesfully with Raspberry 3 B+

import sys
import smbus
import time

bus = smbus.SMBus(1)
LIDAR_ADR=0x62

def measure():
   bus.write_byte_data(LIDAR_ADR,0,4)

   bus.write_byte(LIDAR_ADR, 1)
   while bus.read_byte(LIDAR_ADR) & 1 != 0:
	  pass
	  
   bus.write_byte(LIDAR_ADR, 0xf)
   d=bus.read_byte(LIDAR_ADR)<<8
   bus.write_byte(LIDAR_ADR, 0x10)
   d|=bus.read_byte(LIDAR_ADR)
   
   return d

while True:
   t0=time.time()
   d=measure()
   t1=time.time()
   print "%3d %4d" % ((t1-t0)*1000,d)
3 Likes