Friday, April 11, 2014

Controlling an RC car with a waveform generator

I recently made a video demonstrating that you can control a basic radio controlled (RC) car with just a signal generator. While this was a fun video to make, it does highlight some really useful features that can be used in almost any engineering setting. In this post, I'll go through how I reverse engineered the control signals and how I came to my solution. Some of these generator features are only available in this class with the Trueform series waveform generators.

  • Arbitrary waveforms
  • Using an arbitrary waveform as a modulation signal
  • Internal mixing of Channel 1 and Channel 2 of the generator
  • AM modulation
  • Arbitrary waveform sequencing
  • Advanced Triggering in a sequence
First off let's provide an embedded video so you can join in on the fun:

My goal was to see how much of the RC car that I could control with just my generator.

I started off with trying to digitize the output of the remote control with an oscilloscope. By digitizing, I could theoretically take the scope's trace, download it from the scope and then output all the points with my generator.

I quickly realized that the length of the controlling waveforms (14ms to 60 ms long) coupled with the really fast carrier frequencies of 45 Mhz would require a lot of memory depth from the scope. An option that I didn't have on my scope. But looking at the scope's capture, I could tell that the signal was an amplitude modulated signal and the carrier frequency depended on the frequency of my car/controller pair.

Since the 33600A can do amplitude modulation with very little effort, I was able to simplify the design down to the shape of the modulation that I was seeing on the scope. A quick look on the internet showed that RC car control is fairly simple. There is normally a series of synchronization pulses followed by a series of control pulse. The sync pulses in this case are a series of 4 pulses that are each 2ms in width, but at 75% duty cycle (1.5ms high, .5ms low). The following control pulses are 1ms in width at 50% duty cycle i.e. 500us high, 500us low. It turns out that the number of control pulses determines the direction of the car.
  • Forward - 40 pulses
  • Forward with the wheels facing left - 52 pulses
  • Forward with the wheels facing right - 46 pulses
  • Reverse - 10 pulses
  • Reverse with the wheels facing left- 29 pulses
  • Reverse with the wheels facing right- 34 pulses

With the help of another engineer who was more interested in my project than what he was working on, we decided that recreating this signal with an arbitrary waveform then modulating the carrier signal in the generator itself would be the easiest solution. This method has the added benefit of keeping my arb signal to a small number of samples. If I had been able to digitize the waveform as I originally planned, each of the resulting arbs would have been a few mega-samples (MSa). This isn't a problem with my instrument, which has the optional 64Msa memory installed. The engineer inside of me would rather be more efficient with my memory even if I have a lot to headroom.

I have a 36622A which is a two channel 120Mhz generator. Agilent has sub-branded the technology in these generators as Trueform. While it has many performance improvements over the traditional DDS generators in its class, they didn't play a factor my design in this case. However, two features did. The generator is able to use the signal from channel 1 to modulate channel 2 (or vice versa). I could have just used channel 1 with an arb as the modulation source, but I wanted to be able to sequence the waveform too. More on that later.

My first step after deciding on this route to to start designing my waveform. Since I knew that channel 1 would be the modulation source to determine the envelope's shape, I had to be aware of modulation signal requirements. The modulation source's amplitudes are important here, at +1V the carrier signal is transmitted at full carrier amplitude, and at -1V the carrier signal's transmission signal is 0Vdc. With that in mind, I created a series of pulses. The first section was the four 2ms sync pulses. Using Waveform Builder Pro, it was simple to create a square wave that was 75% duty cycle, 2ms wide, and repeat that four time. Then I appended the 1ms, 50% duty cycle pulses to that signal. I started with the reverse going signal since that was the most simple with 10 pulses.
Figure 2. A typical reverse signal on the RC car w/o the modulation. 4 sync pulses, followed by 10 1ms pulses

This signal was designed with a 20Ksa/s output rate. I needed to remember this setting since the timing of the signal is important. When I use the generator to play this signal, I needed to ensure that the sampling setting on the generator is the same as I designed it. Once I was done with this signal I saved and used channel 1 to output it. Since the 33600A saves the amplitude and sample rates with the arb file, I just needed to do a quick front panel check to make sure nothing happened to my designed signal during the transfer.

Then on channel 2, I set the output to be a sine wave with a frequency that matched my RC car's signal of 45 Mhz. The amplitude could be set depending on how far away from the generator I wanted to control the car. For the purposes of the video, I just set it to maximum amplitude of 10Vpp. But further testing I found that with 2.5Vpp I could limit the distance to my desktop.

The critical part of generating the right signal was the AM modulation. I set the generator to turn Modulation On and ensured that I was using internal modulation. One of the unique features of Trueform generators is the ability to modulate using the other channel as a modulation source. I set the Modulation source to channel 1, which is now generating the reverse arb that  I showed in figure 2. That's all that I needed to create the signal. After turning the channel 2 output on, I was able to make the go backwards/reverse.

My real goal was to control the car in different directions, not just one direction.  This would require multiple arbitrary waveforms to be outputted by my waveform generator. Rather than creating one large waveform that would be difficult to change in the future, I decided to use waveform sequencing which is a feature that is not often seen on this class of waveform generators. Waveform sequencing allows a designer to grab different arbitrary waveforms that he has designed and easily put them together in new orders, lengths, or transition between the waveforms with a trigger.

I mentioned earlier that sequencing is why I decided to use Channel 1 to modulate Channel 2. If I had decided to use an arb to modulate Ch 1, I would have limited my flexibility. With sequencing, I can easily change the duration or trigger the next waveform with a couple of clicks. You can do this as well with editing the waveform by itself, but it is more tedious to try and move the arbs around if you manipulate everything in a single arb. You would need to determine which which samples started and ended your arb, then move those around at the sample level. An analogy would be the difference between programming a simple equation in assembly vs. a compiled language. You could write the equation as:

int a =1+2

or your assembly program can start off as:
 number db 7 dup 0     ; string which will store input and output
  n1     dw 0           ; two input variables
  n2     dw 0
  res    dw 0           ; one output variable
  cr     dw 13,10,"$"  ; carriage return, line feed
  mov dx,offset number
  mov bx,dx
  mov b[bx],5   ; maximum 5 characters to read
  mov ah,0ah
  int 21h   ; read in a string from keyboard
  mov bx,offset number +1
  mov cx,00
Then continue on for another 30-40 lines of code. Both have their uses, but I think that you'll agree that putting things into a higher level hierarchy can make things a lot easier.

I created individual arbitrary waveforms for each of the directions above. Forward, forward with a right turn, forward with a left turn. and the same for the reverse directions. With a library of six waveforms, I can now mix those waveforms to go in any number of directions. Now rather than having individual signals, I can put them together to create a much larger signal we call a sequence. Each of those waveforms I designed are now segments in my new waveform sequence.

If I wanted to just have the waveform segments repeat a number of times, I can set the "Play Control" to repeat then set the number of times I want that waveform to play. I did this in the video and got some pretty fun results.

Another sequence control that is very useful is the Repeat until Trigger setting. This setting will continuously play a signal until a trigger is received. In the real world, this can be controlled with an external trigger that is connected to another instrument such as a DMM. We can also trigger this with a manual trigger from the front panel. I would use this setting if I were to go through an actual obstacle course since trying to time the obstacle course in terms of waveform cycles would be difficult. By using the trigger, I could wait until an event before triggering my next waveform direction.

So, there you have it. Even though this post was pretty long. The actual amount of engineering time to do all of this was less than an afternoon's worth of work. It's hard to even call it work since it was so much fun to do.