Line-Following Robot

In an earlier part of my life I spent my working days writing device drivers for things like printer mechanisms, disc drives and so on. What they all seemed to have in common was that they turned a motor. I was missing turning motors so when I came across a book “Robot Building for Beginners” by David Cook I pricked up my ears. The book leads you from knowing nothing about electronics to building a robot which will trundle along following a line drawn on the ground. This looked like fun so I thought I’d build it.

Book Cover

The technology that the book uses to construct the robot is purely analogue. The line is detected with photoresistors and the motors are simple DC motors with no steppers in sight. What makes the book stand out is the superb way the author explains how and why electronic components work. He explains through examples about resistors and voltage dividers, through LEDs and capacitors, and from comparators to motors. Now I didn’t start from scratch with my knowledge but it seems to be a extremely good way to learn from scratch. And you get a cool robot at the end. Even if it is made from a carry-out box.

I’d built the robot and it worked but the motors were turning too fast. Slowing down a motor is harder than it sounds as all the easy options — adding resistors for example have big drawbacks. I added a PWM-based control to the motor speed controlled by pushing buttons. Here’s the PIC code: This took a little while as although I had spent my time turning motors I don’t remember using PWM, so I had to learn it. I was using an online copy of the book on the learning part of the IEEE website. I went back to SkillSoft to read the next chapter of the book and the IEEE had stopped using SkillSoft and I could no longer read the book. Luckily I found a paper copy of the book for sale online and bought that so I could continue the project. But it reminded me to not rely on things in the cloud.

Here’s a video of the first run of the robot in action.

Line following robot first run 480p

As you can see the robot needs to be made more robust. One thing I learned from making it is that my usual technique for attaching wires to pins using wires taken from ribbon cable is not good enough (despite copious application of hot glue). This leads to lots of tweaking of connectors. So before I show the robot to my grandsons I’ll have to find a better connection method or they will destroy it with their youthful exuberance.

Setting the time on a DS1307 RTC without GPS or NTP

I’m going to use a real-time clock (RTC) in a future WSPR project so that I can start transmitting at the start of a minute. I’ve never used an RTC before so I thought I’d better fix that. I got a DS1307 RTC from Hobby Components. This module comes with an Arduino library to drive the I2C connection so I’m using a SEM01K Arduino Nano clone to drive it. As you can see the wiring is simple, just ground, 5V, and the two wires for I2C.

Typically you might set the time on an RTC using a GPS module or over the Ethernet from an NTP server. I don’t currently have either a GPS module or an Arduino Ethernet module so neither method is immediately available to me. But I do have a MacBook Pro whose time is set by a local NTP server. So I wrote a small Arduino sketch to set the RTC time from the Mac. The procedure to set the time is a bit manual but it only needs done once as the RTC is kept alive by a battery.

From the sketch:

// To run:
// 1) compile and upload this sketch
// 2) on a Mac terminal do: cat < /dev/cu.usbserial-14430
// where /dev/cu.usbserial-14430 is the Arduino device
// 3) on another Mac terminal do: date "+%y/%m/%d_%H:%M:%S" >> /dev/cu.usbserial-14430
// the date and time is output
// 4) Kill (^C) the cat.

Arduino and RTC

To check that I could use the RTC after the date and time is set I also wrote a little demo sketch which turns on the Arduino internal LED for two seconds at the start of each minute.

The sketches are in this ZIP file.

SDRplay and dodgy USB connection

I had thought that my SDRplay RSP2 was dead because none of my computers would recognise it. But I noticed that it was still drawing current from the USB port when attached and 50 mA seemed reasonable.

I got it to work under CubicSDR somehow, but it was not reliable. Luckily at some stage it was working (I was listening to a Classic FM broadcast) and I accidentally tapped the RSP2 and the dulcet sounds of the orchestra turned into a loud buzzing noise. I realised that it was a hardware problem and I tried to recover and nothing would work until I tried an old USB cable. The RSP2 works fine with this cable but not with any other!

Maybe I’ve lived a sheltered life but I don’t remember any device having a dodgy USB type-B socket. Micro- and mini-USB fails are common, but type-B?

Anyway, I’m happy now because I can monitor my VHF Q65 transmissions using the SDRplay.

WSJT-X and JTDX shared memory conflict

If, like me, you use a Mac and both WSJT-X and JTDX for data modes you may run into a problem I had.

The problem comes about because both applications insert a property list into /Library/LaunchDaemons. These property lists are used by the MacOS to start background processes (or daemons) at system startup. But as far as I can tell there is no defined order in which the daemons are started.

I installed the SDRplay API which as part of the install puts a property list into /Library/LaunchDaemons. This must have affected the order in which MacOS started the daemons because suddenly WSJT-X failed to start with a shared memory error. This error persisted even after a re-install and configure of WSJT-X.

I looked at /Library/LaunchDaemons because as part of the WSJT-X install you put a property list there. Sure enough, JTDX does the same (as it is derived from WSJT-X) and the property lists clash because (at least on my system and my version of JTDX) JTDX makes the shared memory size smaller than WSJT-X likes.

So, I think I was getting away with this before I installed the SDRplay API because the WSJT-X property list was being processed after the JTDX one and the shared memory was made big enough for WSJT-X. But after my SDRplay API install the JTDX property list was being processed after the WSJT-X one and the shared memory size was too small.

I fixed this situation by deleting the JTDX property list com.jtdx.sysctl as it is redundant in this circumstance.

And all is well.

SignaLink Jumpers for FT290R (correction)

I was playing about with my FT290R and Q65 protocol and realised that I had to configure my SignaLink jumpers in a way different from how I had previously blogged. 

So these are the settings that I now find ok. Apologies if you’ve been misled by my previous post.

SignaLInk Jumpers for FT290R  correction

PIC12F1840 Si5351a VFO

To recap: this is a no-frills VFO intended as a drop-in replacement for a Colpitt’s oscillator in a Direct Conversion receiver. It allows the frequency to be changed within limits set in the code and allows the tuning to be toggled between fast and slow. An LED lights if a frequency limit is reached.

I decided what to use instead of the PICs I usually choose. The answer is: … more modern PICs! A lot of the competition are modules which makes them bigger. 

I bought a PICkit 3 which seems to be a lot cheaper than when I last looked. This allows me to program a PIC12F1840 which is much smaller than a PIC16F887. So I have ported the PIC16F887 Si5351a VFO code to that PIC. I have improved the encoder turn handling. With the encoder I’m using I needed to debounce by adding capacitors to ground. The tuning speed is toggled with a button in the encoder. It may be nicer to have a switch instead, perhaps a DIP switch for the tuning as holding down the button while tuning is a bit clumsy.

VFO Wiring

The PIC12F1840 has a sleep instruction so the code now does all the encoder turn processing in the ISR. The main loop goes to sleep and all that is done in it is to change the frequency of the Si5351a. So the PIC is asleep nearly all the time. It only wakes up when the encoder is turned. The Si5351a is always on, though, as it is generating the clock that the received RF signal is beating against.

A separate button (or DIP switch) allows the user to change the amount the frequency changes each turn. The VFO uses 30 mA when sleeping and 40 mA when the encoder is turning. I don’t know what the Colpitt’s oscillator took.

Here’s the code.

While I was debugging the code I took the following screenshot:

Debug Screenshot

The yellow and blue are decoder turn voltages. The pink is the LED used for debug. It goes high if the code is on the ISR. As you can see it enters the ISR at every encoder turn change. The reason I’d had to go to these lengths to see what was going on was that I’d assumed that the interrupt-on-change flag was for all changes, but it isn’t. There are separate flags for rises and falls. Moral: always read the data sheet!

The footprint of the VFO is only slightly larger than the Colpitt’s oscillator and if that used a beefier variable capacitor the new VFO would be smaller. I’m hopeful it will be useful in a lot of projects.


I finally got a decent image from the space station. The recent ISS passes have been plagued with interference from somewhere, but this image seems fine.

PD120 20210624 092404

I’m using this setup — the aerial is my Cebik Moxon.

ISS 6 of 12

The Raspberry Pi 3B plus is running QSSTV. The USB Audio dongle is a 33051D. The pre-amp is an M-100.

Si5351a VFO for IC Based Receiver

This is a drop-in replacement for a Colpitt’s oscillator as the local oscillator for the mixer in a direct conversion receiver using a NE602. So it has no frills — it just generates a square wave at the required frequencies. The tuning is done with a rotary encoder. The receiver I want it for works on the CW part of the 40m band so the VFO tunes from 7.000 MHz to 7.020 MHz. An LED lights when a frequency limit has been hit. The encoder button is used to toggle the tuning rate between fast (1000 Hz per click) and slow (100 Hz per click). These can be changed to any pair of values, as can the frequency limits.

A Si5351a synthesiser is used to generate the square wave. It is controlled by a PIC micro-controller.

PIC 887 VFO Layout

I wanted to use a small 8-pin PIC for this to make the VFO have a small footprint. I chose a PIC12F1840 which has the I2C built-in needed to drive the Si5351a. But I found that I couldn’t program this PIC with my ageing PICkit2. So I tried my even more ancient K150 programmer — no joy here either. So I’ve had to use a PIC16F887 for now — even though it must be twenty times bigger. I considered bit-banging the I2C with a PIC12F683 or a PIC12F688, but it looks pretty onerous and I don’t want to spend my time chasing I2C errors. It may be the time has come to move on from PICs though I haven’t seen any alternatives that appeal yet.

The code traps encoder turns as interrupts and works out which way the encoder is turning. The debounced encoder button and frequency changes are done in the main (endless) loop. The Si5351a I2C is driven using a port of Hans Summer’s Si5351a Arduino demo. Thanks Hans! I’m also using one of Hans’ Si5351a module kits. I ‘trimmed’ the 27 MHz crystal by changing the value of SI_XTAL_FREQ in si5351a.h to 27003934 which gave the expected frequencies as seen on my ancient RACAL-DANA 9916 frequency counter.

Here are the source files and make file to build the VFO.

I haven’t tried this in the receiver yet, but it’s hopefully useful as it is.

Sometimes an encoder turn isn’t seen, but this doesn’t seem to be too obvious in use. I intend to fix that when I port the code to whatever PIC replacement I choose.

Rotary Encoder Test for PIC

I’ve been playing about making simple direct conversion receivers using an NE602 for the mixer. These receivers have some sort of input network for the signal captured by the aerial, mix that with a VFO and amplify the (possibly low pass filtered) audio output from the mixer.

The “classic” version uses a Colpitt’s oscillator for the VFO. This is an analogue oscillator that feeds back via a voltage divider made by a pair of capacitors. This works well and tunes nicely and is magical in its own way. However, the tuning is quite coarse with the variable capacitors I have, and the cost of replacement variable capacitors is getting eye-watering. They can also be quite large.

So I’m trying a replacement VFO made from an Si5351a clock generator. The Si5351a will be controlled by a PIC, being my microcontroller of choice (and available in my junk box). The tuning will be done by turning a rotary encoder. 

I had a rotary encoder of the right size in my junk box and but had no way to find out how it performs. So I wrote a small test program for a PIC16F887 which drives the rotary encoder and shows on LEDs which way the encoder was turned, whether it was turned recently and whether the button on the encoder was pressed or not. I often use a PIC16F887 for tests like this as it has many i/o pins that can be digital or analogue and can be pulled up at will. I don’t think I’ll be using it for the VFO as it is quite big (40 pins!) but I’ll be able to re-use the code amended for whichever PIC is choose.

The schematic is simple: pins on the PIC PORTB are weakly pulled-up and are used for input from the encoder. Four LEDs are connected to PORTD each with a current-limiting resistor. One is the power on LED, the others show what is happening (or what the PC thinks is happening) when you play with the encoder. All the pins are digital.

Encoder Test Schematic

The built test is shown below. The wires you can see that are not shown in the schematic are connections to allow the programming of the PIC using a PICkit2. Ignore the LED on the bottom left as it shouldn’t be there.

Encoder Test on Breadboard

The code and make file is in this zip file. Changes made at the encoder by turning the knob are seen via interrupt. The button changes are polled. The LEDs are lit (or not) in the same polling loop.

Tune in later for the VFO itself.

Morse Sending Tutor Mock-up

I realised that now I’ve made a CW Sidetone Oscillator, a Morse Keyer and a Morse Decoder, I could make a useful tutor for testing my sent morse.

The trick of sending good morse is in the timing. Getting the inter-character and inter-word gaps the correct length is quite difficult especially at higher speeds. So a tutor to check this could be a big help.

Morse Sending Tutor Diagram

So I lashed this together using a breadboard to do the connections. 

IMG 0070

And tested it as seen in this video: Morse Tutor

As you can see it’s very rough and ready. If I were to make a proper version I’d remove the WPM and tuning aid on the top line which aren’t necessary. It would fit into a small box quite easily.

It was fun to throw together!