Hello all. First time posting on the forum today. I just heard about XOD today and I thought I’d attempt to a get a simple project up and running using this neat tool. As it turns out, it’s not so simple to get I2C device working if there’s no existing patch made for it already.
I tried making my own and I’m having no luck. I’ve read and re-read the datasheet from Garmin, I’ve read and re-read the C++ code from the Garmin Lidar library that works just fine with the Arduino IDE. I’ve read and re-read the I2C doc here on the XOD site. All that reading and re-reading and tinkering hasn’t got my any closer.
I feel like begin-transmission, write-byte, end-transmission, request and read-byte nodes are all easy enough to understand how they should be working. It’s really tough to figure out why they’re not working though.
After looking at the Garmin Datasheet for the Lidar Lite v3, I see the following at the top:
The simplest method of obtaining measurement results from the I2C interface
is as follows:
1 Write 0x04 to register 0x00.
2 Read register 0x01. Repeat until bit 0 (LSB) goes low.
3 Read two bytes from 0x8f (High byte 0x0f then low byte 0x10) to obtain the 16-bit measured distance in centimeters.
And that’s where I get lost. It says to write 0x04 to register 0x00, then read register 0x01 until 0 LSB goes low. It then says to read two bytes from 0x8F. I don’t really understand how to do all that with XOD nodes since the read and write nodes don’t allow me to specify “registers”, only the i2c address of the device.
What would be really great is if someone has a working example of using a Garmin Lidar Lite v3 i2c inside a XOD patch. Any help is appreciated. Thanks.
Thanks for uploading this patch. Looks promising but I couldn’t get it up and running. I tried it on the main computer that I’ve been working through the XOD examples. I also used the same Arduino Uno that I’ve been working through the examples with. Howerver, when I loaded up the patch you provided, I get an error when I try to upload it to the Uno. The error says:
Cannot read property '@@transducer/step' of undefined
The error has no formatter, which is a bug. Report the issue to the XOD developers.
Please see the attached screenshot. Also, I tried installing XOD on a different computer and trying it there. Exact same result. I also loaded up an example patch and tried deploying that to the Uno, which worked just fine.
Any advice you can offer, I’d appreciate. This patch looks very promising. I’m anxious to get it up and running.
Hello again cesars. I appreciate your patience on this. I finally got the code to upload to Arduino with no problem, however, the distance value remains 0 while I run it in debug mode. I’ve looked at the patch, not too deeply but on the surface everything looks to be set just perfect. The i2c address is indeed 62h and everything else in your patch looks right, but distance value remains zero.
Just to be sure my Garmin LidarLite is still working correctly, I uploaded the Garmin LidarLite v3 example code to my Uno and that does again work correctly as expected.
Is there any ideas you have that I can try to figure out why the XOD patch isn’t working? I’ll try fiddling with it some more. I’ve already put nearly a full day into trying to figure this out so I might as well keep pressing on.
Thanks again for spending time on it. I did try running it and using Arduino serial monitor. All I see after reset button is: +XOD:99:13:0.00
I see nothing about the lidar sensor on the monitor window. I’ll monitor this thread and see if you’re able to figure out a fix.
Ok, I think I’ve tracked down where the offending line of code is. I just don’t know what it does or really what it’s supposed to do. Obviously, I don’t know how to fix it. In the C+ code for “distance-lidarlite”: I find this line at the top of the evaluate function:
if (!isInputDirty<input_init>(ctx))
emitValue<output_dev>(ctx, getValue<input_lidarlite>(ctx));
return;
I changed the lines of code by adding a Serial.print() before the if statement and a Serial.print() after the if statement. It now looks like this:
void evaluate(Context ctx) {
Serial.println("Getting Distance ...");
if (!isInputDirty<input_init>(ctx))
emitValue<output_dev>(ctx, getValue<input_lidarlite>(ctx));
return;
Serial.println("Input IS NOT DIRTY");
It looks like the !isInputDirty<input_init>(ctx)) is always true because the first Serial.print() fires once per second (I’m pulsing the init with a 1/s clock node). The second Serial.print() is never printed. I know the init is being pulsed by my clock node since the same clock is also driving an LED on my breadboard as well as the watch node I’ve attached in the IDE.
So my question is, what exactly is !isInputDirty trying to test for? Why does the test always evaluate to true? I’ll keep digging and see what I can figure out, but any help you can offer would be appreciated. Thanks.
if (!isInputDirty<input_init>(ctx))
emitValue<output_dev>(ctx, getValue<input_lidarlite>(ctx));
return;
And now when I run it, I can see the distance values from the Garmin Lidar Lite v3. However, I’d like to actually FIX these lines of code, rather than just comment them out. If anyone has any advice on how to fix this, please share.
Thank you cesars. This one worked right away with no modifications. Just download the file, open it and the measured values are correct with no problems.
I really appreciate you figuring this out.
I also had another question, maybe I should start a new thread for this question. I’m trying to figure out in XOD how to take a bunch of distance measurements and average them in order to be more accurate. This sensor can take a LOT of measurements per second. Even if I took 20 measurements and averaged them, I would still be able to get dozens of averaged measurements per second.
Any thoughts on how to get a a bunch of averaged measurements in XOD?
About 4 months ago I started with XOD and it took me to learn C ++. But the truth is that I’m learning from mistakes, and yesterday I found out about this sensor, but it’s far from my budget to be able to buy one.
There it has two values calc and delay, 100 readings every 10ms, if descativa biasC, it will read directly
I had to translate descativa so I could understand what you mean. I don’t really understand how calc, delay and biasC work but I’ll work it out on my own. You’ve been a big help. You’ve seemed to figure out C++ a lot more than I have. I only started a few days ago. Although I did learn Java a little bit, C++ seems kind of similar. I only just started with Arduino a few days ago. I bought “starter kits” to help me learn how to build stuff. The starter kits come with a bunch of cheap sensors, and the examples do help me understand how to work with Arduino but I have a specific project in mind, which includes scanning objects in 3D. This is why I purchased the Garmin Lidar Lite. It’s actually more expensive than the entire starter kits. If you think you could make good use of a Garmin sensor, just contact me with direct message and I’ll send one to you. That’s appreciation for helping me get this sorted out.
Hi guys
The !isInputDirty If statement is checking if there is any NEW data / update on the pin.
Read it as "If input is not dirty(updated) then execute this command… bearing in mind there is also a return command in that block which prevents the remaining code from being executed and returns back to XOD for other node processing. The reason this code block is not doing what you think, is that the IF command is encompassing all of your code… Use { } to close it off.
if (!isInputDirty<input_init>(ctx)) {
emitValue<output_dev>(ctx, getValue<input_lidarlite>(ctx));
return;
}
``
Your code would always stop at return;