Fun with electronics

A RC Toy Car

My nerd interests are extending to electronics and remote operated vehicles. The goal of this project is the creation of a RC car capable of streaming video from an on-board camera. There are many like it but this one is mine. The first version of the vehicle has no camera. I also want to measure various things like battery voltage and current.

If anyone is interested in the code, drop me a mail and I might upload it on GitHub.

PC PSU as Bench Power Supply

First things first. I required a power supply with 3.3 V, 5 V and about 12 V. Fortunately standard PC power supplies can do that for little money. There are guides on the web on how to use one as bench power supply. The reset pin on the ATX connector must be shorted to ground to turn it on. In addition my unit required a load of approximately 1 W at one of the 12 V rails in order to provide stable 3.3 V. I connected a standard PC fan which does the trick.

Picture of a PC PSU slightly diverted from its intended use ...

What a mess! Home made adapter on the ATX connector of a standard PC power supply. There are proper boards for sale that serve the same purpose, e.g. this one.

Chassis

I try to make good use of old LEGO pieces.

Picture of the chassis made from LEGO mostly.

A preliminary version of the chassis.

The LEGO motor is rated for 9 V and runs at high RPM and low torque (see Philo's great write-up) Therefore a gear box is required. I needed a differential gear to drive through curves.

The steering mechanism is made from a cheap mini servo and a steel rod from a CPU fan mount. Works quite well actually.

Electronics

I put (almost) everything on a breadboard. Has to be good enough.

Picture of a breadboard with electronic components

My circuitry. If this was a proper PCB it would be the pinnacle of DIY electronics. From left to right: microcontroller board, servo, power and motor connectors, motor driver, sensors, amateurish input protection and finally a voltage converter.

The heart of this thing is a Teensy 3.2 microcontroller board. It is fast, has plenty of peripherals and is easy to use due to Arduino compatible libraries.

I use an H-bridge IC, the L293, as motor driver, allowing to drive in reverse. It is rated for 1 A. The LEGO motor draws less than that. The motor that I bought after that is still in the 1 A range. So no worries.

I measure the battery voltage straight forwardly in the middle of a voltage divider. This drops the voltage proportionally to something that can be safely connected to the input pins of the uC. I added a OP-Amp buffer, just because reasons ...

This configuration uses a ACS 711 hall effect electrical current sensor on top of carrier board. I found it helpful to filter its output and amplify it with an OpAmp. It is a bit noisy, however tolerable.

Current vs. Counts

Measured current with my good old multimeter versus the counts that the ADC spit out.

The full circuit can be powered by 9 - 12 V from the battery or the PSU. My version of reverse polarity protection is made of a diode and a polyfuse. Might not be such a great idea ...

RaspberryPi's and servo motors need a supply of 5 to 6 V. So I ordered a common switch mode regulator for RC models. It is rated for 5 A which is plenty for the little servo and anything that I might need it for later on.

Prototype w/o Video

First tests

The vehicle mostly assembled: USB is disconnected, control inputs are received by Wi-fi. The motor is running as commanded. Everything is powered by a 9 V NiMh battery pack.

Assembled vehicle

German engineering in full glory!

Screenshot of remote control software

Screenshot of my remote control program. It is written in Python. PyQtGraph is used for plotting and PyGame for inputs from gamepads and joysticks. Top left: forward control input (grey = keyboard input, red = commanded PWM duty cycle, blue = actual value applied to motors), Top right: steering input (positive means right, negative means left). Bottom left: Battery current - was not really working at this point. Bottom right: Battery voltage.

The vehicle works in-doors. But it has trouble with slopes and rougher terrain for various reasons. Maximum range, outdoors within line of sight is approximately 70 m with the ESP 8266 configured as access point and a Mac Book Air as remote control. I mounted the WiFi-adapter on a little pole to keep it away from interference. It also looks cool.

Motor Speed Control

Motor speed control is very useful because it helps to keep the vehicle speed steady under changing loads like when driving through curves.

Let's begin with sensing the motor speed. What I conceived involves Neodym magnets mounted to the engine shaft and a pair of hall effect sensors to detect the passing of the magnetic fields. By the order of activation of both sensors it is relatively straight forward to not only measure the frequency but also to figure out the direction of rotation.

Motor Frequency Sensing

Motor frequency measurement and control testing rig.

Motor Frequency Plot

Interesting motor characteristics ... Left: Step response of measured frequency vs time. PWM value of 255 corresponds to 100 % duty cycle. Right: Frequency vs PWM after reaching steady state.

The control algorithm is more or less your standard P-I-controller. Parameters were guesstimated from the step responses of the motor.

Raspberry Pi video & Wifibroadcast Radio

So i got a Raspberry Pi A+ and the camera that belongs to it. Getting it to capture a video stream is straight forward with raspivid. Video compression is already already performed by raspivid, which is nice.

Communications is a bit different now. The RPi - with a USB-WiFi stick attached - basically replace the ESP 8266 board. I run a program on the RPi that does all the telemetry and command packet relaying much like the program on the ESP 8266 module. In addition, video data are send over the WiFi link, one to one, as they come out of raspivid.

Furthermore, I found the awesome Wifibroadcast project. It comes with programs that can send and receive packets without association between WiFi devices, much like analog radio transmissions. This eliminates the case of failure where devices fail to reconnect after a temporary disruption, e.g. due to blocked line of sight. It also allows for damaged packets to arrive - useful for video transmission.

Raspberry Pi Video Transmitter Rig

The testing rig for the Raspberry Pi. It transmits videos in 720p easily over 100 m distance to my Mac Book. I haven't checked the maximum range yet. Time lag is about 300 ms. Not exactly great but also not catastrophic ...

Custom Parts

I wanted to try a new motor and I also needed a housing for the camera to mount a wide angle lens. So I had some parts 3D printed. They are made from Polyamid by laser sintering.

Printed Motor Mount

Printed motor mount and axis adapter. Almost perfect fit!

Camera Housing

The camera housing. Oops ... I must have made a mistake. Nothing that could not be fixed though.

Motor Control Cont.

With regard to the new motor, I decided to attempt to measure the motor speed by sensing the back electromotive force (EMF).

Problem with my previous Hall-sensor based sensing is the dependence of its reaction time on speed. Moreover, the new motor comes already with gearing which would make it nearly impossible for me to attach the sensors directly to the motor shaft for faster response.

Back EMF is the voltage induced across the motor terminals by the coils turning in the magnetic field of the permanent magnets in the motor. It is proportional to speed and can be measured directly when the motor terminals are floating. There are some nice write-ups on the net which I followed.

Drawback of this method is that I cannot run the motor at 100% duty cycle because there needs to be some interval during which to take voltage samples.

Measured BEMF waveform

Captured waveform at a motor terminal. When the PWM signal goes low, there is an inductance spike. After this, the voltage drops to the BEMF level. My particular uC can generate IRQs whenever the PWM signal goes high or low, which I use to determine what samples are okay to take and which ones to reject. Samples are collected continuously by one of the two ADCs available in the uC.

RPM Control Demo

Motor RPM control demo. I captured these waveforms from the assembled vehicle. Left: Increasing the commanded value. Right: Manual braking, literally. PWM duty cycle goes up in response. The display is in arbitrary units. In fact I don't know the actual speed. But that is okay. One can work with a signal that is merely proportional to it.

Drone Car Version 2

Control station

The control station. It is really just my trusty old laptop! It runs a dual boot setup with Linux and Mac OS. Very handy. The video on the of this page shows a lengthy sequence of a proper screen capture.

The remote control program had to be extended significantly. Since I already started with PyQtGraph, I continued to develop it into a more or less complete application with the help of the mighty Qt framework and its python bindings. After evaluating various means of video streaming, I decided to use Libav directly and came up with a little ad-hoc decoder module. With the help of the nice code samples on the web I got it working in short time.

Lego Toy Car Version 2

Improved drone car. Now comes with video feed. This version also has wheel suspension enabling mobility in rough terrain.

I should see if I can somehow reduce the input lag and increase the range. Also, I should better buy a model car chassis.

To be continued ... eventually ...