VL6180 RangeFinder Device Code

I translated the arduino code for the vl6180 rangefinder to work with imp. The code is much shorter and more legible, a testament to squirrel and imp’s friendly API. Feel free to use on any of your projects, the code is public. I don’t think there’s a license on the code I translated, but I credited it in the source file.

https://github.com/saferaging/electric-imp-vl6180

Sweet! That part looks so useful :slight_smile:

So I took a stab at using this sensor/library for a project I’m working on. I found that this library resulted in a response of 255 (error) when trying to measure distances > 40mm. An equivalent raspberry pi library was able to measure accurately around 170mm.
I compared the two libraries looking for differences and I saw a few differences in the initiation plus an added method/function to set the scaling (which is called at initialization). Based off what I can understand from the datasheet the Signal to Noise Ratio settings can extend range for accuracy, and it appears this additional function in the rpi library is setting this register.

I tried to translate from c to squirrel, but I’m no expert at either, and I am stuck on this line in particular. The imp is barking about doing a bitwise operation between an int and a bool. I’m guessing that maybe C performs the OR operation on a 1 or 0 based off the comparison? I could be barking up the wrong tree, but I’d really like to get this sensor working on the imp with the range it has with the rpi library.

The line in question from the set_scaling function. Note rce is a value pulled from the IC and new_scaling is an int passed into the function (the rpi library passes a 1).
write_byte(handle,0x2d, (rce & 0xFE) | (new_scaling == 1));
https://raw.githubusercontent.com/leachj/vl6180_pi/master/src/vl6180_pi.c

That really doesn’t seem a nice way of doing things, to be honest, in that code!

Try this:

(rce & 0xfe) | (new_scaling==1?1:0)

…that will translate a true into a 1 and a false into a zero, which is essentially what the C code is doing, but it’s relying on “true” being coerced into a 1 and “false” a zero.

Ahh. A simple and elegant solution. I suspected that’s what the original code was doing, but my lack of C made me unsure.

I’m getting readings now at greater distance, but they are really inaccurate.
So now I’m questioning this piece of code.

void set_scaling(vl6180 handle, int new_scaling){
int scalerValues[] = {0, 253, 127, 84};
if (new_scaling < 1 || new_scaling > 3) { return; }
write_two_bytes(handle,0x96,scalerValues[new_scaling]);
They are passing a 1 into this function, which i would suspect would select the index of 1 for the last line (253). But this seems flawed. There are 4 numbers in the index but the function exits if 0 is passed in without writing any registers. Does C not start the first index at 0?

Yes, C does start at zero, so they are “burning” an int to make the code a bit more elegant.

Note that in squirrel, you would set the array up like this:

local scalerValues = [ 0, 253, 127, 84 ];