A.R.T.: Autonomous Robot Toy ^_^
A.R.T., PWM and RF
December 20th, 2010 § 0 comments
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.
With the Arduino, we can specify duty cycle and track a certain total duration, but we still need a way to specify frequency.
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)
where 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)
where 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…
]]>
发表评论