Monthly Archives: August 2015

More work on the NEATO XV-11 LIDAR Module

Posted 08/24/2015

Progress on the Pulsed Light ‘Blue Label’ spinning LIDAR system has been put on hold for a few days pending the arrival of some 3mm IR LEDs needed for an upgraded tach sensor wheel, so I am passing the time working on the alternative system, the XV-11 LIDAR module from the NEATO vacuum.

Back in May of this year I posted some results where I mated the Teensy 2.0 based Get Sureal XV-11 module controller (see the post here) and got very good results with a LIDAR ‘image’ of the walls of a cardboard box.  After this effort, I put the XV-11 aside for two reasons; first, I received a ‘Silver Label’ (V1) LIDAR-Lite unit from Pulsed Light and was having too much fun designing and implementing a spinning-LIDAR system, and second, I couldn’t figure out how to get the XV-11 data into my robot controller (an Arduino Uno).  The Teensy 2.0 XV-11 controller parses the data stream from the XV-11, routes it upstream to the USB host, processes commands from the USB host, and maintains the XV-11 rotation speed using a PID controller.  This is all well and good, but the Uno isn’t a USB host, and adding that capability would be a major PITA.  So, I put the whole thing on the back burner, hoping that inspiration would strike at some later date.

Now, almost three months later, I had some ideas I wanted to try to achieve the goal of getting the XV-11 streaming data onto the Uno robot controller so that it could be used for navigation.

The Problem(s):

The XV-11 LIDAR module streams angle, position, data-quality, and RPM information over a serial connection to the Teensy 2.0 controller, and there is a LOT of it.  The XV-11 rotates at a nominal rate of 300 RPM, i.e. 5 RPS.  During every 200 msec rotation, it sends 360 (at least) data groups, where each data group contains pointing angle (0-360), distance (in cm, I think), a data quality metric, and RPM.  Each data group must be parsed to extract the needed information.  The Teensy firmware also provides a PWM waveform to control the XV-11’s rotation speed, based on the RPM values being reported over the serial port.

The Teensy 2.0 boasts two hardware serial ports, but one is used for the connect to the upstream USB host,  and the other one is used to receive the data from the XV-11.  So, no easy way to get the needed XV-11 data from the Teensy to the Uno – bummer :-(.  And, even if the Teensy had a third hardware serial port, the Uno only has one – and it is used to connect to its upstream USB host – double bummer :-(.

And, even if I could figure out a way to get the data over to the Uno, how was I going to keep the data stream from swamping the Uno’s (or the Teensy’s) very finite resources.  With the spinning LIDAR system,  I only capture 18 data groups/revolution, and even this amount threatens to blow out the top of working memory.  There is no way it can handle the 360 data groups from the XV-11.  Moreover, those data groups are arriving at about twice the rate of the groups from the Pulsed Light spinning LIDAR system.

The (partial) Solution – Software Serial to the Rescue!:

In between times where I was actively working on the Pulsed Light spinning LIDAR project, I kept returning to the problem of how to get XV-11 data into the Uno, and in my wanderings through the online Arduino world I ran across references to ‘Software Serial’, where virtual serial ports could be implemented using two of the Arduino GPIO pins.  This sounded intriguing, but all the available libraries come with baggage of one sort or another; one can’t send/receive simultaneously, another can do that, but is sensitive to other interrupts…  Then, just the other day I ran across ‘SimpleSoftSerial’ a version written by ‘Robin2’ just for the Uno (see the post here).  The whole thing is just a ‘.ino’ file, not a library at all, and it does exactly what I want – YAY!  Having the ability to add another serial port to the Uno solves part of the problem, so I decided to see if I could get just this part going, and maybe figure out the data management issue at some future time.

Robin2 also kindly provided a pair of Arduino sketches to demo the ‘Simple SoftSerial’ capability. One part runs on a Uno (of course, as that is the target processor for this little hack) and the other ‘Partner’ program runs on (in his case) a Mega as it requires multiple hardware serial ports.  I didn’t have a Mega handy, but I did have the Teensy 2.0 that came with the Get Sureal XV-11 controller, and it has two hardware serial ports.  So, I disconnected the XV-11 LIDAR module from the Teensy, and temporarily re-purposed it for this test.

I loaded ‘DemoPartner.ino’ onto the Teensy, and ‘DemoSimpleSoftSerial.ino’ onto a spare Uno, connected the two using a pair of jumpers, and voila – it ‘worked’ but only in one direction.  I was able to see characters transmitted on the Uno showing up on the serial monitor port on the Teensy, but not the other way around.  I had previously used my trusty O’scope to probe the pins of the connector from the Teensy to the XV-11 module, and thought that I had determined which pin was Tx and which was Rx, but clearly something wasn’t adding up.  At first I thought I just had a loose connection with my jumper leads, but after some more fiddling, I became convinced that wasn’t the problem.  With my ‘scope,  I probed the actual Teensy board Tx pin (D3), and discovered that the Teensy serial data was there, but it wasn’t making it to the XV-11 connector pin!  Initally this seemed unlikely, as The Teensy/XV-11 combination was working fine – until the realization hit me that the XV-11 is a transmit-only device – there is no serial traffic going from Teensy to XV-11, and therefore there is no need to have the Teensy’s Tx pin connected to the XV-11 connector!  After confirming this theory using a continuity checker, I bypassed the XV-11 connector entirely by soldering a 2-pin header onto the (fortunately side-by-side) Tx & Rx (D3 & D2 respectively) pins of the Teensy module.  Once I made this change, I started seeing bi-directional data transmissions as advertised.

The following photo shows the experimental setup, with the temporarily disconnected XV-11 module in the background.  I have also included a screenshot of the serial port monitors for both the Teensy module (running the ‘Partner’ sketch) and the Uno (running the ‘Demo’ sketch), on two separate instances of Visual Studio 2013/Visual Micro.

Experimental setup. Uno in foreground, Teensy and (temporariliy disconnected) XV-11 LIDAR module in background

Experimental setup. Uno in foreground, Teensy and (temporariliy disconnected) XV-11 LIDAR module in background

Screenshot showing serial port monitors from Uno (bottom) and Teensy (top).

Screenshot showing serial port monitors from Uno (bottom) and Teensy (top).

Now that I have demonstrated the basic Uno virtual serial port capability, I plan to try and use this capability to get XV-11 serial data into my Uno motor controller by piggy-backing on the Teensy 2.0’s serial connection to the XV-11.

My plan is to return the Teensy module back to its original configuration, connected to the XV-11 via its second hardware serial port and running the Get Sureal processing sketch.  Then I’ll put that same sketch on the Uno, but modify it to use the virtual serial port set up via the ‘Simple SoftSerial’ capability.  If I do it correctly, I should be able to see the XV-11 data on both the Teensy 2.0 and Uno USB host serial monitors.

Stay tuned!

Frank

8/25/2015 Late addendum.  Tried that trick and it didn’t work :-(.  Turns out the virtual serial port isn’t anywhere near fast enough.  Advertised speed is 9600 bps, with some speculation that it will work at 14200.  Unfortunately, the XV-11 runs at 115200.  So, I’ll either have to abandon the virtual port idea (and the Uno processor!) or figure out a way of slowing the XV-11 output down, or something else entirely.  Bummer

 

 

 

Under-Counter Heat Gun Holster

Posted 08/18/2015

I have an old Black & Decker paint stripping gun that I have found to be perfect for shrinking heat-shrink tubing on my electronics projects. It’s old and beat up, but it is does that one thing very well.  However, it is big, bulky and its metal tip stays HOT for a long time after use (note the burned rubber/plastic on the tip), so finding a place to put the bloody thing after use has always been a bit of a PITA.

Oldie-but-goody - my trusty B & D paint stripper works perfectly for heat-shrink tubing

Oldie-but-goody – my trusty B & D paint stripper works perfectly for heat-shrink tubing

I was recently re-arranging my office/lab work areas for better efficiency, and I once again ran into the problem of “where do I put this bloody heat gun!”, when I had an epiphany; I have not only one, but TWO 3D printers, and so I should be able to design and print some sort of under counter holster for this thing!

When our Hobbit-house (earth sheltered house) was built way back when, I had my office/lab outfitted with a built-in wrap-around work surface with NO LEGS!  The work surface is supported with 5/16″ steel L-brackets built into the wall structure, so I can roll my work chair from one end to the other with nary a chance of banging my knees – yay!

Anyway, that meant that I had these steel beams in several places along the span of my work surface, and it turned out that one of them was in just the right place to be a convenient under-counter mounting location for my new holster brainstorm.  And as an added bonus, when the heat gun is in the holster, the HOT metal tip would rest against the steel support, not against anything remotely flammable – double yay!

So, now all I had to do was design and print something that would capture the forward body of the gun but still allow for easy insertion & removal.  After a few minutes with my trusty digital calipers and another few minutes on TinkerCad, I had a preliminary design that I thought might work.  I decided to not add a mounting structure in the initial design, as I just wanted to see if I had the dimensions right, and then adjust from there.  With TinkerCad and a 3D printer, you don’t have to be right the first time; if it doesn’t work or isn’t complete – it’s just a few minutes work to adjust the design, and another few minutes (or in the case of the holster – another few hours) to print another iteration; the modern version of ‘cut and try’ is ‘print and try’ ;-).

Version 1 of the heat gun under-counter holster.  I didn't include any mounting provisions on this first version - and it turned out I didn't need any

Version 1 of the heat gun under-counter holster. I didn’t include any mounting provisions on this first version – and it turned out I didn’t need any

The holster was printed in white ABS on my MicroCenter PowerSpec Pro 3D printer.  I used white ABS because that was what was on the printer at the moment  (and I didn’t want to use the brilliant neon magenta ABS stuff I had on the other extruder head).  I assumed I was going to go through several versions (and I still may) so I didn’t really care what I used for the first version.  In any case, the print took about 3 hours (most of which was spent while I was away playing bridge – hee hee).  When I tried the result on my heat gun, it actually fit pretty well.  The holster was just a teeny bit undersized, but the walls were thin enough (and ABS is flexible enough) so that the gun fit easily but tightly; I hadn’t really planned it this way, but I’d rather be lucky than good!

The whole thing worked so well in the initial tests that I decided to try and mount it under the counter on the steel L-bracket as planned.  Instead of my non-existent mounting surface, I drilled some 6-32 holes in the front and rear upper inside corners. The rounded corners of the gun leave a bit of space there, enough so a protruding screw head won’t cause a problem.  The biggest problem was drilling the mounting holes in the steel bracket – a 5/16″ thick piece of steel is not a trivial job!

After getting the first hole in, I noticed that I didn’t really need the second one – the heat gun stays pretty level, and can’t go anywhere, even with just one mounting screw.  The following photos show the installation.  The holster is mounted far enough under the counter that I can roll my chair past this spot without my knees hitting the gun, but still close enough so I can easily remove/insert the gun in the holster.

HeatGunHolster1 HeatGunHolster2 HeatGunHolster3

 

More Pulsed Light ‘Blue Label’ LIDAR testing

Posted 08/18/2015

Well, I have to say that the Pulsed Light tech support has been fantastic as I have been trying to work my way through ‘issues’ with both the V1 ‘Silver Label’ and V2 ‘Blue Label’ LIDAR systems (see my previous posts here and here).  I know they must be thinking “how did we get stuck with this guy – he seems to be able to break anything we send to him!”  I keep expecting them to say “Look – return both units and we’ll give you twice your money back – as long as you promise NOT to buy anything from us ever again!”, but so far that hasn’t happened ;-).

In my last round of emails with Austin (apparently one of two support guys.Bob is the other one, but he is on vacation, so Austin is stuck with me), he mentioned that he had found & fixed a bug or two in the V2 support libraries, and suggested that I download it again and see if that fixes some/all of the issues I’m seeing here with my ‘Blue Label’ V2 unit.

So, I downloaded the new library, loaded up one of my two newly-arrived ‘genuine’ Arduino Uno boards with their ‘Distance As Fast as Possible’ example sketch, and gave it a whirl.  After at least 45 minutes so far of run time, the ‘Blue Label’ unit is still humming along nicely, with no hangups and no dropouts – YAY!!

The  ‘Distance As Fast as Possible’ sketch starts by configuring the LIDAR for lower-than-default acquisition count to speed up the measurement cycle, and increasing the I2C speed to 400 KHz.  Then, in the main loop, it takes one ‘stabilized’ measurement, followed by 100 ‘unstabilized’ measurement.  The idea is that re-stabilization (re-referencing?) isn’t required for every measurement for typical measurement scenarios, so why pay the extra cost in measurement time.  This is certainly true for my wall-following robot application, where typical measurement distances are less than 200 cm and target surfaces are typically white-painted sheet-rock walls.

To get an accurate measurement cycle time, I instrumented the example code with ‘digitalWrite() calls to toggle Arduino Uno pin 12 at appropriate spots in the code.  In the main loop() section the pin goes HIGH just before the single ‘stabilized’ measurement, and LOW immediately thereafter.  Then (after an intermediate Serial.print() statement) it goes HIGH again immediately before the start of the 100-count ‘unstabilized’ measurement loop, and then LOW after all 100 measurements complete.  After another Serial.print() statement the loop() section repeats.

The following O’scope screenshots show the results.  The first one shows the single ‘stabilized’ measurement time, with the scope set for 0.2 msec/div. From the photo, it appears this measurement completes in about 0.8 msec – WOW!!!  The second one shows the time required for 100 ‘unstabilized measurements, with the scope set for 20 msec/div.  From this it appears that 100 measurements take about 140 msec – about 1.4 msec per measurement — WOW WOW!!

 

0.2 msec/div.  HIGH duration is time required for one 'stabilized' measurement

0.2 msec/div. HIGH duration of about 0.8 msec is time required for one ‘stabilized’ measurement

20msec/div.  HIGH duration of about 140 msec shows time required for 100 'unstabilized' measurement

20msec/div. HIGH duration of about 150 msec shows time required for 100 ‘unstabilized’ measurements

Hmm, from the comments in the code, the ‘stabilized’ measurements are supposed to take longer than the ‘unstabilized’ ones – but the scope measurements indicate the opposite – wonder what I’m getting wrong :-(.

I left the LIDAR and Arduino system running for most of a day while I played a duplicate bridge session and did some other errands.  When I got back after about 6 hours, the system was still running and was still responsive when I waved my hand over the optics, but the timing had changed considerably.  Instead of 0.8 msec for the single ‘stabilized’ measurement I was now seeing times in the 3-6 msec range.  For the 100 ‘unstabilized’ measurements, I was now seeing around 325 msec or about 3.2 msec per measurement.  Something had definitely changed, but I have no idea what.  A software restart fixed the problem, and now I’m again looking at 0.8 msec for one ‘stabilized’ measurement, and 150 msec for 100 ‘unstabilized’ ones.

So, the good news is, the new V2 ‘Blue Label’ LIDAR is blindingly fast – I mean REALLY REALLY FAST (like ‘Ludicrous Speed’ in the SpaceBalls movie).  The bad news is, it still seems to slow down A LOT after a while (where ‘while’ seems to be on the order of an hour or so).  However, even at it’s ‘slow’ speed it is pretty damned fast, and still way faster than I need for my spinning LIDAR project.  With this setup I should be able to change from a 10-tooth to at least a 12-tooth (or even a 24-tooth if the photo-sensor setup is sensitive enough) and still keep the 120 rpm motor speed.

Interestingly, I have seen this same sort of slowdown in my V1 (‘Silver Label’) LIDAR testing, so I’m beginning to wonder if the slowdown isn’t more a problem with the Arduino I2C hardware or library implementation.  I can just barely spell ‘I2C’, much less have any familiarity with the hardware/software nuances, but the fact that a software reset affects the timing lends strongly exonerates the LIDAR hardware (the LIDAR can’t know that I rebooted the software) and lends credence to the I2C library as the culprit.

Stay tuned,

Frank

 

 

Pulsed Light ‘Blue Label’ LIDAR Initial Tests

Posted 08/15/15

In my ongoing Sisyphean effort to get Wall-E (my wall-following robot) to actually follow walls, I recently replaced the original three (actually four at one point) acoustic distance sensors  with a spinning-LIDAR system using the Pulsed Light LIDAR-Lite unit.  While this effort was a LOT of fun, and allowed me to also get some good use from my 3D printers, I wasn’t able to reach the goal of improving Wall-E’s wall-following performance.  In fact, wall-following performance was much WORSE – not better.  As described in previous posts, I finally tracked the problem down to too-slow response from the LIDAR unit – it couldn’t keep up with the interrupts from my 10-tooth tach sensor that provides then necessary LIDAR pointing-angle information.  I tried changing the LIDAR over from MODE control to I2C control (see previous posts), but this led to other issues as described, and although I saw some glimmers of success, I’m still not there.

So, when I noticed that Pulsed Light was advertising their new ‘Blue Label’ (V2) version of their LIDAR-Lite unit, with a nominal 5x response time speedup, I immediately ordered one, thinking that was the solution to all my problems.  A 5x speedup should easily be fast enough to enable servicing interrupts at the 25-30 msec time frame required for my spinning LIDAR setup.  I would be home FREE! ;-).

Well, as it turns out, I wasn’t quite home free after all.  As often happens, the reality is a bit more complicated than that.  When I first received my V2 ‘Blue Lable’ unit and made some initial tests, I immediately started having ‘lockup’ problems of one sort or another, even using the Arduino example sketches provided by Pulsed Light, and with a 470 uF BAC  (big-assed capacitor) installed (Pulsed Light operating recommended 680 uF, but 470 was the biggest I had readily available).

The Pulsed Light supplied ‘Distance as fast as Possible’ Arduino sketch makes a single call to the V2 measurement routine with ‘stabilization’ enabled, and then makes another 99 calls to the routine with ‘stabilization’ disabled. The idea is that the extra time required for the stabilization process is only necessary every 100 measurement or so.  The provided test sketch implements a Serial.println() statement for every measurement, but this can quickly overload the serial port and/or PC buffers.  So, I modified the sketch to print the results of the single ‘stabilized’ measurement plus only the last (of 99) ‘unstabilized’ measurements.  This seemed to work *much* better, but then I noticed that the ‘stabilized’ measurement was showing occasional ‘drop-outs’ where the measurement to a constant 60cm distant target was 1 cm instead of 60 cm – strange.

08/11/15 Test with 'Blue Label' LIDAR-Lite.  Target is a constant 60cm away.

08/11/15 Test with ‘Blue Label’ LIDAR-Lite. Target is a constant 60cm away.

I passed this all along to the Pulsed Light folks (Austin and Bob, who have been very responsive the entire time).  They suggested that the smaller cap might be the problem, so I ordered replacements from DigiKey.  When they arrived, I ran the same test again, but this time I not only had the ‘stabilized measurement dropout’ problem, but now the unit was consistently hanging up after a few minutes as well.  More conversation with Austin/Bob indicated that I should try using an external power supply for the Arduino rather than depending on the USB port to supply the necessary current.  So, I made up a power cable so I could run the Uno from my lab power supply and tried again, with basically the same result.  The V2 unit will run normally for a while (with ‘stabilization drop-outs’ as before) and then at some point will go ‘ga-ga’ and start supplying obviously erroneous results, followed at some point by a complete lack of response that requires a power recycle to regain control.

08/15/15 Test with external power supply for Arduino Uno

08/15/15 Test with external power supply for Arduino Uno

V2 'Blue Label' test setup showing BAC (Big-Assed Capacitor) and external power supply connection

V2 ‘Blue Label’ test setup showing BAC (Big-Assed Capacitor) and external power supply connection

V2 'Blue Label' test setup showing BAC (Big-Assed Capacitor) and external power supply connection

V2 ‘Blue Label’ test setup showing BAC (Big-Assed Capacitor) and external power supply connection

All this went back to Austin/Bob for them to cogitate on, and hopefully they will be able to point out what I’m doing wrong.  In the meantime, I have ordered a couple of ‘Genuine’ Arduino Uno boards to guard against the possibility that all these problems are being caused by some deficiency associated with clone Uno’s that won’t be present in ‘genuine’ ones.  A guy can hope, anyways! ;-).

Stay Tuned!

Frank

 

 

I2C Interface Testing for the LIDAR-Lite V1

Posted 08/12/15

In my last post (http://fpaynter.com/2015/08/wall-e-has-more-interrupt-issues/) I found that the Pulsed Light LIDAR-Lite (now called ‘V1’ as there is a new ‘Blue Label’ V2 version out) couldn’t keep up with the pace of hardware interrupts from my 10-tooth tach wheel running at about 120 RPM.  So, I decided to try my luck with the I2C interface, as that was rumored to be somewhat faster than the MODE line interface.  I had resisted doing this as it requires the use of the I2C (or ‘Wire’) library, and I thought it would be more trouble to implement.  As it turned out, I was mostly wrong (again) :-).

In any case, changing over from the MODE interface to the I2C interface turned out to be a non-issue.  Pulsed Light has some nice Arduino example code on GitHub, along with clear instructions on what I2C library to use (there are several). I did have to swap out the MODE line for one of the two I2C lines due to the limitation of 6 wires through the spinning LIDAR slip-ring setup (4 were already occupied by power, ground, and the two laser diode wires).  However there was some good news in that this freed up one of the Uno’s analog ports, as the I2C SCL and SDA lines have dedicated pin-outs on the Uno.

Anyway, I got the SCL/SDA lines connected through the slip-ring and to the Uno,  downloaded/installed the necessary I2C library, downloaded and installed the Arduino example, code, and uploaded it to my Uno system.  Sure enough, the example code worked great, and in addition gave much more accurate distance results than with the MODE method (with the MODE method, I had to subtract 40 cm from each measurement.  With the I2C method, the measurements seemed to be ‘dead on’).

However, when I instrumented the code to toggle a Uno digital pin so I could measure the timing with my trusty O’Scope, I received a major shock.  Instead of the 30-35 msec cycle time from the MODE method, the I2C method was showing more like 110-120 msec – MUCH slower than the MODE method, and WAY too slow for servicing interrupts at 20-25 msec intervals!

Yikes – what to do?  Well, as usual when I’m faced with a situation I don’t understand, my response is to yell for help, and take more data.  the ‘yell for help’ part was accomplished via an email to ‘help@pulsedlight3d.com’, and the ‘take more data’ part is described below.

The first thing I did was to re-download the Pulsed-Light test code from GitHub and run it again without any modifications.  The test program simply writes distances out to the PC console, and I was able to re-verify that the LIDAR unit was indeed responding with what appeared to be correct distances, and responded appropriately when I waved my hand in front of the optics.

Next, I added a line of code at the top of the test code’s Loop() section to force the Uno’s LED pin (pin 13) HIGH, and another one at the ‘bottom’ (after the measurement but before the Serial.println() statement) to force the LED pin LOW.  This gives me the ability to directly view the measurement timing on my trusty O’Scope.  The reason the LOW statement line has to be before the Serial.println() statement is that the bottom of the Loop() code and the top are actually the same point in time, which would effectively put the HIGH and LOW statements right next to each other, making O’Scope measurements impossible.  By putting the LOW statement before the Serial.println() statement, I am guaranteed to have a LOW period equal to the time it takes the Serial.println() statement to convert the distance value to a string and send it to the serial port.

After uploading the above modification to the Uno, I got the following Scope screenshots:

20msec/div showing the '20msec' mode.

20msec/div showing the ’20msec’ mode.

20msec/div showing the '100msec' mode, where the LOW between measurement pulses are  spaced approximately 100 msec apart.

20msec/div showing the ‘100msec’ mode, where the LOW between measurement pulses are spaced approximately 100 msec apart.

Closeup of the LOW period between the 'bottom' and 'top' of the Loop() section.  Note the curved section at the bottom is due to the LED turning OFF.

0.1 msec/div closeup of the LOW period between the ‘bottom’ and ‘top’ of the Loop() section. Note the curved section at the bottom is due to the LED turning OFF.

The first image above at 20msec/div shows what I expected to find – that the LIDAR-Lite V1 unit is capable of taking measurements with an approximate 20msec cycle time.  This should work fine for my Wall-E spinning LIDAR robot, as interrupts from the tach wheel sensor occur at about 25msec intervals.

However, after a few minutes, the scope display (again at 20msec/div) showed that the system stopped responding a the 20msec rate, and instead started responding no faster than about 100-110msec, WAY too slow for my spinning LIDAR application.  I have no idea why this happens, but I am hoping the Pulsed Light guys will tell me that I have simply screwed something up and doing XYZ will fix it.

The last image above  at 0.1msec/div shows a closeup of the OFF period.  The curved bottom section is due to the fact that the LED turns OFF at about 3 Vdc, and below that the remaining energy has to be drained off through a high impedance.

After sending this information off to the PL guys, I started thinking that maybe the apparent change from ’20msec’ mode to ‘100msec’ mode might possibly be due to the extremely short LOW duration (about 100 usec or less) and the fact that the LOW doesn’t go much below about 3Vdc.  Although I didn’t really believe it, I thought it was just barely possible that my trusty O’Scope was just missing these very short transitions after a time, and the whole problem was an O’Scope problem and not a LIDAR problem.  So, in order to put this possibility to rest, I modified the code again to extend the LOW duration by 1msec with a delay(1) statement just after the line that sets the LED output LOW (essentially adding an extra 1msec delay between the LOW and HIGH lines).  After uploading this to the Uno, I captured the following O’Scope waveforms.

After addition of a 1msec delay to the LOW period.  Showing the '20msec' mode at 10msec/div

After addition of a 1msec delay to the LOW period. Showing the ’20msec’ mode at 10msec/div

After addition of a 1msec delay to the LOW period.  2msec/div

After addition of a 1msec delay to the LOW period. 2msec/div

After addition of a 1msec delay to the LOW period.  0.2 msec/div closeup of the LOW period between the 'bottom' and 'top' of the Loop() section.  Note the curved section at the bottom is due to the LED turning OFF.

After addition of a 1msec delay to the LOW period. 0.2 msec/div closeup of the LOW period between the ‘bottom’ and ‘top’ of the Loop() section. Note the curved section at the bottom is due to the LED turning OFF.

After addition of a 1msec delay to the LOW period.  This shot was taken about 45 minutes after startup, showing that the system has  made an uncommanded transitioned to '100msec' mode

After addition of a 1msec delay to the LOW period. This shot was taken about 45 minutes after startup, showing that the system has made an uncommanded transitioned to ‘100msec’ mode

As shown in the above photos, I got essentially the same behavior as before.  The system came up in ’20msec’ mode, but made an uncommanded transition to ‘100msec’ mode about 45 minutes after startup.

So, something is happening here, but I don’t know what it is.   It ‘smells’ like a heat-related problem, but that doesn’t make a whole lot of sense, as I’m running this in an air-conditioned environment, and there isn’t that much power being used as it is.  As I mentioned above, I’m hoping it’s just something dumb that I’m doing that is causing this, but I have no clue what that might be.

There is one other possibility that just popped into my head.  I’m using Uno clones rather than actual Arduino boards.  I guess it is just barely possible that the problem is in the Uno board, not the LIDAR. Maybe the I2C lines get flaky after some time, and start sending bad requests to the LIDAR or not properly processing LIDAR responses?  I’m thinking I might want need to acquire some genuine (Genuino?) Arduino Uno boards to eliminate this possibility.

Stay tuned!

Frank

 

 

 

Wall-E Has More Interrupt Issues

Posted 08/04/2015

In my last post (http://fpaynter.com/2015/07/emi-problems-with-lidar-and-wall-e/) I described my efforts to track down and suppress an apparent EMI problem with Wall-E. After successfully (I hope) killing off the EMI problem, I added navigation code back into the mix, and did some initial tracking tests on a long, straight wall.   The results were not encouraging at all – it appeared that Wall-E was having quite a bit of difficulty deciding which way to steer; it appeared to be correctly measuring the distance and angle to the nearest obstacle (the wall), but wasn’t adjusting wheel speed to compensate for nose-in or nose-out conditions.

As it turned out, there was a very obvious reason Wall-E wasn’t adjusting the wheel speeds; at some point I had overridden the wheel speed setting logic and arbitrarily pegged the wheel speeds at 50 and 50 – oops!  Unfortunately, while I was figuring this out, I discovered something even more disturbing.  Apparently, all this time Wall-E has been servicing only about half (9 vs 18) of the LIDAR tach wheel interrupts!  I hadn’t noticed this up until now because although I had previously looked at the the contents of the 18-element distance/time/angle array, there was apparently enough ‘creep’ in the interrupt numbers that Wall-E *did* service that the array looked normal.  However, some of the instrumentation code I put in place this time made it painfully obvious that only 9 interrupt calls were being made.  As a double-check, I changed the code to turn the red laser ON during interrupt service routine (ISR) calls, and OFF at all other times.  Then I made a surround screen from several sheets of paper and looked at the pattern made by the laser.  In the following time-lapse image (0.5 sec or about 1 full revolution), 4 laser pulses (ISR calls) are visible in about 1/2 full circle.  In the following video, there are only 9 laser pulses visible per revolution.

Time Lapse (0.5 sec) photo with GetMeasure() call in

Time Lapse (0.5 sec) photo with GetMeasure() call in

 

Then I went into the code, and commented out the call to GetMeasurement().  GetMeasurement() is where the Pulsed Light LIDAR measurement delay occurs, and this is the obvious suspect for missing ISR calls.  As the following time-lapse photo and companion video shows, this indeed allowed all 18 ISR calls per revolution.   Comparing the two photos, it is obvious that the one without the GetMeasurement() call exhibits twice as many laser pulses (ISR calls) and each pulse is much shorter, denoting less time spent in the ISR.

Time Lapse (0.5 sec) photo with GetMeasure() call commented out.

Time Lapse (0.5 sec) photo with GetMeasure() call commented out.

 

So, what to do?  In the first place, I’m still not sure why interrupts are being skipped.  If you believe that the laser ON time represents the duration of a particular ISR call, then the fact that there are times when the laser is OFF should indicate that the system can service another interrupt – why doesn’t it?

So, back to the drawing board.  I drug out my trusty O’Scope and started poking around.  I have one of the Uno’s digital lines set up to show the duration of GetMeasurement() and another one set to show the duration of the ISR.  Then I did a series of tests, starting with GetMeasurement() turned ON as normal, but with the call to PulsedIn() (the actual LIDAR measurement function) commented out and replaced with delays of 10, 20, and 30 msec.  The following captioned photos show the results:

 

Conclusions:

  • The PulseIn() call in GetMeasurement() is definitely the culprit.  Not surprising, as this is the call that interfaces with the spinning LIDAR unit to get the actual distance measurement.  The only question is how long does/should it take the LIDAR to return the distance measurement.
  • Delays up to 20 msec in place of the PulseIn() do not adversely affect operation.  Both the O’Scope and laser pattern presentations clearly show that interrupt servicing is proceeding normally.
  • A 30 msec delay is too large, but not by much.  There is some evidence in the O’Scope photo that occasionally the next interrupt is not skipped.

The above conclusions track reasonably well with the known physics of the setup. The spinning LIDAR rotates about 2 times/sec, or about 500 msec/rev.  Interrupts are spaced out 1/20 rev apart, except for the index plug where 2 interrupts are missing.  (500 msec/rev) times (1/20 rev/interrupt) = 25 msec/interrupt.  So, 10msec delay should be no problem, 20 should also fit, but 30 is too long.  The fact that there is some evidence that 30 is almost short enough is probably due to the rotation speed being slower than estimated; 30 msec/interrupt –> 600msec/rev or about 20% slower than nominal.

In any case, it is clear that the current setup can’t support an interrupt interval of 25 msec.  I’m either going to have to slow down the spinning LIDAR (which I do not want to do) or speed up the measurement delay (which I don’t know how to do – yet).

There are two methodologies for interfacing with the Pulsed Light LIDAR.  One (the one I’m using now) is pretty simple but involves the PulseIn() call with it’s known issues.  The other one is via the I2C channel, which I have not tried because I thought would be harder to do, and there wasn’t any real evidence that it was any faster.  Now that I’m convinced that PulseIn() won’t work, I’m going to have to take another look at the I2C interface technique – EEK!!

Stay tuned,

Frank