This is an 8 channel serial servo controller.
Specs and Usage
It's performance depends on it's clock source. Running at 5V, it can use a 20 MHz clock source maximum, which would give it 0.05 microsecond resolution. At 3.3V, it can use its internal 8 MHz clock and have a resolution of 0.125 microsecond.
Individual channels can be enabled or disabled with a command and then a bit-mask. To ensure safe operation, the controller will start with all channels disabled. The pulse widths and pulse period should be set before enabling any channels.
The pulse period is adjustable, but keep in mind that it works by adding a delay after the final enabled channel is pulsed. All channels that are enabled will be pulsed, so the period can be longer that what the user has set to ensure all channels gets pulsed.
The command set is very simple, one command byte followed by its parameters. To set the pulse width of a channel, send the channel number (1 to
, then two bytes representing the pulse width as a 16 bit integer, send the upper 8 bits first. To enable/disable channels, send a 0x09 then send a byte with each bit representing a channel, the value of bit 0 determines the status of channel 1, bit 7 determines the status of channel 8, a value of 1 means enabled and 0 means disabled. To set the pulse peroid, send 0x0A, then send a 32 bit integer representing the period length, send the upper 8 bits first. Sending a 0x00 as a command byte will do nothing and there are no parameters. This is useful because if you disconnect the serial port in the middle of a command, sending four 0x00 will cause the servo controller to wait for a new command no matter what stage of the process you were in.
The baud rate is automatically detected, upon resetting the servo controller, two bytes must be detected with the first byte being 0x00 for proper detection. You should still use a baud rate that works with your clock source, check the ATtiny2313 datasheet for the best baud rate and frequency combinations.
A neat feature of the way that the command set works and the automatic baud rate detection is that it's guaranteed to work if you send four 0x00 before any commands, the commands can be chained together after the four 0x00.
Project is compiled by AVR-GCC in AVR Studio, WinAVR is needed. Schematic is drawn in EAGLE. Please note that you need to compile this yourself first if you are not using the default 8 MHz clock source. You may also want to modify the schematic to suit your own application.
How It Works
The 16 bit timer interrupt is used. To ensure accuracy, TCNT1 is never modified, and the first thing that's done in the interrupt is to update the output port. The next pulse width is fetched from an array and the alarm is set, the index of the array is incremented until it reaches the next enabled channel, or it is determined that it is the last channel. After the last channel is pulsed, the remaining delay is calculated using the sum of all the previous pulses. The delay is split into the number of overflows needed and the remainder. The delay is executed like a channel would be except no pin is actually pulsed.
The AVR loops until a command is found. If it's a 0x00 command, then no parameters are needed and it loops again. If it's a valid command, it is executed as specified. The timer is started when at least one channel is enabled and it is stopped when the command disables all channels.
The automatic baud rate detection uses the input capture feature of the 16 bit timer. When there is a falling edge on the serial port, the input capture module takes a time stamp. The number of counts between two rising edges when two 0x00 bytes are sent is equal to the time it takes for 10 bits to be sent. The count is divided by 10, then by 16, then decremented, which would give a value to be used for the UBRR register. quadrotor helicopter.