A.R.T.: Autonomous Robot Toy ^_^
Some theory gleaned related to PWM and RF
Disclaimer: this is my first contact with PWM and RF… Feel free to correct me.
General PWM introduction
Using the Arduino to do drive the transmitter circuit would be a temporary hack. Best would be to be a simple circuit using a few dedicated IC to achieve the same (specifically the TX2C
Generating correct Pulse Modulation
I’m trying to have Arduino output a PWM that will in turn drive the transmitter (using a crystal oscillator at a specific frequency) on/off to achieve the needed pulses.
According to “How Stuff Works
“, RC control is four pulses that are 2.1 milliseconds long, with 700-microsecond intervals.
The pulse segment, which tells the antenna what the new information is, uses 700-microsecond pulses with 700-microsecond intervals. The number of pulses will tell what order to execute:
- Forward: 16 pulses
- Reverse: 40 pulses
- Forward/Left: 28 pulses
- Forward/Right: 34 pulses
- Reverse/Left: 52 pulses
- Reverse/Right: 46 pulses
- RC control is 2.1 ms HIGH + 0.7ms LOW for a total of 2.8ms.
- This represents a duty of 2.1/2.8 = 75% duty cycle and a frequency of 1/0.00028 = ~3571 Hz.
- Pulse segment duty cycle is 50% (since pulse = interval) with a frequency of 1s/1.4ms (0.7ms+0.7ms) 714Hz.
According to the Secrets of Arduino PWM
and the Servo PWM FAQ
the Arduino (or rather, the ATMega168 that it uses) has a 16Mhz clock with prescalers (1, 8, 64, 256, or 1024) that can divide this to a “timer”. Final precise control is done by using an integer in the ICR. The microcontroller will count up to ICR and then count down back to 0, turning to HIGH everytime it gets to zero.
Can probably dig this out of the ATMega168 doc: http://www.atmel.com/dyn/resources/prod_documents/doc2545.pdf
The equation is: desired_frequency = system_clock / (2*prescaler_value*ICR)
(1/0.00028) = 16e6/ (2*prescaler*x) or x = (16e6*2.8e-4)/(2*prescaler)
- 1: 2240
- 8: 280
- 64: 35
- 256: 8.75
- 1024: 2.1875
…we can thus use prescaler value 1,8,64 + corresponding ICR value. We cannot use 256 and 1024 because their results are fractional.
Same exercise with the pulse segment:
(1/0.0014) = 16e6 / (2*prescaler*x) or x = (16e6*1.4e-3)/(2*prescaler)
- 1: 11200
- 8: 1400
- 64: 175
- 256: 43.75
- 1024: 10.9375
…we can use either 1, 8 or 64 prescaler (the other two are fractional values).
Higher prescale is better generally as lower timer also reduces power consumption.
The ATmega timers script
should be useful at some point, but I don’t understand the output right now…
How do I turn this knowledge into an Arduino embedded program?
I have no idea yet! I did try to manually create a PWM here by using sleeps:
…and feed that into an hacked together RF circuit based on what I could figure out from the circuit but it… obviously doesn’t do much
I’ve come to the conclusion that buying the IC chip that does the same work and use the provided schematics… would be a lot easier…