War:
Ceasefire:
How They Work:
The Dragon and Knight robots communicate through the simple language of violence. Upon booting up, there is a chance that one of the robots will lash out at the other, starting the “conversation”. Alternatively, they may simply glare at each other and an outside user can participate by instigating the violence.
Upon being hit, the robot will rock forward and trigger its roller switch so that it knows that it has been hit. Upon receiving a hit, the robot will wait a randomly determined amount of time before swing back at the other robot and continuing the conversation. After a certain randomly determined number of hits received, a robot will surrender by raising its white flag. Upon seeing the white flag, the other robot will stop attacking. Upon achieving victory, the dragon will let out a triumphant roar.
Solidworks Files:
Code:
#include <Servo.h>
#define PHOTO_PIN 0
#define NUM_PINS 1
#define NUM_SAMPLES 8
int16_t avg_samples [NUM_PINS][NUM_SAMPLES];
uint8_t ind [NUM_PINS];
int16_t avg_total [NUM_PINS];
int16_t avg [NUM_PINS];
void update_avg(uint8_t pin){
uint8_t i = ind[pin];
//Subtract old value
avg_total[pin] = avg_total[pin] - avg_samples[pin][i];
//Measure and add new value
avg_samples[pin][i] = analogRead(pin);
avg_total[pin] = avg_total[pin] + avg_samples[pin][i];
//Increment counter
ind[pin] = i + 1;
ind[pin] %= (uint8_t)NUM_SAMPLES;
avg[pin] = avg_total[pin] / NUM_SAMPLES;
}
void update_avgs(){
for(uint8_t i = 0; i < NUM_PINS; i++){
update_avg(i);
}
}
void init_avgs(){
//Zero out AVG array
for(uint8_t i = 0; i < NUM_PINS; i++){
for(uint8_t j = 0; j < NUM_SAMPLES; j++){
avg_samples[i][j] = 0;
}
ind[i] = 0;
avg_total[i] = 0;
avg[i] = 0;
}
}
#define HAMMER_PIN 9
#define FLAG_PIN 10
#define SWITCH_PIN 3
#define LED_PIN 2
//Angles for servos
#define FLAG_REST 40
#define FLAG_ACTV 180
#define HAMM_REST 0
#define HAMM_ACTV 90
#define LIGHT_THRESHOLD 650
Servo hammer_servo;
Servo flag_servo;
uint8_t loss_ct;
void setup() {
init_avgs();
hammer_servo.attach(HAMMER_PIN);
flag_servo.attach(FLAG_PIN);
hammer_servo.write(HAMM_REST);
flag_servo.write(FLAG_REST);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
pinMode(SWITCH_PIN, INPUT);
Serial.begin(9600);
randomSeed(analogRead(4));
loss_ct = random(5, 10);
}
#define WAIT 0
#define HIT1 1
#define HIT2 2
#define HIT3 3
#define DBNC 4
#define FLAG 5
#define VICT 6
uint8_t state = WAIT;
uint8_t delay_ct = 0;
uint8_t hit_ct = 0;
float mult = 1.06;
float base = 440;
uint8_t counter = 0;
void do_tone(){
counter++;
counter%=24;
tone(11, base*pow(mult, counter));
delay(50);
}
void loop() {
update_avgs();
switch(state){
//Wait for something to happen
case WAIT:
//If we get signaled that we won
if(avg[PHOTO_PIN] > LIGHT_THRESHOLD) state = VICT;
if(hit_ct > loss_ct) state = FLAG;
//If we get hit
if(digitalRead(SWITCH_PIN)){
hit_ct++;
state = HIT1; //Retaliate
delay_ct = 20 + random(20); //After random amount of time
}
break;
//Initial Wait
case HIT1:
if(delay_ct > 0) delay_ct--;
else state = HIT2;
break;
//Downswing
case HIT2:
hammer_servo.write(HAMM_ACTV);
delay_ct = 5;
state = HIT3;
break;
//Upswing
case HIT3:
if(delay_ct > 0){
delay_ct--;
}else{
hammer_servo.write(HAMM_REST);
delay_ct = 20;
state = DBNC;
}
break;
//Debouncing
case DBNC:
if(delay_ct > 0){
delay_ct--;
} else {
state = WAIT;
}
break;
//Raise flag
case FLAG:
flag_servo.write(FLAG_ACTV);
break;
//Victory Screech
case VICT:
do_tone();
break;
}
delay(50);
Serial.println(avg[0]);
}
Leave a Reply
You must be logged in to post a comment.