wiki/ LV0/ Payload/ LV0 PIC

PIC and Accelerometer
?PIC/Accelerometer Schematic

The Accelerometer

The main payload of the rocket is the little itty bitty prototpe of our future kick-ass inertial navigation system (INS). It's a micro-machined solid state accelerometer produced by Analog Devices, Inc called the ?ADXL50 (it's the small metal cylinder above the black chip). It's a killer device, complete with onboard signal conditioning, an exterrnally available onboard op-amps, a self-test function, and even ?excellent documentation. NOTHING beats the ADXL series for prices versus performance; these guys run for around $30 (although AD is great with samples - thanks AD!) while their more accurate cousins run for more like hundreds of dollars. Our initial flight simulations (using ALT4) predicted an acceleration of around 10g, so we reduced the dynamic range of the ADXL50 from the +/- 50g maximum to +/- 20g for improved resolution and reduced noise. To reduce noise further, we bandwidth limited the accelerometer to 1KHz. Now frankly, this was probably a bit conservative but we wanted to have a really flat response (see the frequency response on the ?datasheet). We could have had improved noise reduction by lowering the bandwidth to 300Hz but we were afraid of higher frequency components slipping by. The military likes to run their INS a sample rate of 250Hz but who knows how oftern they sample their sensors. Once we get the acceleration data, we'll run an FFT (Fast Fourier Transform) on the data and find out what frequencies seem to be imporant and then decide what bandwidth makes "sense".

The PIC Microcontroller

The main part of the flight controller was the Microchip, Inc. PIC microcontroller. We used the PIC16C73A which is a 28pin DIP with 1K ROM, 256B RAM, a USART, a 8bit A/D converter, and the kitchen sink in their for good measure. We programmed the PIC on Microchip's PICSTART+ development system which, by the way, rocks. It's probably the best integrated development environment out there and it's free. If you can handle a 24 word assembly language, and excellend development environment and an amazing variety of microcontrollers (from 8pin(!) to 64pin).

The PIC digitizes the accelerometer data and spits it out at a furiously fast 300bps (ha) to our modem for transmission to the ground. Using the onboard 8bit Analog to Digital converter (ADC), we get a (+20g - -20g)/256 = 156mg resolution. Now, granted, this isn't the best resolution but hey it's a prototype. Future systems will need on order a 12bit system to get our resolution close to the noise floor (5mg). Once the 8bit data bytes get converted from the ADC, we send them out as fast as possible into the onboard USART (Universal Synchronous/Asynchronous Receiver/Transmitter). We use the asynchronous transmitter to send the data out of the PIC in the standard serial format used by most computers (8data bits, no stop bits, 1 start bit). The data gets sent out at 300 bits per second (bps) which actually drops our sampling rate to 37 samples/second. Ugly, huh? On the next flight, we'll up the throughput rate as high as possible, and then perhaps implement some crude data compression schemes to help.

Here's our our incredibly simple assembly language program we wrote to digitize and dump the data to the modem:

; AESSS High Altitude Launch Vehicle PHASE 0 PIC Controller
; File: MAIN_2a
; 5/23/98
; Andrew Greenberg
; This is the PHASE 0 rocket launch PIC PROGRAM. It is meant to take an A/D
; sampling and throw it out Port B and the Port C UART. It expects a 16C73A running at
; 1MHz with the A/D device sampling CH0 (RA0/AN0). This program uses A/D
; interrupts instead of polling. The sampling rate is approximately once
; every 80uS (12.5KHz). The UART is set at 300bps (300bps.
        list      p=16C73A
        #include <>
; --------------------- Reset Interrupt Vector 0000H - 0003H
        org 0x0000
        goto start

; --------------------- Interrupt Vector 0004H
        org 0x0004
        goto int_svc

; --------------------- Main Program Memory 0005H -
        org 0x0010
; Initialize from Reset
; Initialize ports, interrupts and A/D converter
        clrf    PORTA                   ; Set PORTA output latch to 0 (optional)
        clrf    PORTB                   ; Set PORTB output latch to 0
        clrf    PORTC                   ; Set PORTC output latch to 0
        bsf     STATUS,RP0              ; Switch to Bank1
        movlw   B'00111111'     ; Set for PORTA Bits 0 - 4 (5 pins)
        movwf   TRISA           ; Set PORTA to tri-state
        clrf    ADCON1                  ; Set PORTA Ch0 - 3 as analog inputs, Vref = Vdd
        clrf    TRISB                   ; Set PORTB to all outputs
        movlw   B'11000000'     ; Set PORTC 7,6 to TRI-state for RX/TX
        movwf   TRISC           ; Set PORTC to all outputs & TRI-S for RX,TX
        bcf     STATUS,RP0              ; Switch back to Bank0
; --------------------- Initialize A/D Converter
        BSF     STATUS, RP0             ; Switch to Bank1
        CLRF    ADCON1                  ; Configure A/D inputs
        BSF     PIE1, ADIE              ; Enable A/D interrupts
        BCF     STATUS, RP0             ; Switch to Bank0
        movlw   B'00000001'    ; Select: 2*Tosc, CH0, Turn A/D on
        movwf   ADCON0         ; Move to ADCON0
        BCF     PIR1, ADIF              ; Clear A/D interrupt flag
        BSF     INTCON, PEIE            ; Enable peripheral interrupts
        BSF     INTCON, GIE             ; Enable global interrupts
; ---------------------- Initialize UART Transmitter
        movlw   B'10000000'             ; Select: Port C serial ports (not I/O), RX diabled
        movwf   RCSTA
        BSF     STATUS, RP0             ; Switch to Bank1
        movlw   51h                     ; Load 51 -> 300bps (-> +0.16% error)
        movwf   SPBRG           ;
        movlw   B'00100000'     ; Select Asynchronous, 8bit, low baud rate, TX enabled serial port
        movwf   TXSTA           ;
        BCF     STATUS, RP0             ; Switch to Bank0

        ; Note: 12uS (3 cycle) pause taken care of by UART init. (For Tacq)
        ; Note: Tad = 1MHz/2 = 2.0us -> 2* Tad = 2 * 2.0us = 4.0uS -> 4.0us/250uS/Tcycle = 1 cycle = NOP!
        BSF     ADCON0, GO              ; Start the A/D cycle
        movlw   B'10101010'     ; Turn on half of PORTB's LEDs
        movwf   PORTB           ;
; --------------------- Main Loop
loop    btfss   PIR1, TXIF
        goto    loop
        movf    PORTB,W                 ; Load w with the latest A/D conversion
        movwf   TXREG           ; Move w to TX register
        goto    loop
; --------------------- Interrupt Serivce Routine
int_svc btfss PIR1, ADIF        ; Check if this is an A/D interrupt
        retfie                          ; If not, return to whatever was happening
        bcf     PIR1, ADIF              ; reset the A/D interrupt flag
        movf    ADRES,w                 ; If so, move A/D results into w
        movwf   PORTB           ; Move the contents out to PORTB
        bsf     ADCON0, GO              ; Start up the A/D converter again
        retfie                          ; Return from interrupt

; ---------------------


For more information on all of this junk, feel free to contact us at!