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
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
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