View Our Source Code: project.c and project_utils.c
The software for this project (project.c) is multiprocessed. One process takes user input from the knobs and button and controls the gun based on that input. The other process keeps track of the game, detecting when a square has been hit, lighting the appropriate LEDs, and checking victory conditions to determing end-of-game. A diagram showing the interaction between the two software processes and the two pieces of hardware may be found at the bottom of this page.
In order to better abstract the programming problem, we created a seperate source file (project_utils.c) to hold the basic functions for handling input and output.
The servo motors are controlled with this code. The functions servo_a5_init() and servo_a7_init(), as well as the global variables servo_a5_pulse and servo_a7_pulse are defined in precompiled files designed for controlling two servo motors.
#define HORIZ 0
#define VERT 1
#define MIN_MOTOR_POS 600
#define MAX_MOTOR_POS 4500
/* Initializes both Servo Motors */
void init_motors(){
servo_a5_pulse = 2000;
servo_a5_init(1);
servo_a7_pulse = 2000;
servo_a7_init(1);
}
/* Shuts Down both Servo Motors */
void shutdown_motors(){
servo_a5_init(0);
servo_a7_init(0);
}
/* Controls Servo Motor */
void motor_pos(int motor, int pos){
if(pos >= MIN_MOTOR_POS && pos <= MAX_MOTOR_POS){ if(motor="=" HORIZ && pos !="servo_a5_pulse)" servo_a5_pulse="pos;" else if(motor="=" VERT && pos !="servo_a7_pulse)" servo_a7_pulse="pos;" } else beep(); } /* Controls Servo Motor based on input in range 0 255 */ void motor_255(int motor, int analog_val){ motor_pos(motor, MIN_MOTOR_POS + (int)((float)(MAX_MOTOR_POS MIN_MOTOR_POS) * ((float)analog_val / 255.0))); } /* Controls Servo Motor based on input in range 0 180 */ void motor_ang(int motor, int angle){ if(angle>= 0 && angle <= 180){ motor_pos(motor, MIN_MOTOR_POS + (int)((float)(MAX_MOTOR_POS MIN_MOTOR_POS) * ((float)angle / 180.0))); } else beep(); }
Here is the code to control the LEDs. Calling the function will toggle the specified LED, and calling the second function will toggle all the LEDs. The calls to poke() first write the LED number to be toggled, then make the clock for the J/K flip-flops go high, then clear everything (making the clock go low again).
void toggle_led(int player, int led){
int led_num = led + (16 * player);
if(player >= 0 && led >= 1 && led <= 9){ poke(0x4000, led_num); poke(0x4000, 32 + led_num); poke(0x4000, 0); } else beep(); } void toggle_all_leds(){ int i, j; for(i="0;" i <="1;" i++) for(j="1;" j <="9;" j++) toggle_led(i, j); }
The remainder of the code is pretty straightforward, and you can go through it on your own by following the links at the top of the page.