High Level Design

Program Design

Hardware Design


What Next?

Source Code



Program Design.

For our project, we have two separate programs: one for the transmitter and one for the receiver.

In the transmitter, we have three separate tasks running, all off of the time base generated from timer0. To keep the time base, we used the timer0 overflow interrupt. The three tasks were to start the transmit interrupt, read in user input, and run the power button debounce state machine.

The reason why our group needed a separate task to start and stop the transmit interrupt was to keep the interrupt non-blocking. We used the data register empty interrupt to tell when it was ready to send the next bit, which under normal conditions is always faster than the 20 ms this task was run at. However, we still used this interrupt to make sure that our code was failsafe. The data register empty interrupt is triggered when a byte is transmitted from the UART I/O Data Register (UDR) to the Transmit Shift Register. We set the 8-bit UART BAUD Rate Register (UBRR) to 255 to send and receive at a BAUD rate of 1953.13, the slowest possible BAUD rate with a clock of 8 Mhz.

To read in the analog inputs generated by the user, we used two lookup tables. The first lookup table was used to take the raw input voltage and place it within a specified range to determine which of the 15 magnitudes to set each motor to. The second lookup table was used to turn the magnitudes into the correct transmission packets, without overwriting the opposite engine’s information while updating each engine. This task ran at 50 ms.

Our last task is a simple four-state debounce state machine used for the power button. This task ran at 30 ms.

For our receiver, we had only one task, running at 20 ms based off of timer0. The job of this task was to receive the transmitted byte, parse it, check if it is meant to turn on/off the hovercraft, and if not, to convert into the appropriate signal for each of two motors. Our group once again used a lookup table to determine exactly what signal to send to each motor. The motors obtain their values by manipulating the timer1 Output Compare Register A (OCR1A) for the right engine and timer1 Output Compare Register B (OCR1B) for the left engine.

Timer1 is set to PWM mode, which generates a wave that counts from 0 to 255 and back down. Once the counter is the same as the value in the output compare register, the resultant output wave transitions from high to low, or low to high, depending on the current state. An OCR value of 255 will generate a completely low output signal, resulting in a full forward value. An OCR value of 128 will generate even square output wave, resulting in a stop value, and an OCR value of 0 will generate a completely high output wave, resulting in a full reverse signal. More details regarding the operation of PWM can be found in the hardware design.

After OCR1A and OCRIB are updated, we enable the receive complete interrupt to keep the code non-blocking and to make sure that the OCR1A and OCR1B values do not change while updating them.

A few problems we ran into were due to the fact that when the transmitter and receiver are reset, they both assume that the hovercraft is off. When the hovercraft is off, none of the three motors can move. If only the hovercraft and not the transmitter is reset, the hovercraft will think its off but the transmitter will think it is on, and vice versa. Another problem was that originally, if the hovercraft lost the receive signal, it would keep its last signal and keep using that value over and over again. This would not be good, for example, if you hovercraft went out of transmission range and kept going and going and going… We fixed all these problems in the final versions of the code.