Merge branch 'master' of github.com:ZeusWPI/OBUS
This commit is contained in:
commit
769f4ddd5d
7 changed files with 79 additions and 40 deletions
|
@ -68,4 +68,6 @@ Some things we had to consider:
|
|||
|
||||
## Development setup
|
||||
|
||||
In the Arduino IDE, select the correct board (Arduino Nano) and processor (ATmega328P (Old Bootloader)).
|
||||
|
||||
We use [this](https://github.com/autowp/arduino-mcp2515/) library for CAN communications. See [this](https://github.com/autowp/arduino-mcp2515/#software-usage) header for 3 simple steps on how to use it in the arduino IDE
|
||||
|
|
|
@ -124,6 +124,10 @@ bool receive(struct message *msg) {
|
|||
break;
|
||||
|
||||
case OBUS_PAYLDTYPE_COUNT:
|
||||
if (receive_frame.can_dlc < 2) {
|
||||
Serial.println(F("W Received illegal count msg: payload <2"));
|
||||
return false;
|
||||
}
|
||||
msg->count = receive_frame.data[1];
|
||||
break;
|
||||
|
||||
|
@ -156,7 +160,8 @@ void send(struct message *msg) {
|
|||
uint8_t length = 1;
|
||||
send_frame.data[0] = msg->msg_type;
|
||||
|
||||
switch (payload_type(msg->from.type, msg->msg_type)) {
|
||||
uint8_t pyld_type = payload_type(msg->from.type, msg->msg_type);
|
||||
switch (pyld_type) {
|
||||
case OBUS_PAYLDTYPE_EMPTY:
|
||||
break;
|
||||
|
||||
|
@ -176,7 +181,8 @@ void send(struct message *msg) {
|
|||
break;
|
||||
|
||||
default:
|
||||
Serial.println(F("Unknown payload type"));
|
||||
Serial.print(F("E Unknown payload type "));
|
||||
Serial.println(pyld_type);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ void _updateLed() {
|
|||
digitalWrite(GREEN_LED, false);
|
||||
}
|
||||
|
||||
blink_next_time = millis() + BLINK_DELAY_SLOW;
|
||||
blink_next_time = millis() + blink_delay;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ void setup(uint8_t type, uint8_t id) {
|
|||
obus_can::init();
|
||||
|
||||
strike_count = 0;
|
||||
active = false;
|
||||
active = true;
|
||||
|
||||
pinMode(RED_LED, OUTPUT);
|
||||
pinMode(GREEN_LED, OUTPUT);
|
||||
|
@ -142,7 +142,7 @@ void strike() {
|
|||
return;
|
||||
}
|
||||
strike_count++;
|
||||
_setLedBlink(COLOR_RED, BLINK_DELAY_FAST);
|
||||
digitalWrite(RED_LED, HIGH);
|
||||
time_stop_strike_led = millis() + 2000;
|
||||
obus_can::send_m_strike(this_module, strike_count);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
// yellow
|
||||
#define CLOCK_PIN 8
|
||||
#define CLOCK_PIN 6
|
||||
|
||||
// orange
|
||||
#define DATA_PIN 10
|
||||
#define DATA_PIN 7
|
||||
|
||||
// green
|
||||
#define READ_PIN 7
|
||||
#define READ_PIN 5
|
||||
|
||||
uint8_t shiftInFixed(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) {
|
||||
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
#define STATE_INACTIVE 0
|
||||
#define STATE_HELLO 1
|
||||
#define STATE_GAME 2
|
||||
#define STATE_GAMEOVER 3
|
||||
|
||||
#define OBUS_MAX_STRIKES 3 // Number of strikes allowed until game over
|
||||
#define OBUS_GAME_DURATION 10 // Duration of the game in seconds
|
||||
#define OBUS_GAME_DURATION 60 // Duration of the game in seconds
|
||||
|
||||
#define OBUS_MAX_MODULES 16
|
||||
#define OBUS_DISC_DURATION 5 // Duration of discovery round in seconds
|
||||
|
@ -27,13 +28,14 @@ uint8_t nr_connected_puzzles;
|
|||
uint8_t strikes;
|
||||
|
||||
// Bitvector for checking if game is solved or not
|
||||
// 32 bits per uint32 bitvector field
|
||||
#define N_UNSOLVED_PUZZLES DIVIDE_CEIL(MAX_AMOUNT_PUZZLES, 32)
|
||||
uint32_t unsolved_puzzles[N_UNSOLVED_PUZZLES];
|
||||
// 8 bits per uint8 bitvector field
|
||||
#define N_UNSOLVED_PUZZLES DIVIDE_CEIL(MAX_AMOUNT_PUZZLES, 8)
|
||||
uint8_t unsolved_puzzles[N_UNSOLVED_PUZZLES];
|
||||
|
||||
// Timers
|
||||
uint32_t hello_round_start;
|
||||
uint32_t game_start;
|
||||
uint32_t last_draw;
|
||||
uint32_t last_update;
|
||||
|
||||
struct obus_can::module this_module = {
|
||||
|
@ -51,7 +53,7 @@ TM1638plus tm(STROBE_TM, CLOCK_TM , DIO_TM, HI_FREQ);
|
|||
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
Serial.begin(19200);
|
||||
obus_can::init();
|
||||
|
||||
state = STATE_INACTIVE;
|
||||
|
@ -70,14 +72,14 @@ bool check_solved() {
|
|||
}
|
||||
|
||||
|
||||
void add_module_to_bit_vector(uint8_t module_id) {
|
||||
void add_puzzle_to_bit_vector(uint8_t module_id) {
|
||||
uint8_t byte_index = module_id >> 3;
|
||||
uint8_t bit_index = module_id & 0x07;
|
||||
unsolved_puzzles[byte_index] |= 0x1 << bit_index;
|
||||
}
|
||||
|
||||
|
||||
void solve_module_in_bit_vector(uint8_t module_id) {
|
||||
void solve_puzzle_in_bit_vector(uint8_t module_id) {
|
||||
uint8_t byte_index = module_id >> 3;
|
||||
uint8_t bit_index = module_id & 0x07;
|
||||
unsolved_puzzles[byte_index] &= ~(0x1 << bit_index);
|
||||
|
@ -104,8 +106,8 @@ void start_hello() {
|
|||
|
||||
uint16_t full_module_id(struct obus_can::module mod) {
|
||||
return \
|
||||
((uint16_t) mod.type << 8) | \
|
||||
(uint16_t) mod.id;
|
||||
(((uint16_t) mod.type) << 8) | \
|
||||
((uint16_t) mod.id);
|
||||
}
|
||||
|
||||
|
||||
|
@ -115,17 +117,23 @@ void receive_hello() {
|
|||
|
||||
if (obus_can::receive(&msg)) {
|
||||
if (msg.msg_type == OBUS_MSGTYPE_M_HELLO) {
|
||||
Serial.print(" Registered module ");
|
||||
Serial.println(full_module_id(msg.from));
|
||||
|
||||
if (nr_connected_modules < OBUS_MAX_MODULES) {
|
||||
Serial.print(F(" Registered module "));
|
||||
Serial.println(full_module_id(msg.from));
|
||||
|
||||
connected_modules_ids[nr_connected_modules] = msg.from;
|
||||
nr_connected_modules++;
|
||||
|
||||
if (msg.from.type == OBUS_TYPE_PUZZLE) {
|
||||
nr_connected_puzzles++;
|
||||
add_module_to_bit_vector(full_module_id(msg.from));
|
||||
add_puzzle_to_bit_vector(msg.from.id);
|
||||
}
|
||||
|
||||
char buffer[10];
|
||||
snprintf(buffer, 10, "%02d oF %02d", nr_connected_modules, OBUS_MAX_MODULES);
|
||||
tm.displayText(buffer);
|
||||
} else {
|
||||
Serial.println(F("W Max # modules reached"));
|
||||
}
|
||||
|
||||
obus_can::send_c_ack(this_module);
|
||||
|
@ -135,10 +143,12 @@ void receive_hello() {
|
|||
} else if (current_time - hello_round_start > OBUS_DISC_DURATION_MS) {
|
||||
if (nr_connected_puzzles == 0) {
|
||||
hello_round_start = current_time;
|
||||
Serial.println(" No puzzle modules found, restarting discovery round");
|
||||
obus_can::send_c_hello(this_module);
|
||||
Serial.println(F(" No puzzle modules, resend hello"));
|
||||
} else {
|
||||
Serial.println(F(" End of discovery round"));
|
||||
initialize_game();
|
||||
}
|
||||
Serial.println(" End of discovery round");
|
||||
initialize_game();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,11 +157,13 @@ void initialize_game() {
|
|||
strikes = 0;
|
||||
game_start = millis();
|
||||
|
||||
last_draw = 0;
|
||||
last_update = game_start;
|
||||
state = STATE_GAME;
|
||||
|
||||
Serial.println(" Game started");
|
||||
|
||||
draw_display(millis(), OBUS_GAME_DURATION_MS);
|
||||
obus_can::send_c_gamestart(this_module, OBUS_GAME_DURATION_MS, strikes, OBUS_MAX_STRIKES);
|
||||
}
|
||||
|
||||
|
@ -168,7 +180,7 @@ void receive_module_update() {
|
|||
break;
|
||||
|
||||
case OBUS_MSGTYPE_M_SOLVED:
|
||||
solve_module_in_bit_vector(full_module_id(msg.from));
|
||||
solve_puzzle_in_bit_vector(full_module_id(msg.from));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -181,6 +193,22 @@ void receive_module_update() {
|
|||
}
|
||||
|
||||
|
||||
void draw_display(uint32_t current_time, uint32_t time_left) {
|
||||
if (last_draw + 100 <= current_time) {
|
||||
// +25 to avoid rounding down when the loop runs early
|
||||
int totaldecisec = (time_left + 25) / 100;
|
||||
int decisec = totaldecisec % 10;
|
||||
int seconds = (totaldecisec / 10) % 60;
|
||||
int minutes = (totaldecisec / 10 / 60) % 60;
|
||||
int hours = totaldecisec / 10 / 60 / 60;
|
||||
char buffer[10];
|
||||
snprintf(buffer, 10, "%01dh%02d %02d.%01d", hours, minutes, seconds, decisec);
|
||||
tm.displayText(buffer);
|
||||
last_draw = current_time;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void game_loop() {
|
||||
uint32_t current_time = millis();
|
||||
uint32_t time_elapsed = current_time - game_start;
|
||||
|
@ -193,34 +221,36 @@ void game_loop() {
|
|||
if (check_solved()) {
|
||||
Serial.println(" Game solved");
|
||||
obus_can::send_c_solved(this_module, time_left, strikes, OBUS_MAX_STRIKES);
|
||||
state = STATE_INACTIVE;
|
||||
state = STATE_GAMEOVER;
|
||||
tm.displayText("dISArmEd");
|
||||
return;
|
||||
}
|
||||
if (time_left == 0) {
|
||||
Serial.println(" Time's up");
|
||||
obus_can::send_c_timeout(this_module, time_left, strikes, OBUS_MAX_STRIKES);
|
||||
state = STATE_INACTIVE;
|
||||
tm.displayText("boom");
|
||||
state = STATE_GAMEOVER;
|
||||
tm.displayText(" boo t");
|
||||
// m
|
||||
tm.display7Seg(4, 0b01010100);
|
||||
tm.display7Seg(5, 0b01000100);
|
||||
return;
|
||||
}
|
||||
if (strikes >= OBUS_MAX_STRIKES) {
|
||||
Serial.println(" Strikeout");
|
||||
obus_can::send_c_strikeout(this_module, time_left, strikes, OBUS_MAX_STRIKES);
|
||||
state = STATE_INACTIVE;
|
||||
tm.displayText("boom");
|
||||
state = STATE_GAMEOVER;
|
||||
tm.displayText(" boo S");
|
||||
// m
|
||||
tm.display7Seg(4, 0b01010100);
|
||||
tm.display7Seg(5, 0b01000100);
|
||||
return;
|
||||
}
|
||||
|
||||
draw_display(current_time, time_left);
|
||||
|
||||
if (last_update + OBUS_UPDATE_INTERVAL <= current_time) {
|
||||
obus_can::send_c_state(this_module, time_left, strikes, OBUS_MAX_STRIKES);
|
||||
last_update = current_time;
|
||||
|
||||
int totalsec = (current_time + 100) / 1000;
|
||||
int minutes = totalsec / 60;
|
||||
char buffer[10];
|
||||
snprintf(buffer, 10, "%06d.%02d", minutes, totalsec % 60);
|
||||
tm.displayText(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -238,5 +268,8 @@ void loop() {
|
|||
case STATE_GAME:
|
||||
game_loop();
|
||||
break;
|
||||
|
||||
case STATE_GAMEOVER:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,7 @@ ezButton green_button(6);
|
|||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
// WARNING: do not use 255 for your module
|
||||
obus_module::setup(OBUS_TYPE_PUZZLE, 255);
|
||||
obus_module::setup(OBUS_TYPE_PUZZLE, OBUS_PUZZLE_ID_DEVELOPMENT);
|
||||
red_button.setDebounceTime(100);
|
||||
green_button.setDebounceTime(100);
|
||||
}
|
||||
|
|
|
@ -10,8 +10,7 @@ ezButton green_button(6);
|
|||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
// WARNING: do not use 255 for your module
|
||||
obus_module::setup(OBUS_TYPE_NEEDY, 255);
|
||||
obus_module::setup(OBUS_TYPE_NEEDY, OBUS_NEEDY_ID_DEVELOPMENT);
|
||||
green_button.setDebounceTime(100);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue