Monthly Archives: August 2017

IR Homing Module Integration, Part I

Posted 06 August 2017

Now that I have the 2-channel IR demod algorithm working, it’s time to start integrating the capability back into my long-neglected Wall-E2 robot.  The grand plan here is to incorporate the IR demod algorithm into a ‘IR Homing Module’ with raw IR sensor input on one end, and (R-L)/(R+L) normalized steering information output on the other, as shown in the following diagram.

Teensy 3.2-based IR Demod module block diagram


As the first step in this project, I wanted to verify that I can port the IR demod algorithm from its current Teensy 3.5 SBC host to a Teensy 3.2.  The Teensy 3.2 is about half the size of the 3.5, runs at 72MHz instead of 120MHz, and has “only” 64KB RAM instead of the 3.5’s 192KB.  I didn’t think any of this would matter, but you never know ;-).  The code modifications required to run this test were pretty trivial; I had to comment out the DAC1 setup lines, and change the pin number for the Channel 1 DAC0 output from A21 to A14.  Then I commented out the lines that transmitted the Ch2 final value to the now-nonexistent DAC1 port and that was it.  The following photo shows the T3.2 in the foreground, with the T3.5 sweep generator next back, and the original T3.5-based IR demod host in the background

Teensy 3.2 trial as host for IR demod algorithm. The Teensy 3.5 in the middle is the sweep generator and the one in the back is the original host for the 2-channel IR demod algorithm

After making the above changes, I ran a frequency sweep from 510 to 530Hz in 0.1Hz steps, 0.5S/step, with the following results.

Frequency sweep of the IR demod algorithm hosted on a Teensy 3.2

For comparison, here is the same plot from the previous post using the Teensy 3.5.

I think it’s safe to say that the Teensy 3.2 operating at 72Mhz is doing as good a job with this algorithm as the Teensy 3.5.

So, the next step was to figure out how to get the steering information from the Teensy to the main robot controller (a Mega 2560).  I decided to use the I2C port for this purpose; the Mega has one I2C port, and the Teensy has several, so this should work.  Of course that means I have to figure out how to actually use the I2C capability, but hey – that’s what the internet is for ;-).

In any case, I found the new i2c_t3 library for use with Teensy 3.x, and the ‘I2C_Anything’ library for transparently handling arbitrary data types, and a couple of examples showing their use.  With these (and my handy-dandy Teensy testbed) I was able to implement a little master/slave demo project to confirm that I could use I2C to transmit float data values from the Teensy 3.2 I would be using as the IR homing beacon demodulator to the Mega.


Output from master/slave demo project

So the next step is to integrate the above master/slave I2C code into the Mega 2560 and the Teensy 3.2.  The plan is to have the Mega request data from the Teensy, and the Teensy will then transmit the latest L/R steering value.  There will be no buffering on either end, so whatever the Mega doesn’t request will simply fall off the end into the ‘bit bucket’.

Currently, the IR phototransistors appear on pins 55-58 (A1-A4) on the Mega.  These will be transplanted to pins 14-17 on the T3.2 (A0-A3).  GND will go to GND, and +5V from the Mega will go to ‘VIN’ (+5V with USB connected) on the T3.2.  With this setup, and a few modifications to the ‘Master’ sketch in my previous master/slave demo program, I should be able to transmit a 520Hz square-wave modulated IR signal to the IR detectors, and have it appear on the master’s serial port after having been demodulated by the T3.2 – stay tuned! 😉

As an interim step, I disconnected the four IR sensor leads from the Mega 2560 and reconnected them to the T3.2, as shown below.




IR sensor connections moved to the Teensy 3.2 IR Homing Module

Next I set up an IR LED source a few inches away from the detector array and moved it from right to left across the array field of view, and recorded the raw sensor data as received by the Teensy, as shown below:

Raw IR sensor data as received by the Teensy 3.2

Left & Right averages

So, the IR sensors are indeed alive (maybe too alive in the case of sensor #3) and working, and the A0-A3 analog inputs are verified working as well.  Also, in this very rough test, it is apparent that the responses from all four sensor overlap to form a continuous field of view, and that averaging the two left and two right IR sensor data sets also works.

Next, I moved the range out to 1m and then to 1.8m and ran the same tests, with results as follows:

From the above results it is clear that sensor #3 is considerably more sensitive than the others.


IR Modulation Processing Algorithm Development – Part XVII

Posted 30 July 2017

This long-running saga started actually started almost exactly two months ago with the weekend visit of my friend and long-time mentor John Jenkins.  Naturally, being fellow geeks, I showed him all my new toys, including Wall-E2, my autonomous wall-following robot.  When I explained that Wall-E2 was having some trouble homing in on an IR beacon to connect to a charging station due to the ‘flooding’ effect of direct sunlight and overhead incandescent lighting (see for instance, this post), John opined that the way to address this problem was to modulate the homing beacon with a square wave, and then use a  ‘simple’ digital filter on the robot to better discriminate between the wanted (square-wave modulated) and unwanted (sunlight and/or incandescent lighting) sources.

Right then and there I should have realized I was in trouble, because I have (or should have!) learned over the years that whenever John uses the word ‘simple’, what he really means is “this is going to be so complex that you will wish you never listened to me”, and what he means by the word ‘better’ is “this will make your robot capable of operating from the vacuum of space to the depths of the ocean, in the middle of a thermonuclear war.  All other life on earth will have long since been reduced to its constituent atoms before your robot fails to meet spec”.  What I should have done was say to John “that’s nice John, but I think I’ll just operate Wall-E2 at night with the lights off”

But noooo, I fell for this line, (again!), and said “hmm, sounds interesting John”, thus going down yet another rabbit hole in my quest to make Wall-E2 completely autonomous. So now I started working on the design and implementation of a ‘degenerate N-path band pass filter’ (John’s term), a project tangential to the implementation of a charging station, which in itself was tangential to my original wall-following robot project.  My only justification (well justifications) for this clearly insane behavior are:

  1. am clearly insane – I’m a twice-retired engineer, after all!
  2. The entire impetus for the Wall-E2 project was to give me a way to waste as much time as possible in an intellectually stimulating way, and the idea of implementing a ‘degenerate N-path band pass filter’ promised to waste a lot of time (and besides, being able to tell people I had implemented a “degenerate N-path band pass filter” was just too sexy to pass up!)

Well, it has been a heck of a journey these last two months, but I believe that with John’s help (or possibly in spite of it), we now have a working two-channel 520Hz N-path BPF, and as a bonus – a working high-accuracy frequency/amplitude sweep generator, both based on Paul Stoffregen’s wonderful Arduino-ish Teensy 3.5 SBC.  The last piece of the puzzle for the sweep generator design fell into place just yesterday with a post from ‘tni’ on the Teensy user forum, describing the proper technique for updating the count-down value for the Periodic Interrupt Timer (PIT) used in the sweep generator.

Sweep generator recap:

The original plan for the sweep generator was to use the same ‘elapsedMicros’ object type that I had used to generate the transmit waveform, but it turned out (see this post) that t he ‘elapsedMicros’ technique produced an unavoidable frequency offset.  So, searching for other alternatives, I tried a rounding technique using ‘elapsedMicros’ which helped somewhat but didn’t really solve the problem, and then a method using Daniel Gilbert’s IntervalTimer library (this library wraps access to the Periodic Interrupt Timer (PIT) module of the FreeScale Cortex-M4 microcontoller used in the Teensy 3.x line).  This technique produced a very accurate frequency output, but unfortunately also produced bad artifacts in the frequency response curves from the N-path BPF implementation due to the delays inherent in the need to stop and then restart the PIT for each new frequency step.  A representative ‘raw’ and ’round-trip’ frequency response curve set is shown below to illustrate the problem, along with the timestamp representation of the PIT operation.

‘Round-trip’ and ‘raw’ FinalValue vs Frequency, with IntervalTimer technique

Square-wave transition times vs time using the IntervalTimer technique

I was just about ready to give up on the IntervalTimer technique, and just deal with the frequency offset inherent in the ‘elapsedMicros’ technique. However, John shamed me into putting a post up on the Teensy forum explaining my issues and asking for help.  I hate to say it but I’m glad he did, as among the other helpful posts was one from ‘tni’ with the complete code for an add-on function to the IntervalTimer library to do just what I wanted – update the count-down count in the PIT without disturbing anything else.  As a result of this addition, I was able to get frequency-accurate response curves from the IR demodulator filter without any ugly artifacts, as shown below

‘Round-trip’ and ‘raw’ FinalValue vs Frequency, with IntervalTimer technique, using tni’s updateInterval() function

Square-wave transition times vs time using the IntervalTimer technique, using tni’s updateInterval() function

So now I have a sweep generator that works – albeit one that needs a little cleanup before I push it up to GitHub

August 02 2017 Update:

Today I finally ‘finished’ (to the extent that I ever really finish anything) the 2-channel IR demodulator algorithm, and the accompanying frequency/amplitude sweep generator, and posted both to my GitHub account (see and  After squashing a few last buglets, I was able to run fairly detailed frequency sweeps on both demodulator channels using the sweep generator, with the following results

If you like data, this is pretty good stuff – nice and smooth, no unusual artifacts, nicely centered around 520-522Hz, and the Ch1/Ch2 overlap is almost perfect.  Whatever else has happened in this little 2-month vacation from reality, the ‘N-path band pass filter’ algorithm clearly works, at least on the bench.

Now that I have the BPF algorithm humming along, the next challenge will be to integrate the BPF module onto the robot, and modify the charging station to modulate the IR homing beacon with the requisite 520Hz square wave, and of course test it all to verify functionality.  Still plenty of work to do, so I don’t have to worry about getting bored anytime soon!  Stay tuned…