Yearly Archives: 2021

Serial Bridge over WiFi using ESP32 DevKitC

Posted 09 April 2021

I have been wanting to upgrade my robot’s brains from the old Arduino Mega 2560 to a more modern Teensy 3.x or 4.x MCU for some time now, but have been stymied by the lack of Over-The-Air (OTA) programming support. My current Mega-based setup uses a pair of Pololu Wixels to form a transparent wireless bi-directional serial link between my PC and the robot. My Microsoft Visual Studio IDE sees the link as just another COM port, and the Mega thinks it’s Tx/Rx0 lines are connected directly to the PC; couldn’t be simpler and more effective. The range of the Wixel connection is on the order of a few tens of meters, but that’s all I need for managing my autonomous wall-following robot.

Unfortunately, the Teensy world seems a bit short on effective wireless OTA solutions, or at least my searches have come up mostly dry. Some users report they have been able to use a Raspberry Pi Zero-W for this purpose, but that seems like a major overkill

After yet another Google search, I started seeing some posts about the ability to form a wireless serial data bridge using an ESP32 wireless-enabled development module, and I since I happened to have a ESP32 DevKitC hanging around Idecided to try my hand at that, maybe as a first step to achieving OTA nirvana with a Teensy 3/4.x.

The starting point for this project was this tutorial (the bottom ‘Serial Bridge Using ESP8266 (Simpler)’ part), based on this module sold on the AliExpress site. The AliExpress module wasn’t exactly the same as the DevKitC I had on hand, but it was close enough and AFAICT the pinouts are identical.

The first step was getting the Arduino/VS2019 IDE to recognize the ESP32 hardware. This was a semi-major PITA, but I eventually found some posts showing how the board information could be added to the system.

The next step was getting PuTTY downloaded and installed on my Win10 system. This went fairly easily.

Next I downloaded the ESP32 serial bridge software from the GitHub site and set it up as a project in my VS2019/Visual Micro IDE. This all seemed to work, and I was able to upload the program to my DevKitC module

I also happened to have an old CKdevices FTDI module, so I was able to connect to the required serial lines on the ESP32 module. However, I discovered that the tutorial didn’t use the standard Tx/Rx lines shown in the DevKitC pinout diagram; evidently they had to be moved to allow all three UART/USB modules to be connected at the same time. The actual pinouts used by the tutorial are:

After some fumbling around, I finally realized that the ‘GPIOxx’ labels in the above pinout list is the same as the numbers printed on the actual module, i.e. ‘GPIO21′ <==> ’21’ on the module PCB (the lone exception to this is ‘GPIO1’, which corresponds to ‘TX’ on the module). Here’s a picture from the GitHub documentation showing the actual layout expected by the sofware.

After working my way though these problems, here’s the physical setup I wound up with:

CkDevices FTDI UART/USB connected to COM5 on USB side, Tx2/Rx2 on ESP32 side
Detail showing the pin connections to ESP32 module. Yellow is connected to ESP32 Rx2, Green to Tx2

With the above hardware setup, I was able to pass serial data from one PuTTY terminal connected to the 192.168.4.1/8882 port, and another connected to COM5 on the PC (corresponding to COM2 on the ESP32).

Having accomplished this, I’m still unsure how to go about using this capability to program a Teensy 3/4.x using the wireless link. More study required!

Frank

Turn Rate PID Tuning

Posted 05 April 2021

Wall-E2, my autonomous wall-following robot, does a lot of turns to follow walls. Originally Wall-E2 used a simple timing algorithm to make turns, but this wasn’t very accurate. On a hard surface a 5-second turn at half motor speed could result in a 360º turn, while the same 5 seconds on carpet my only cover 90º. After installing the MPU6050 IMU about 18 months ago, turns could be controlled much more accurately, but the turn rate still varied widely on carpet vs hard flooring. Some time ago, I revised Wall-E2’s program to use a PID engine for turn rate control, but this resulted in a low-frequency ‘motorboating’ movement as the robot ramped up motor current until the angle started changing, followed by ramping the motor current down again because the turn rate target had been exceeded.

After having some success with improving the robot’s performance in homing to the charging station by utilizing the Zeigler-Nichols tuning method, I decided to try using it to improve turn rate control.

The method starts with setting the PID variables to (Kp, 0, 0) and then varying the Kp values to determine Kc, the value at which the setpoint variable (in this case, the turn rate in deg/sec) exhibits a steady oscillation. The value of Kc is then used to calculate all three PID parameters using

The existing setting for Kp, Ki, and Kd was Kp = 5, Ki = 0, Kd = 10, and this resulted in the following plot for a single 270º turn.

To start the process of determining Kc, I first zeroed out the Kd factor, resulting in the following plot:

So the system is clearly exhibiting a ‘constant amplitude oscillation’, but Kc is the minimum Kp value that produces oscillation. So, I started reducing Kp looking for the point at which the oscillation stopped, producing the following plots:

Comparing the above plots, it seems the value of Kc is probably around 0.1. Using the Z-N formula above, I get

These values are almost two orders of magnitude smaller than the values I had been using – ouch! Looking back on the original work, I had declared the Kp, Ki, & Kd variables as ‘const int’, which means the lowest positive value I could use was ‘1’, which might explain why I never tried anything smaller. Of course, I could have also done what I did with the home-to-charger PID engine and arranged the turn rate calculation so that instead of Kc = 0.1, it would have been more like 100, resulting in (Kp,Ki,Kd) values of (50,45,60).

Anyway, using values of (0.05, 0.045, 0.06) results in the following plot

And here is a short video showing the robot executing the 270º turn plotted above

I was quite impressed by the difference between what I had before and the current performance after implementing the Z-N tuning method; the turn rate was an almost constant 40º/sec (an average of 42.9º according to Excel). And, now that I have a semi-constant rate to look at, it appears to me that I should probably crank up the turn rate to something more like 90º/sec.

With the turn rate cranked up to 90º/sec and using the same values for Kp, Ki, Kd, I get the following plot and video.

The plot of turn rate vs time shows considerably more variation with a 90º/sec turn rate, as compared to 45º/sec; maybe Kc is different due to the different physical dynamics of the robot? The average turn rate from the Excel data is 80º/sec; not the 90º/sec I was looking for, but still not bad. Even so, this result is much better than I had before, with extreme motorboating between 0º/sec and something much higher. I may or may not try to re-determine Kc, but in the meantime I think I’ll run with this for a while.

10 April 2021 Update:

Some of the above data were collected at a pretty low charge level. When I had the opportunity to recharge Wall-E2 I re-took the 90º/sec run with the following results:

As the above plot shows, the turn rate was held almost constant (average of 87.9º) throughout the turn – very nice!

Here’s another run, this time on carpet with a fully charged battery. As expected, the robot has a harder time getting started on carpet due to the added sideways friction on the wheels. However, once the turn gets started, it stabilizes fairly well on the 90º turn rate target

Stay tuned,

Frank

Another Try at Charging Station Homing PID Tuning

Posted 04 April 2021

Lately I have been working on improving the performance of Wall-E2, my autonomous wall-following robot, when homing in and connecting to it’s charging station. The robot uses the PID (Proportional-Integral-Derivative) library to drive the motors to home in on an IR beacon, and this ‘mostly’ works, but still occasionally hangs up on the lead-in rails. I have made several attempts to get this right (see this post and earlier work), but have never really gotten it zeroed in. After yet another web search for tuning help, I ran across this post dealing with the Ziegler-Nichols method for PID tuning. Basically the method starts by setting the proportional (Kp), integral (Ki) and derivative (Kd) terms to zero, and then slowly increasing the proportional (Kp) term until a ‘stable oscillation condition’ is achieved (Kp = Kc). Then the Ki & Kd terms can be calculated using the following relationships:

Getting to the ‘Kc’ (Kp-critical) value for my setup is a bit more difficult than normal, as the PID engine only operates for a few seconds, from the time the IR homing beacon is detected, to the time the robot actually connects (or doesn’t) to the charging probe. Here’s a short video showing a typical run (Kd = 150 in this case), and an Excel plot of the steering value from the same run.

As can be seen from the above, there really isn’t much of an ‘oscillation’ to go on – there is basically only one full cycle from about 10.5 sec to around 12.0 sec.

Here’s another run, this time with Kd set to 200. As can be seen, this is much more like what I was expecting to see, with several full cycles of oscillation. The amplitude trails off a bit toward the end, but this may have been due to a low battery level – I’ll have to repeat this experiment after getting a full charge into the robot.

Kp = 200, Kd = Ki = 0. Period is approximately 1.3 sec

However, using the above data with Kc = 200, we get

I revised my program to incorporate the Z-N numbers from the above calculations, and this resulted in the homing runs shown below; in the first one, Wall-E2 was oriented directly at the charging station beacon, and the robot’s track was pretty much direct, with no side-side oscillation at all. In the second one I oriented the robot a bit off-axis to excite a more active homing response. In both runs, the LEDs on the rear of the robot show the current relative wheel speed commands – LED’s to the left of center indicate higher wheel speed on the left, and vice versa. In the first run, the LEDs show that there is some oscillation of wheel speed commands, but it is relatively small, leading to an almost serene homing performance. In the second run the initial orientation offset forces the robot to more actively manage the wheel speeds to stay ‘on the beam’.

Stay tuned,

Frank

Charging Station Initial Approach Algorithm Improvement

Posted 20 March, 2021

In order to realize my long-term goal of a fully autonomous wall-following robot, Wall-E2 has to be able to reliably mate to its charging station when it gets low on go-juice. Unfortunately, Wall-E2 occasionally fails to mate properly, usually due to an initial misalignment with the center of the IR homing beam. I haven’t worried too much about this, as there have been more pressing problems, but as these have been solved, the mating problem has risen to the top of the to-do list.

The basic geometry for the charging station is shown below:

Tilted gate option. The tilt decreases the minimum required IR beam capture distance from about 1.7m to about 1.0m

As long as the robot starts its approach on or near the boresight of the IR beam, all goes swimmingly. However, if Wall-E2 detects the IR beam while tracking the wall at right angles to the one depicted above, it can easily start its approach before getting to the center of the beam, resulting in it getting stuck on the outside guide-in rail (upper rail in the above diagram). In addition, if Wall-E2 is tracking too close to the wall above, it can actually get stuck on the inside guide-in rail (lower rail in the above diagram).

So, what is needed here is a way to force the robot to line up on the IR beam centerline before committing to the mating approach. To investigate this, I created a part-task version of Wall-E2’s operating system that does just one thing; it detects the IR homing signal, and then takes action to position itself in the center of the IR homing beam, aligned with the beam’s boresight. In the aviation instrument (blind) flying world, this is known as the ‘IAP’ (Initial Approach Point), so I needed to create an algorithm so Wall-E2 could navigate to the Charging Station IAP, and start it’s final approach from the same place every time.

In previous work I have gotten Wall-E2 smart enough to track walls at a constant offset. so this is where I started with the current effort. When Wall-E2 starts to track a wall, the first thing it does is use the near-side array of VL53L0X IR laser TOF sensors to orient parallel to the wall, without regard to the absolute offset. It then angles toward or away from the wall to achieve tracking at the desired offset.

The starting position for the current effort is with the robot placed close to the wall leading to the charging station, pointed generally toward the charging station. When the robot wakes up, it sees that there is an active IR homing beacon, and takes action to navigate to the IAP.

  • First it uses the parallel orientation algorithm to align itself parallel to the near wall so it can measure it’s offset from the wall, and also to ensure that the front distance measurement accurately reflects the distance from the robot to the charging station.
  • Next, it compares the wall offset and front distance measurements to the known values for the IAP, i.e. a 50 cm offset at a distance of 180 cm. It then calculates how much additional offset it needs to place itself in the center of the beam.
  • If necessary, the robot turns 90º away from the wall and moves away to achieve the desired offset. If the robot is already far enough away from the wall, it skips this step
  • After getting far enough away, the robot turns in place (a ‘Spin Turn’) until the signal strength of the received IR homing beacon rises above a set threshold. This gets the robot oriented generally in the direction of the charging station
  • The last step is to fine-tune the robot’s orientation so that it is centered in the beam and also well aligned with the beam boresight.

The following photograph shows the robot at the IAP, ready to start the final approach to the charging station.

Wall-E2 at the Initial Approach Point, ready to start the final approach to the charging station.

And the following video shows the entire process, up to the point where the robot would actually start the final approach.

15 April 2021 Update:

One of the issues with the current initial approach algorithm is the lack of accuracy in achieving the desired wall offset, due to Wall-E2’s tendency to ‘coast’ past the desired distance. I could just lower the offset target by a fixed amount to account for the ‘coast’ effect, but since that changes significantly depending on whether Wall-E2 is on carpet or hard flooring, that doesn’t sound like a good ide.

Instead, I decided to use yet another PID object to manage offset distance acquisition, using the following algorithm:

Using this code, I got the following output:

And a short video showing the offset acquisition process:

Here’s the same process, but starting from farther away than desired

21 April 21 Update:

After some additional work on the initial approach algorithm, I arrived at a pretty nice spot; Wall-E2 will reliably detect the IR homing beacon, offset the proper amount from the wall using a 90º turn and a PID engine-driven rear-distance controlled movement, and then rotate to orient to the IR beam boresight. The ‘rotate-to-boresight’ operation takes place in two stages. In the first stage, the robot turns toward the beacon in 10deg steps until the beacon is re-acquired (this is necessary because the robot loses the beam signal when it turns 90º to the wall) and then uses another PID-driven algorithm to center up on the beam boresight. Here’s a short video showing the process.

IR Homing with Initial Approach Phase added. 2-sec pauses are inserted to delineate sub-phases

As can be seen from the above video, the robot successfully navigates to the initial approach point (IAP), rotates to orient with the homing beacon boresight, and then homes to the charging station. This all works, but it is pretty clunky and inelegant. The initial 90º turn away from the wall is in itself a bit problematic, as it can easily overshoot, and then the robot loses the beacon signal, which means that after the appropriate wall offset has been reached, the robot has to turn back toward the charging station to re-acquire the signal, and it has to do so ‘gently’ so as not to overshoot.

I think it would be much better if the initial turn away from the wall was just 45º so the robot won’t lose the beacon signal while navigating to the IAP, and potentially eliminating the first part of the ‘rotate to boresight’ phase. Here is the relevant geometry:

Charging station initial approach and homing geometry

In the above figure, the robot currently makes a 90º utilizes the line labelled ‘Offset =…’ to offset out to the IR beam boresight. I’m thinking that the line labelled ‘x = …’ would work better, as the robot only has to make a 45º turn initially, and then the robot might not lose the beam signal as it offsets out to the IR boresight line. Here’s the supporting math.

Initial Approach Point math

In the above figure, an example is worked out for d = 120cm, where the perpendicular offset is found to be 34.4cm and the 45º turn distance is found to be 1.09*Offset = 37.8cm.

23 April 2021 Update:

The change from 90º to 45º IAP approach angle turned out to be pretty easy to do – really just a matter of changing ‘SpinTurn(90)’ ‘SpinTurn(45)’ and the offset value to 1.09 x offset. Here’s a short video showing the result.

After a few more runs (with some failures due to the robot hanging up on the outside rail), I realized my basic beam geometry estimate was significantly off. Instead of a beam angle of about 16deg, it was more like 11, yielding a distance::offset ratio of about 0.18 instead of 0.27. Revising the program to use the more accurate ratio resulted in the following much nicer homing run.

Homing run using a distance::offset ratio of 0.18 vs 0.27

And here is the telemetry from the run:

Much nicer!

Stay tuned!

Frank

Wall-E2 Gets a VL53L0X Array Upgrade

Posted 13 March 2021

Back in May of last year I started the process of replacing the ultrasonic distance sensors on Wall-E2, my autonomous wall-following robot, with two side-looking arrays of STMicroelectronics’ VL53L0X infrared laser ‘Time-of-Flight’ distance sensor. Later that same year I upgraded the installation by adding a rear distance sensor as well, as shown in the following photo:

left-hand VL53L0X array and rear sensor shown. Identical 3-elelment array on the other side

All went swimmingly until I started having problems when Wall-E2 connected up to its charger. Wall-E2 connecting to its charger is a pretty dynamic event, as it has to build up enough speed to make sure the charging probe seats into the charging jack properly. I discovered that about every other time Wall-E2 connected, the distance sensors would start reporting ‘-1’ instead of the actual distances. This meant that when Wall-E2 disconnected from charging, it had no idea what to do or which way to turn. This didn’t happen all the time, but often enough to be very worrisome.

After some head-scratching and program instrumentation I became convinced this was a real issue, and I posted on the ST Micro’s forum about the issue. ST Micro’s VL53L0X expert John E. Kvam answered with this post:

The VL53L0X sensor will not return a -1. The user manual does define a -1 error, but it states that this cannot happen. What does return a -1 is an I2C timeout.
And I think that is what is killing you. The I2C is notorious for being basically unreliable. And the major symptom of a dropped bit (the most likely failure), is that the bus is stuck low. (When nothing is being transmitted both the clock and data lines should be high.) Philips designed the I2C bus and NXP bought Philips. So the NXP site has some documentation on how to tweak the bus. I’d read and understand that.
One other possibility is that one or more of the sensors rebooted – perhaps due to power glitch. If this happens the sensor will revert to it’s base I2C address.
If you’ve changed all your addresses there should be nothing at address 0x29 (0x52/0x53). You could occasionally ping the base address – and if you ever got an answer, you would would know you had a reboot of some kind.

After thinking about this some more, I realized that there is a good chance that the I2C ‘daisy-chain’ wiring and/or the power/ground connections are getting interrupted due to the impulse generated when Wall-E2 hits the charging station stop, and this is causing one or more of the sensors to drop out. I thought I had done a very careful job with the I2C/power ‘daisy-chain’, but I had thought that about a previous effort where I found a faulty ground connection, so I knew it was a possibility.

After thinking about this some more, it occurred to me that I could eliminate most of the point-point wiring issues by creating a PCB to house the VL53L0X modules, with a single 4-pin connector for I2C and power. I had made a PCB some years before using DipTrace that had turned out petty well, so making one for the very simple VL53L0X wiring scheme should be a piece of cake.

Well, as it turned out, designing the PCB was the easy part. However, when it came to the part about having the boards actually manufactured, I was in for a bit of a shock. For my previous board I used DipTrace’s ‘baked-in’ manufacturer Bay Area Circuits to purchase 5 boards for around $30, but when I tried this same trick with my new board, the minimum charge for boards from BAC was $150 – ouch!

After a lot of web searching and research, I eventually found the Chinese company JLCPCB and discovered they have a very nice document that shows how to export the required files from DipTrace and upload them to their site. Took me about 30 minutes to go through the process the first time, and now I have my 5ea boards ordered for a grand total of about $15USD. Only a 10:1 ratio from BAC to JLCPCB. I can’t imagine how BAC can stay in business, and I can’t imagine why DipTrace has that company ‘baked in’ and not JLCPCB. DipTrace must be getting a heck of a kickback from BAC!

Less than 10 days later, I had the finished PCBs in my hand – wow! Here’s a photo showing two PCB’s installed on Wall-E2. I installed 4-pin headers on both ends of the near PCB in order to daisy-chain the I2C and power connections to the rear distance sensor (hidden behind the red ‘rear bumper’ block in the right background).

New VL53L0X array PCB to replace all the hand-wired I2C/Power connections.

Comparing the ‘before’ and ‘after’ photos, it is easy to see that the PCB installation eliminates two 4-pin connectors and a three-loop daisy chain on one side of the robot, and two 4-pin connectors and a four-loop daisy chain on the other side (the one that also connects to the rear distance sensor. Moreover, now none of the 3 connectors used for all seven sensors has more than one wire per pin.

Hopefully this upgrade will eliminate (or at least significantly suppress) wiring and/or connector issues associated with the charger-connect ‘impulse’ – we’ll see

25 March 2021 Update:

After getting the new PCBs installed and some other connection issues solved, Wall-E2’s sensors seem to be a lot more reliable. However, I decided to take this opportunity to study John Kvam’s idea of re-initializing all seven sensors if one of them happens to show up at the default VL53L0X I2C address.

So, I modified the Teensy 3.5 VL53L0X array management code to abstract the sensor init code from setup() to its own function so it can be called if the program detects a sensor at the default I2C address, and then added code in loop() to do just that. Here’s the detection code:

and here’s the new ‘InitAllSensors()’ routine:

And here is the complete Teensy program for managing the VL53L0X arrays:

After getting everything set up, I started experimenting. The first thing I tried was momentarily disconnecting one or the other of the two I2C bus connections at the Teensy end. This was interesting in that the affected sensor array results became invalid as soon as the I2C connection was pulled, but resumed valid output as soon as the connection was restored – nice!

Next, I tried momentarily disconnecting the +V line to the arrays. All sensor outputs immediately became invalid, and stayed invalid after +V was restored. In addition, the code in loop() designed to detect one or more VL53L0X sensors at the default address immediately triggered – nice – but the re-initialization code failed to restore valid output.

Here’s the output from a run were the +V line was momentarily disconnected and then reconnected:

28 March 2021 Update:

I have been continuing to work on the ‘re-initialize after power interruption’ idea for my VL53L0X sensor array, and while I haven’t come up with a very good solution, I have learned some things:

  • The VL53L0X reverts to it’s default (0x29) I2C address immediately when power is removed, but will actually respond to a 0x29 query even after power has been removed. Apparently, the module can draw enough current from the I2C connections to continue to operate (albeit at the default address).
  • A ‘powered down’ (power disconnected, but I2C leads still connected) will also respond to distance measurement requests, but will return a nonsense number (65535).
  • In order to get a VL53L0X sensor to stop responding, the power lead must be physically grounded – just disconnecting isn’t enough.
  • If I use a digital output to power the array, I can turn the power on and off programmatically. Using this tool:
    • Turning power OFF causes distance measurements to return ‘65535’ (because this is the same as connecting the power lead to GND). However, this isn’t the normal failure mode; the normal failure mode for power disconnections is an open-circuit – not GND
    • Turning power back ON again causes the system to detect that one or more VL53L0X units has appeared at the default I2C address. This probably means I could successfully re-initialize all modules.

So, it looks like I can’t really protect against an arbitrary length power disconnect scenario, as I can’t tell when the power has been restored. All I can do is have the program detect the ‘65535’ distance value, wait for some time (a few seconds?) and then try to re-initialize the sensors. This is, unfortunately, a one-shot deal, as if power hasn’t been restored when the re-init procedure is executed, the initialization code hangs up permanently.

Stay tuned!

Frank

ILI9341-Based Digital Clock Project

A while ago, the clock/time display on our microwave started having problems; it’s a 7-segment vacuum-flourescent display, and a couple of the segments a no longer lighting up. Instead of “End”, we now see “Erd”, and the clock is getting harder to read. The microwave itself is still running fine, but because this particular display is our primary time display in the house (aside from our phones), not having a good clock display is annoying.

I investigated getting the appropriate repair part for the display, but that module costs more than the entire microwave did originally, so that didn’t seem like a practical idea. And while I can get a cheap stick-on clock for just a few bucks, what’s the fun in that?

So, I’m in the middle of a design project to build a digital clock to replace the one on the microwave. At first I built up a clock using a Teensy 3.2 and one of my spare Nokia 5110 LCD displays, but that turned out not to be very practical, as the display is basically unreadable from more than just a few feet away, with or without backlighting.

So, I started looking around for better displays, and ran across the ILI9341 TFT display with a touch-sensitive screen. Even better, this was available with Teensy-optimized drivers, as shown here – what a deal! I started thinking that with a touch-sensitive screen, I might be able to implement some on-screen buttons for setting the time, which would be way cool!

So, I ordered two of these displays from PJRC, and started working on the design. Here’s the initial schematic

Here’s my initial breadboard setup:

Teensy 3.2 in foreground, Adafruit DS3231 RTC in background, ILI9341 TFT touch display

I originally used the Arial proportional font provided by the library, but I discovered that it produced bad artifacts after a few hours, as shown below: The only way to avoid these artifacts is to refresh the entire screen on every pass through the 1-second timing loop, which causes a very annoying ‘blink’. Eventually I figured this out, and changed to a non-proportional font, as shown below;

Non-proportional font looks worse, but doesn’t suffer from artifacts

Once I got everything working (well, except for the touch screen stuff that I plan to add later), I fabricated a nice box using Open SCAD and TinkerCad, and made a more permanent version using a half-sized ‘perma-proto’ board, as shown below

Here’s the more-or-less final schematic

7 March 2021 Update:

After a long and somewhat agonizing journey, I finally got the touch-screen stuff working, so I can now adjust the time on my digital clock using on-screen touch-sensitive controls. Here’s the updated schematic:

The only real difference between this one and the previous schematic is the T_IRQ line is no longer connected; the Teensy-optimized XPT2046_Touchscreen.h/cpp library doesn’t use it.

Here’s a short video showing how the touch-screen enabled time/date adjustment feature works:

Although I hope to clean up this code considerably in the future, I include it here in it’s entirety in it’s current state

10 March 2021 Update:

After getting all of the above to work, I decided to re-tackle the proportional fonts issue. In my first attempt, I had used the ‘ILI9341_t3’ version of the ILI9341 Teensy library, and there is a newer ‘ILI9341_t3n‘ version out now. So, I modified one of the example programs (unfortunately still written for the old library) to be compatible and got proportional fonts (well, just the Arial one) working on the display.

After several hours of running this example with no apparent artifacts or problems, I decided to update my complete clock program to use the Arial font. After making the modifications and running it overnight, the time & date displays were still rock-solid the next day, as shown in the following photo – YAY!!

So now all that is left to do is to upload the new Arial-based code (with the time background color switched back to ‘black’) to my ‘working’ clock module, sit back and enjoy the proportional font display.

14 July 2021 Update:

I noticed that my clock had some ‘issues’ with time/date adjustments, so I ‘put it back in the shop’ for some additional TLC. While I was at it, I noticed that the system schematic didn’t include the DS3231 (hard to have a clock without a RTC!), so I updated it as well. Here’s the updated schematic.

The updates made were to make the time/date adjustments more robust. The updated code is included in its entirety below. First the main program:

And then the ‘CustomBox’ class file (no .cpp file – everything is in the .h file)

Stay tuned,

Frank

Wall Tracking Trials Using Office ‘Sandbox’ Part II

Posted 24 January 2021,

Back in November of 2020, I posted about some wall-tracking exercises using my Office ‘sandbox’. Since then I have done some work on the charging station to make it more robust, and on Wall-E2’s ability to home in on and connect to the charging station. The following short video shows Wall-E2 making a complete circuit of the sandbox, ending with a homing run and connection to the charging station.

Wall-E2 makes a complete circuit of the ‘sandbox’, ending up connected to the charging station.

I plan to do quite a bit more work on the charging station homing algorithm, in particular how Wall-E2 reacts when it gets stuck trying to connect (which happens with somewhat disconcerting regularity).

Stay Tuned!

Frank

Wall-E2 Charging Station Update

Posted 17 January 2021,

While doing some ‘local sandbox’ testing with Wall-E2, I noticed that the charging station transmitter was occasionally going offline, even though I hadn’t done anything. After a while I was able to confirm that it simply shut down at some point, for some unknown reason.

After troubleshooting the problem for a bit, I came to realize that the shutdowns were being caused by the NTE960 5V LDO regulator going into over-temp shutdown. Here’s the circuit diagram for the charging station, with the NTE960 highlighted:

After puzzling over this for a bit, I realized why the regulator was going into thermal shutdown. I had stupidly routed the IR LED current through the regulator, so the regulator instead of supplying just the current to the Teensy processor, also had to handle the approximately 1A pulsed IR LED current — oops!

In my defense, this wasn’t actually as stupid as it looks now; the original system design used a 5V power supply to both charge the robot’s battery pack and run the Teensy, so there was no need for a regulator in the system. Later on, the system design changed to use the TP5100 charger, so now the charging station had to supply 12V to the TP5100 and 5V to the Teensy. Adding the 12V supply and the regulator was a non-trivial change to the existing charging station layout, and it just turned out to be MUCH easier to simply place the regulator in-line with the existing +5V power connection, which incidentally also powered the IR LED stack. This worked fine, until I started doing longer runs in my sandbox, giving the regulator more time to heat up and go into thermal overload – oops again.

So, what to do? Well, the obvious answer was to power the IR LED stack directly from 12V. This wouldn’t change the power budget for the 12V supply at all, but would dramatically reduce the power handling requirement for the regulator. However, the current 5Ω 5W current limiting resistor would have to be changed to a 10Ω 10W resistor as it would now be dropping 10V instead of 5V, at the same current. In addition, the current setup had the voltage regulator on a separate terminal strip on one side of the charging station and the IR LED modulation circuit on the other, as shown below.

Teensy 3.2 and IR LED modulation circuitry on left, 12-to-5V regulator on the right

Rather than split the two again, I decided to see if I could put all the circuitry on the left side, next to the Teensy. To do this, I started with two Bakelite terminal strips. In case you aren’t more than about 50 years old, you probably have never seen real Bakelite terminal strips, but they are perfect for this sort of thing. I got mine from a company that specializes in antique electronic items. Here’s a photo of the two-strip layout I devised to accommodate both the regulator and the IR LED modulation circuitry.

Two terminal strips ganged together to accommodate the regulator and the modulation circuitry

First I revised the circuit to bypass the 5V regulator for everything but the Teensy processor, and changed the current limiting resister from 5Ω to 10Ω. When I tested this, everything worked OK, except when I disconnected the modulation signal output from the Teensy to the modulation circuit. To my horror, the IR LED stayed ON! The input to the base of the 2N3904 was pulled low by the 10K pulldown resistor, turning it OFF, which turned the IRF520 MOSFET ON – oops! This was a problem with the original circuit – I had just never noticed it before. This is not a particularly disastrous situation, as the 12V power supply can handle the current, as can the MOSFET and the IR LED’s. However, it just isn’t very good engineering, so I decided to change the 10K resistor to be a pullup rather than a pulldown. As it turns out, this works fine, except now I couldn’t turn the IR LEDs on at all! Some more head-scratching and I figured out that in the pullup configuration, I had formed a voltage divider with the 1K current limiting resistor from the Teensy, and now the LOW signal from the Teensy was being converted to a (mostly) HIGH signal by the voltage divider. Changing the 10K to 100K solved this problem, and now the IR LEDs stay OFF when the modulation is disconnected, and operates properly when the modulation signal is present – YAY! One last ‘gotcha’; when operating from my lab power supply, the Teensy had a tendency to reset when the circuit first went to full load. I cured this with the addition of a 680 uF cap on the +5V line (actually I found that 10 uF would do, but I had more of the 680’s floating around, so…

Here are some photos showing the modified regulation/modulation control circuit

And a scope photo showing the input modulation (yellow) and the IR LED cathode voltage (green), along with the power supply voltage, current, and power values

Input modulation (yellow), IR LED cathode voltage (green), and Power supply output voltage, current and power

Hopefully this will completely solve the intermittent shutdown problem I was seeing in my sandbox trials – we’ll see!

20 January 2021 Update:

After getting everything running, I set up an experiment with a spare IR sensor mounted about 20cm away from the IR flashlight emitter. As shown below, the scope trace in the background is from the IR transistor on the left, in response to the 520Hz square wave transmitted over the IR path from the charging station. Once I got it set up, I let it run most of the afternoon and overnight. The next morning after almost 24 hours, the setup was chugging along beautifully – YAY!

Scope trace shows IR signal received by IR transistor on left. IR Flashlight and charging station electronics shown on right

28 December 2021 Update:

In the process of bringing up my new Wall-E3 robot, I was testing the IR homing module, and discovered that it wasn’t acting correctly – the values being read from the IR homing module were basically zero, even with the charging station IR transmitter less than one meter away. Troubleshooting, I found that the IR transmitter wasn’t transmitting correctly, which I finally tracked down to a (probably) misplaced connection to the Teensy 3.2 waveform generator. However, in the process of doing that, I also discovered that the driving waveform to the IR emitter had a big spike on one transition, which if not really a system problem, sure looked unprofessional.

So, I started looking at the IR transmit module schematic, and decided it could use some TLC. One problem that leapt out at me was the 01/17/21 mod to force the IR transmitter OFF if the connection to the Teensy was lost. This mod involves a 100K resistor pullup to +12V, which, if the 2N3904 transistor base failed ‘OPEN’ would mean putting +12V into the Teensy – probably not a good thing! So, I changed the circuit to route the 100K pullup to +5V instead of +12V. This still works to force the 2N3904 output LOW, which in turn would force the IRF520 OFF. Teensy digital I/O pins are all 5V tolerant, so this is a much better deal.

Chasing around a bit regarding the big spike on the leading edge of the IR transmit pulse, I found that a 0.01 uF cap on the gate lead of the IRF520 did a nice job of killing the big spike, as shown in the photos below:

With these two modifications, the IR transmit block looks pretty solid. Here’s the updated schematic:

The way that I implemented the IR transmit hardware on two parallel terminal strips looks kind of ugly, so I decided to replace that with a perfboard setup and not think of barfing every time I look at it. Here’s the ‘before’

and here is the ‘after’

While I was in the neighborhood, I also decided to modify the IR Beacon transmit code to force all unused Teensy GPIO pins to a known HIGH or LOW state in setup(). This is something I learned about just recently in the Teensy forum, and it sounds like a good idea. I think I’ll write a ‘InitAllGPIOPins()’ function that sets ALL pins to a known state, and follow it with just the necessary changes for functionality. From now on, I plan to do this with all my Teensy projects.

Stay tuned,

Frank

MakerGear MK3-ID BuildTak FlexPlate System Installation

I’ve had my MakerGear MK3-ID for a year or so now, along with a Prusa MK3S. The Prusa MK3S with it’s removable flexible build plate is my ‘go to’ printer for almost everything that can be done with a single extruder. The flexible build plate is wonderful – it makes printing so much easier. Fortunately there is now a comparable option for the MakerGear M3-ID – BuildTak’s 8×10 FlexPlate System. I was able to find the correct size system for my M3-IE at Partsbuilt 3D and it arrived in just a few days (unfortunately with Ohio state tax applied as both the company and I are in the same state). This system makes a HUGE improvement in the ease of printing with the M3-ID, and consequently make it a much more appealing alternative to printing everything on my Prusa. Here’s a photo of the FlexPlate base on my M3-ID.

However, there were a few ‘gotcha’s’ during the installation, necessitating some modifications to the M3-ID.

  • The stock M3-ID comes with a 4mm glass build plate, mounted on top of the heating element, and held down with screw-down rotating clamps at each corner . There’s no need to keep the glass build plate with the BuildTak FlexPlate system, but the resulting 4mm gap means that the stock clamps will no longer hold the build plate down firmly (or at all, for that matter).
  • The FlexPlate system consists of a mounting plate with a number of embedded magnets that is affixed to the flat heating plate with an adhesive film, and a flexible steel build plate onto which the actual build surface (either a BuildTak or PEI sheet) is adhered. The steel build plate attaches magnetically to the mounting plate, and can be easily removed and flexed to pop the print off, a la the Prusa MKS system. However, it turns out that while the mounting plate with embedded magnets mounts quite nicely on the heated base, the 8×10″ steel build plate is just a smidge too large in both dimensions for easy mounting/dismounting. It tends to overhang in one or both dimensions, meaning that one corner rests atop its corner hold-down block, and then the plate isn’t quite flat. This problem could easily be fixed if the steel build plate was just a few millimeters smaller in both dimensions.
  • The Prusa MK3S has a simple and elegant way of achieving excellent physical registration of the flexible build plate when it is placed onto the printer. There are two small protruding posts (3 or 4mm screws, actually) at the rear of the print area, and the flexible plate is notched so that when it is placed against the screws, it lines up perfectly every time. There is no such physical registration feature on the M3-ID, so getting the plate down correctly so it isn’t overlapping one of the corner pieces is a bit of a PITA

So, I needed to make a couple of modifications to the M3-ID corner hold-down system. The idea was to make the build plate fit without binding, and to achieve better physical registration of the build plate when it is re-installed onto the M3-ID after popping off a print.

The first thing I did was simply place a couple of 3mm hex nuts under the hold-down clamp foot at each corner, filling the gap left by the 4mm glass build plate, as shown below.

2ea 3mm hex nuts under the hold-down clamp foot, replacing the thickness of the removed glass build plate

This worked – sorta – but it wasn’t very elegant and didn’t address the other issues, i.e. the flex plate interference, and the problem of physical registration. So, I started designing some alternate hold-down clamp and corner pieces to do a better job. The first effort was a modifed hold-down clamp, as shown below:

Modified hold-down clamp requires only 1ea 3mm hex nut spacer

The thing I love about 3D printing is that you can iterate through several designs rapidly and learning from each version. I usually go through half a dozen versions before getting where I want to go, but it is so cheap and fast that doing it this way is MUCH faster than trying to do a ‘moon-shot’ on-off solution (which generally doesn’t work anyway, due to some unknown unknown).

So, back to the drawing board (TinkerCad) and some more designs. I started with designs to replace the stock corner blocks, and after six revs, had the following final design

MakerGear M3-ID replacement corner blocks – V6A & B are left/right mirror images

and the final design for the hold-down clamp:

MakerGear M3-ID replacement hold-down clamps – left/right mirror images

Both the corner blocks and hold-down clamps were printed with left/right mirror images to match the mirror-image corner requirement.

After getting all the final versions printed up, I installed everything on the M3-ID, as shown below:

Here’s a short video showing me placing the flexplate onto the magnetic base, using the rear corner blocks for physical registration.

Me placing the BuildTak build plate onto the magnetic base

I’ve already made a number of prints with this system (all the corner blocks – about a dozen by the time I was through) and I have to say it’s like night and day compared to the hassle with my stock M3-ID. If you have a MakerGear M3-ID, this is a must-have!

I created a Thingiverse ‘thing’ with the final designs for the corner block and hold-down clamps.

Stay tuned,

Frank

Dewalt DWS713 Miter Saw Dust Port Vacuum Hose Adaptor

My wife got me this really cool Dewalt DWS713 miter saw for Christmas this year, and I have been having fun pimping it out a bit. In a previous post I described how I added a cut shadow line LED light and control box, and this post describes how I added a 3D-printed coupler from the saw’s sawdust exhaust port to a small vacuum I keep in the shop for small cleanup jobs.

My first attempt at a coupler was a straight piece that connected on one side to the exhaust port, and on the other side to the rigid end of the vacuum hose, as shown below:

Unfortunately, I had neglected to consider what was going to happen when I actually tried to use the saw. As soon as I released the downlock and raised the saw, the coupler snapped when the rigid part of the vacuum hose ran up against items on my bench behind the saw – oops!

So, I started over again. I found the TinkerCad ‘bent pipe’ shape generator, and made a few versions that incorporated 45-60 deg bends into the rigid portion of the vacuum hose, but all of these suffered from the same problem with physical interference and cracking when the saw was raised. After some more head-scratching, I discovered I could remove the rigid end of the vacuum hose, leaving just the flexible part. As shown below, this particular vacuum has a detachable end piece that fits inside the flexible hose

Flexible hose connector. Note circular ribs.

So, I decided that I could replace the rigid piece from the end of the vacuum hose with a short coupling piece to connect the sawdust exhaust port directly to the flexible hose. As I normally do with complex projects, I started by printing a test piece – just the portion that couples to the flexible vacuum hose, as shown below:

Short piece to test the flexible hose coupling geometry

Once I had the flexible hose coupling geometry nailed, I did the same thing with the other end, and then connected the two coupling ends with a ‘curved pipe’ shape from TinkerCad, resulting (after a number of revisions) in the piece shown below:

Version 10 – this one worked!

As can be seen in the above screenshot, the final working version was version 10. One of the more wonderful things about 3D printing is the ability to make and discard multiple revisions – all it costs is a little time and a bit of very cheap filament. No need to hyperventilate over mistakes – just throw it away and try again!

The next few photos show the finished coupler installed on the miter saw.

I had uploaded the previous straight-line coupler to Thingiverse here, and I edited it to provide the new design as well

Stay tuned!

Frank