Red October
     an ME218C Project

ME218C: Red October

Dept. of Mechanical Eng. | Stanford University



Meaningless graphic

Helm Code

E128

 

Module Breakdown:

 

 

Main.c

Main game code.

Called by nothing, includes no header

Module variables:        

 

Message_In[12]

destination_MSB

destination_LSB

header_in

navigation_in

special_in

keypress_throttle

keypress_direction

incoming_address_MSB

incoming_address_LSB

paired_Address_LSB

paired_Address_MSB

iButton_LSB

iButton_MSB

game_state

 

Module functions: (full psuedocode below)

 

Main_Init

InitializePeriodTimer

Message_Machine

Handle_Admiral

Handle_iButton

Handle_Craft

Import_Message_Machine

InitializeSecondTimer

 


iButton.c

iButton reading code.

Has header “iButton.h

Module variables:

 

(long) SerialNumber

Serialhighbyte

Seriallowbyte

 

Module functions:

 

ResetSequence                                     - sends the iButton a reset command

SendReadROMCommand                   - tells the iButton to start sending its SN

ReadNextBit                                          - reads a single bit out of the iButton

SetLineLO                                             - sets data line LO

SetLineHI                                              - sets data line HI

SetLineInput                                         - makes the shared data line an Input

ReadLine                                               - reads the value on the shared data line

Wait                                                       - waits, takes defined time constants as arguments

InitiButtonModule                               - initializes the iButton module (ports, etc)

ReadiButton                                          - reads the first 3 bytes in an iButton SN

GetiButtonMSB                                    - reports the MSB of the SN, excluding family byte

GetiButtonLSB                                     - reports the LSB of the SN, excluding family byte

PollForiButton                                      - checks whether an iButton is present, reports

 

                       

Xbee.c

Xbee sending and receiving code.

Has header “Xbee.h

Module variables:

 

XBee_Message_In[12]

New_Message_Flag

data_in

event

Send_Data

 

Module functions:

 

                SendingFSM         - a finite state machine that cycles through all 12 bytes of a send

ReceivingFSM      - receives the 12 bytes

XBee_Init              - initializes the XBee ports

Get_XBee_Byte   - stores a single byte coming in over SCI

Set_XBee_Address - sets the XBee output address

Set_XBee_Bytes  - sets the Xbee output bytes

Check_Message_Flag – checks if we have a new messages

Clear_Message_Flag – clears the new message flag

           

 

Helm_input.c

Controls all the inputs

Has header “helm_inputs.h

Module variables:

 

None

 

Module functions:

 

InitInputPorts       - initializes the ports used as inputs

Report_Special1   - reports whether the special 1 button is pressed

Report_Special2   - reports whether the special 2 button is pressed

Report_Voice        - reports an voltage from the microphone A/D pin

Report_Roll           - reports a voltage from the accelerometer x-axis A/D pin

Report_FSR          - reports a voltage from the FSR A/D pin

Report_Pitch         - reports a voltage from the accelerometer y-axis A/D pin

 

Set_Speed             - calculates the speed value bases on the throttle and direction (voice and roll)

Set_Direction        - calculates the direction based on the roll and pitch

Set_PumpSpeed   - calculates the pump speed based on the FSR value

Check_Reverse    - checks the Pitch to see if we should be reversing

 

 

Helm_display.c

Controls all helm display segments

Has header “helm_display.c

 

Module variables:

 

            none

 

Module function:

 

void InitDisplayPorts(void);

 

display_0                               - sets the appropriate pins to display a 0 on the seven segment display

- similarly titled functions exist 0-F to display all 16 values.

 

Set_Affiliation                      - displays which team we’re on                        

Set_Base                               - displays which base is active                                                         

Set_Standdown_LED          - controls the standown led, which shows us what the game state is

DisplayBoatNumber            - calls the display_? function based on the given team number


Psuedocode

 

 

Main.c

 

 

                Initialize the stand-down and animation timer                             

                Initialize the xbee module    

                Initialize the ports used for display

                Initialize input ports

clear the display

                set Xbee to an invalid address

                EnableInterrupts;

 

Repeat forever (this is the game loop) :

                                                               

    

If we’re WAITING_FOR_IBUTTON: 

 

Set the animation to Double Circle (2 segments chasing eachother around a circle)

 

                MessageMachine ß checks for XBee received messages, deals with them            

                Initialize the iButton module

 

                If we find an iButton:

                                Read that iButton’s serial number

                                Store the LSB and MSB of the SN as iButton_last_lsb and iButton_last_msb

                                Read the iButton again, store the serial number again

                               

                                If the newly read values, both low and high byte, are the same

                                And if they aren’t 0xFFFF and 0x00, then

                                                Store them as iButton_MSB and iButton_LSB

 

           

                If we’ve found an iButton

             our game state to SEND_IBUTTON_MESSAGE

           

 

if we’re in game state: SEND_IBUTTON_MESSAGE:

       

                 Message_Machine ß check messages again

       

           

                Set our Xbee output bytes to be the iButton SN that we’ve found

                ( we are already transmitting every 200ms)           

                Turn off animation

                Display the middle bar of our 7 segment display, so we know we’ve found an ibutton

Change our game state to LOOKING_FOR_WATERCRAFT;

           

       

If we’re in game state: LOOKING_FOR_WATERCRAFT:

 

            Message_Machine ß check messages again

           

       

If we’re in game state:  PAIRED:

       

                Change our Xbee output address to a junk address, so we don’t send trash accidentally

                Message_Machine ß check messages again

        

          

If we’re in game state:  PLAYING_GAME:

       

                Turn on our LEDs to show that we’re now playing the game

                Set our XBee address to the craft to which we’ve paired

                 Message_Machine ß check messages again

 

                Poll for the following inputs, and store them:

 

Special1

Special2

Throttle

Direction

Reverse?

Pump

 

assemble the Xbee output byte to send

            Set_XBee_Bytes(COMMAND, ((directionout*16)+speedout), (pumpspeedout + special1 + special2)); 

           

 

If we’re in game state:  STANDING_DOWN:

 

            Message_Machine ß check messages again

            Set our Xbee address to our paired watercraft

            Set the Xbee output bytes to NO_ACTION

       

 

If we’re in game state:  ENGAGEMENT_OVER:

           

Message_Machine ß check messages again

                As we did before, poll for inputs

                Assemble the Xbee output bytes, but include no pump/water delivery value

           

 

 

 

Main module initialization functions

 

 

Main_Init

 

 

                Turn on our first timer

                  

 

InitializePeriodTimer:

 

                Turn a timer on

                Enable the output compare interrupt on that timer line

                Set the first interrupt for 200 ms later   

 

InitializeSecondTimer:

 

                Same as InitializePeriodTimer, but on a different channel

 

 

Main module Interrupt service routines

 

interrupt _Vec_tim0ch4 Periodic_ISR

 

clear interrupt flag

                schedule next interrupt for 200 ms later

 

                until we get a “send complete” return from SendingFSM in the Xbee.c module

                                call SendingFSM                 

                                ( this sends one full message)                          

 

interrupt _Vec_tim2ch7 Periodic_ISR_2

{

                Clear interrupt flag

                Schedule the next interrupt for 200 ms later

 

                If we’re in STANDING_DOWN gamestate

                                Decrement the stand_down_counter

                                If stand_down_counter reaches 0

                                                Reset stand_down_counter to a FULL_STAND_DOWN

                                                                (the right number of interrupts per 10 s interval)

                                                Turn off the animation flag

                                                Display our paired boat number on the 7 segment display

                                                Change our game state to PLAYING_GAME       

 

 

                Check our animation flag

                                If that is set

                                                Use that value to pick which animation sequence to use

(in the code, a bunch of animation sequences follow. They take animate_counter, %ed with the number of steps the animation has, and then display the appropriate value on the seven segment display. They then increment the animate_counter.

                                               

 

Main module message handling functions

 

Message_Machine

 

     If the flag for a new message has been set:

                Clear that flag

                Run Import_Message_Machine, which stores the incoming bytes that we care about.

                Check the incoming message header

 

 

If the incoming message has the  ADMIRAL_HEADER:

                           Call Handle_Admiral to parse the message

               

If the incoming message has the  CRAFT_HEADER:  

                            Call Handle_Craft   

                               

If the incoming message has the  HELM_HEADER:

                            Print out an error message, and do nothing

                            

If the incoming message has the  IBUTTON_HELM_HEADER:

                            Print out an error message, and do nothing

 

 

Handle_Admiral:

 

 

                Check the sender’s address.

                If it matches the admiral’s address,

continue.

                                Otherwise, skip the rest.

                Check the last byte in

 

If the last byte in represents a START_GAME:

                 

                If we’re in the PAIRED game state:  

                                               

                                                Set our output address to the admiralty

                                                Set an acknowledgement into our output bytes

                                                Send the message

                                                Set our output address to an unused one

                                                Set the appropriate LEDs so we know we’re playing the game

                                                Change our game state to PLAYING_GAME

                       

                       

                   

If the last byte in represents a END_GAME:

 

Set our output address to the admiralty

                                Set an acknowledgement into our output bytes

                                Send the message

                                Set our output address to an unused one

                                Set the appropriate LEDs so we know we’re playing the game

                                Change our game state to ENGAGEMENT_OVER

                Turn on all LEDs, so we know the game is over

                   

If the last byte in represents a BLUE_GOAL active:

                                Turn on our blue base LED                                                                                                                                                               

                   

If the last byte in represents a RED_GOAL active:

                                Turn on our red base LED

                   

If the last byte in represents a HARD_RESET:

 

                                Erase our memory of the iButton we’ve read and the craft we’re paired to:

        paired_Address_LSB = 0;

                      paired_Address_MSB = 0;

                      iButton_LSB = 0;

                      iButton_MSB = 0;

                                set our game state back toWAITING_FOR_IBUTTON;

                                clear all LEDs

                turn off the second timer interrupt

                   

 

If the last byte in represents a  PING:

             

Check our game state, so we can respond (PONG) accordingly

                      

 If we’re in game state  WAITING_FOR_IBUTTON:

                                                Set our output address to the admiralty

                                                Set our output bytes to the “waiting for ibutton” response

                                                Send the message

                                                Set our output address to an unused one

                                                Set the appropriate LEDs so we know we’re playing the game

 

                           

                            If we’re in states SEND_IBUTTON_MESSAGE or LOOKING_FOR_WATERCRAFT

Set our output address to the admiralty

                                                Set our output bytes to the “have an ibutton, not paired” response

                                                Send the message

                                                Set our output address to an unused one

                                                Set the appropriate LEDs so we know we’re playing the game

 

                               If we’re in states PAIRED, PLAYING GAME, OR ENGAGEMENT_OVER

Set our output address to the admiralty

                                                Set our output bytes to the “paired” response

                                                Send the message

                                                Set our output address to an unused one

                                                Set the appropriate LEDs so we know we’re playing the game

 

 

 

Handle_Craft

 

                Check our game state

 

If we’re in game state  LOOKING_FOR_WATERCRAFT:

 

                If the last byte in represents a “matched” message from a craft:

                                Save the sending address of that craft as:

                                                                paired_Address_MSB

                                                                paired_Address_LSB

                                                display our paired boat number (the LSB)

                                show appropriate team affiliation (if even, BLUE, if odd, RED) with the LEDs

               

                                                change our game_state to  PAIRED                                         

       

       

                 If we’re in game state PLAYING_GAME:

 

Check to make sure it’s from our boat

                                If the address of the boat (MSB and LSB) is correct,

                                                Check the last byte in

                                               

                                                If that last byte represents a STAND_DOWN (0x02):

                                                                Acknowledge, by:

                                                                                Set our address to the paired boat

                                                                                Set our output bytes to a “stand down acknowledged”

                                                                                Send the byte

 

                                                                                Set our address to the admiralty

                                                                                Set our output bytes to a “command acknowledged”

                                                                                Send the byte

 

                                                                                Set our addres to an unused address

 

                                                                Set our game state to STANDING_DOWN

                                                                Set our animate flag to FLASH_PAIRED

                                                                                (flashes the paired boat number for the duration)

                                                                Reset the stand down counter to a FULL STAND DOWN

           

Import_Message_Machine

 

                Repeat 12 times:                                                                                                                                                                                  

                                Call Get_Xbee_Byte of the index (in the Xbee.c module)

                                 Store this value as Message_In at the current index

                                Increment the index           

      

 

                Store the 8th byte as the header_in

                Store the 9th byte as the message_in

                Store the 10th byte as the special_in

 

                Store the 4th and 5th bytes as the sender’s address