Device Software




Our device software algorithm is relatively simple.  We use the Mega32 to:


1.      Sample each analog channel at twice the maximum signal frequency (Nyquist Rate).

2.      Attempt to minimize time in between each channel sample so as to make all 6-channel samples become an instantaneous event.

3.      Construct data packets from the sampled channels.

4.      Send data packets over a communications link at a rate that ensures new data each frame cycle on the simulation software.


Thus, the majority of software constraints come from timing issues.





The KXM52 accelerometers are bandwidth limited to 50 Hz.  Thus, we choose a sampling frequency of 100 Hz to satisfy the Nyquist Rate.  The goal is to achieve 1024-bit resolution to allow for the greatest accuracy.  We implemented a method of over sampling and averaging by sampling the analog signals at 4 times the sampling frequency.  In general, to increase the resolution of a measurement, by W bits, the over sampling frequency must be:


Equation (11): Over sampling Frequency [s1]


Where, W was chosen to be 1, to allow for 11-bit resolution using the 1024 bit internal ADC on the Mega32.  The 11th bit is later eliminated by averaging the signal (divide by four).  Thus, the over sampling frequency is chosen to be 400 Hz.  In this time interval, four independent samples are taken for each channel, and averaged.  A new average value is available at 100Hz.


Because we are sampling 6 channels, we need to change channels in between each sample.  This is accomplished most easily by changing the channel and then starting a sample.  The internal hardware will not actually start the sample until the new channel is selected and the voltages settles (this takes about 13 cycles).  It then takes about 13 cycles to sample the data.


A faster sampling rate is not possible to due speed constraints of the ADC on the Mega32.  Where the maximum conversion rate, fSMAX using a 125 KHz clock on the ADC is:

Equation (12): Maximum Sample Rate


Where 12-bit resolution would require:


Equation (13): 12-Bit resolution Sampling Rate


Thus, the sampling algorithm is as follows:


1.      For each analog channel:

2.      Select the proper channel in ADMUX using a vector in flash memory.

3.      Start a new conversion by writing 1 to ADCSRA.6.

4.      Poll for completion of the conversion (ADCSRA.6 is 0).

5.      Read the 1024 bit data by reading ADCL first followed by ADCH in left-adjusted format and add it to the data vector storing that channel’s result.

6.      Loop until each channel is done.


The value averaging occurs upon data transmission, where the data vector is divided by four (averaged).





The RS-232 interface was chosen to communicate to the PC.  Using the UART at 9600 baud, the communication algorithm must construct a data packet and send it at an appropriate rate.  A transmission rate of 100Hz is chosen for two reasons:


1.      This ensures that the playback software on the computer will receive at least 1 data packet per 60Hz frame cycle

2.      This ensures no data backup as a new [averaged] sample is available at 100 Hz.


This means that the maximum number of bytes that can be sent over the UART, NBMAX in that time interval is:


Equation (14): Maximum Number of Data Bytes


Where, 1 start of frame byte, followed by 6 1024-bit values must be sent.  Obviously, the channel samples cannot take up two bytes, as it will put the frame length up to 13 bytes.  So, the data is chopped up into pieces and sent over as a data packet.  The data packet is organized as shown by figure (13).


Figure (13): Data Transmission Packet

Byte Number




Start Of Frame (SOF)



X1 Low Byte



Y1 Low Byte



Z1 Low Byte



X2 Low Byte



Y2 Low Byte



Z2 Low Byte



Upper Bits

     X1HB Y1HB Z1HB X2HB


Upper Bits

     Y2HB Z2HB   0  0  0  0



Where a low byte (LB) indicates the lower 8 bits of a 10-bit value and high byte (HB) indicates the upper two bits of the 10-bit data.  The SOF byte is used to identify the beginning of a new packet.  Because the application code is checking the RS-232 Port at 60Hz and data transmission occurs at 100Hz, there is no assurance that only full data packets will be received.  A packet value of 0x01 is not allowed to be transmitted over the port.  Sending 0x01 for any byte field has extremely low probability.   In the case that any byte field is 0x01, it is incremented to 0x02.  The data packet is actually a BYTE (unsigned char) array of length 10, where the final byte is null-terminated to tell the transmit loop when to stop transmission.  Thus, every packet byte is not allowed to take the value 0x00, where it instead takes the value 0x02.  Because of the rather small acceleration that a human can have during simple motion, these constraints are well met and rarely (if ever) does a packet have the value 0x00 or 0x01.  There is, however, safety code on the receiving end.


The UART code written by Professor Bruce Land for lab3 was used for data transmission [bl1].  There are 4 functions and several variables used.  The functions puts_int and gets_int initialize transmit and receive operations respectively.  Receive is never initialized.  The interrupt uart_rec receives characters and puts it into the character array r_buffer.  The interrupt uart_send (called when the UART TX register is empty, indicating a byte has finished being sent) loads the next byte in t_buffer into the transmit register, or stops the send loop at the end of a packet transmission via null-termination.


Although there currently is never a case where the application software transmits information to the device, the receive code was left intact for future modifications and expansions.


If this project were to take on a greater scale (or accuracy), then obviously a higher bandwidth communication medium, such as USB, would be required.  For this simple implementation, however, the RS-232 interface works.





Timer0 is used to keep an accurate time base for the system.  The timer generates compare match interrupts at half a millisecond.  Choosing a timer clock of 250Khz and setting the compare register to 125 generates the half a millisecond time base.  Two variables, time0 and time1 keep track of the timing intervals for both tasks (sampling and data transmission – respectively).




The final algorithm is as follows:


1.      Initialize all peripherals (Ports, Timer0, ADC, UART) and variables.

2.      Turn the protoboard LCD on by writing 0 to D.7

3.      Loop forever

a.      If time0 is 5 (2.5 milliseconds)

                                                                          i.      Run the sampling code

b.      If time1 is 20 (5 milliseconds)

                                                                          i.      Divide the sample averages by 4 (two bit-shifts right)

                                                                        ii.      Build the data packet

                                                                      iii.      Send the data

                                                                       iv.      Reset the sample averages to zero



4.      On Timer0 interrupts:

a.      Increment time0 variable

b.      Increment time1 variable


5.      On UART RX (transmission received)

a.      Do nothing


6.      On UART TX (transmission complete)

a.      Send the next data byte

b.      If there are no more data bytes to send

                                                                          i.      Turn off the TX loop