uint8_t address_exchange(void) { uint8_t ch; uint8_t id; set_led_rgb(0, 0, 255); id = eeprom_read_byte((uint8_t *)ee_pump_id_offset); if (id == 0 || id == 255) { // we failed to get a unique number for the pump. just stop. set_led_rgb(255, 0, 0); for(;;); } for(;;) { for(;;) { if (serial_rx_nb(&ch)) break; if (check_reset()) return 0xFF; } if (ch == 0xFF) break; if (ch == '?') serial_tx(id); } set_led_rgb(0, 255, 0); return id; }
//Power On Delay with LEDs void power_on(void) { set_led_rgb(1,0,0); CyDelay(250); set_led_rgb(0,1,0); CyDelay(250); set_led_rgb(0,0,1); CyDelay(250); set_led_rgb(0,0,0); CyDelay(250); }
void id_conflict(void) { // we failed to get an address. stop and wait for a reset set_led_rgb(255, 0, 0); for(; !check_reset();) ; }
void idle(void) { color_t c; uint8_t animate = 0; uint32_t t = 0; cli(); if (g_sync_count >= g_sync_divisor) { g_sync_count = 0; animate = 1; } sei(); if (animate) { cli(); t = g_pattern_t++; sei(); // do some animation! led_pattern_next(t, &c); set_led_rgb(c.red, c.green, c.blue); } flush_saved_tick_count(0); }
void loop() { int raw_temp = analogRead(TEMP_SENSOR); int magnify = digitalRead(TEMP_MAGNIFY_BTN); float deg_temp = 37.3 / 1024 * raw_temp; if (magnify == HIGH) { // magnifying mode button ON/OFF ref_deg_temp = deg_temp; // setting up the reference value set_led_rgb(ref_deg_temp); } else { ref_deg_temp = 0; // reset the temperature value set_led_rgb(0); } serial_log(); delay(250); }
void comm_test(void) { uint8_t ch; // disable all interrupts and just echo every character received. cli(); set_led_rgb(0, 255, 255); for(; !check_reset();) if (serial_rx_nb(&ch)) for(; !serial_tx_nb(ch) && !check_reset();) ; sei(); }
void check_software_revision(void) { uint8_t bit0 = PINC & (1<<PINC2) ? 1 : 0; uint8_t bit1 = PINC & (1<<PINC3) ? 1 : 0;; uint8_t bit2 = PINC & (1<<PINC4) ? 1 : 0;; if ((bit0 | bit1 << 1 | bit2 << 2) == SOFTWARE_VERSION) return; // Wrong software! I refuse to do shit! set_led_rgb(255, 255, 255); for(;;) ; }
void idle(void) { color_t c; uint8_t animate = 0, current_state = 0, button_state_changed = 0; uint32_t t = 0; cli(); if (g_sync_count >= g_sync_divisor) { g_sync_count = 0; animate = 1; } // read button state & check time if (g_button_time > 0 && g_time >= g_button_time) { current_state = g_button_state; g_button_time = 0; button_state_changed = 1; } sei(); // Set the leds and motor speed accordingly when button is pressed if (button_state_changed) { if (current_state) set_motor_speed(255, 1); else set_motor_speed(0, 1); } // run the animation if the current state if (animate) { cli(); t = g_pattern_t++; sei(); // do some animation! led_pattern_next(t, &c); set_led_rgb(c.red, c.green, c.blue); } flush_saved_tick_count(0); }
int main(void) { uint8_t id, rec, i, cs; color_t c; packet_t p; setup(); stop_motor(); sei(); for(i = 0; i < 5; i++) { set_led_rgb(255, 0, 255); _delay_ms(50); set_led_rgb(255, 255, 0); _delay_ms(50); } // get the current liquid level update_liquid_level(); for(;;) { cli(); g_reset = 0; g_current_sense_detected = 0; g_current_sense_num_cycles = 0; setup(); serial_init(); stop_motor(); set_led_rgb(0, 0, 255); sei(); id = address_exchange(); for(; !check_reset();) { rec = receive_packet(&p); if (rec == COMM_CRC_FAIL) continue; if (rec == COMM_RESET) break; if (rec == COMM_OK && (p.dest == DEST_BROADCAST || p.dest == id)) { // If we've detected a over current sitatuion, ignore all comamnds until reset cli(); cs = g_current_sense_detected; sei(); switch(p.type) { case PACKET_PING: break; case PACKET_SET_MOTOR_SPEED: if (!cs) set_motor_speed(p.p.uint8[0], p.p.uint8[1]); if (p.p.uint8[0] == 0) flush_saved_tick_count(0); break; case PACKET_TICK_DISPENSE: if (!cs) { dispense_ticks((uint16_t)p.p.uint32, 255); flush_saved_tick_count(0); } break; case PACKET_TIME_DISPENSE: if (!cs) { run_motor_timed(p.p.uint32); flush_saved_tick_count(0); } break; case PACKET_IS_DISPENSING: is_dispensing(); break; case PACKET_LIQUID_LEVEL: get_liquid_level(); break; case PACKET_UPDATE_LIQUID_LEVEL: update_liquid_level(); break; case PACKET_LED_OFF: set_led_pattern(LED_PATTERN_OFF); break; case PACKET_LED_IDLE: if (!cs) set_led_pattern(LED_PATTERN_IDLE); break; case PACKET_LED_DISPENSE: if (!cs) set_led_pattern(LED_PATTERN_DISPENSE); break; case PACKET_LED_DRINK_DONE: if (!cs) set_led_pattern(LED_PATTERN_DRINK_DONE); break; case PACKET_LED_CLEAN: if (!cs) set_led_pattern(LED_PATTERN_CLEAN); break; case PACKET_COMM_TEST: comm_test(); break; case PACKET_ID_CONFLICT: id_conflict(); break; case PACKET_SET_CS_THRESHOLD: g_current_sense_threshold = p.p.uint16[0]; break; case PACKET_SAVED_TICK_COUNT: get_saved_tick_count(); break; case PACKET_RESET_SAVED_TICK_COUNT: reset_saved_tick_count(); break; case PACKET_FLUSH_SAVED_TICK_COUNT: flush_saved_tick_count(1); break; case PACKET_GET_LIQUID_THRESHOLDS: get_liquid_thresholds(); break; case PACKET_SET_LIQUID_THRESHOLDS: set_liquid_thresholds(p.p.uint16[0], p.p.uint16[1]); break; case PACKET_TICK_SPEED_DISPENSE: if (!cs) { dispense_ticks(p.p.uint16[0], (uint8_t)p.p.uint16[1]); flush_saved_tick_count(0); } break; case PACKET_PATTERN_DEFINE: pattern_define(p.p.uint8[0]); break; case PACKET_PATTERN_ADD_SEGMENT: c.red = p.p.uint8[0]; c.green = p.p.uint8[1]; c.blue = p.p.uint8[2]; pattern_add_segment(&c, p.p.uint8[3]); break; case PACKET_PATTERN_FINISH: pattern_finish(); break; } } } } return 0; }
void text_interface(void) { char cmd[MAX_CMD_LEN]; uint8_t speed, current_sense; uint16_t ticks; uint16_t t; uint8_t i, cs; for(i = 0; i < 5; i++) { set_led_rgb(0, 0, 255); _delay_ms(150); set_led_rgb(0, 0, 0); _delay_ms(150); } set_led_pattern(LED_PATTERN_IDLE); for(;;) { cli(); g_reset = 0; g_current_sense_detected = 0; setup(); stop_motor(); serial_init(); cs = 0; sei(); _delay_ms(10); dprintf("\nParty Robotics Dispenser at your service!\n\n"); for(;;) { cli(); cs = g_current_sense_detected; sei(); if (!receive_cmd(cmd)) break; if (sscanf(cmd, "speed %hhu %hhu", &speed, ¤t_sense) == 2) { if (!cs) set_motor_speed(speed, current_sense); if (current_sense == 0) flush_saved_tick_count(0); continue; } if (sscanf(cmd, "tickdisp %hu %hhu", (short unsigned int *)&ticks, &speed) == 2) { if (!cs) { dispense_ticks(ticks, speed); flush_saved_tick_count(0); } continue; } if (sscanf(cmd, "timedisp %hu", (short unsigned int *)&t) == 1) { if (!cs) { run_motor_timed(t); flush_saved_tick_count(0); } continue; } if (strncmp(cmd, "forward", 7) == 0) { set_motor_direction(MOTOR_DIRECTION_FORWARD); continue; } if (strncmp(cmd, "backward", 8) == 0) { set_motor_direction(MOTOR_DIRECTION_BACKWARD); continue; } if (strncmp(cmd, "led_idle", 8) == 0) { set_led_pattern(LED_PATTERN_IDLE); continue; } if (strncmp(cmd, "led_dispense", 12) == 0) { set_led_pattern(LED_PATTERN_DISPENSE); continue; } if (strncmp(cmd, "led_done", 8) == 0) { set_led_pattern(LED_PATTERN_DRINK_DONE); continue; } if (strncmp(cmd, "led_clean", 8) == 0) { set_led_pattern(LED_PATTERN_CLEAN); continue; } if (strncmp(cmd, "help", 4) == 0) { dprintf("You can use these commands:\n"); dprintf(" speed <speed> <cs>\n"); dprintf(" tickdisp <ticks> <speed>\n"); dprintf(" timedisp <ms>\n"); dprintf(" forward\n"); dprintf(" backward\n"); dprintf(" reset\n"); dprintf(" led_idle\n"); dprintf(" led_dispense\n"); dprintf(" led_done\n"); dprintf(" led_clean\n\n"); dprintf("speed is from 0 - 255. cs = current sense and is 0 or 1.\n"); dprintf("ticks == number of quarter turns. ms == milliseconds\n"); continue; } if (strncmp(cmd, "reset", 5) == 0) break; dprintf("Unknown command. Use help to get, eh help. Duh.\n"); } } }
//Call this function every ms in main while() void rgb_led_ui(uint8_t err_l0, uint8_t err_l1, uint8_t err_l2, uint8_t new_comm) { static uint32_t cnt_comm = UI_COMM_TIMEOUT, cnt_err_l0 = 0, cnt_err_l1 = 0, cnt_flash = 0; static uint8_t latch_err_l2 = 0, flash_red = 0, comm_blue = 0; uint8_t r = 0, g = 0, b = 0; //Set variable for the flashing red light: if(cnt_flash < UI_RED_FLASH_ON) { flash_red = 1; } else { flash_red = 0; } cnt_flash++; if(cnt_flash >= UI_RED_FLASH_PERIOD) { cnt_flash = 0; } //New communication green/blue: if(new_comm) { //Received a new valid packet, resets the counter cnt_comm = UI_COMM_TIMEOUT; } if(cnt_comm > 0) cnt_comm--; if(!cnt_comm) { comm_blue = 1; } else { comm_blue = 0; } //From the highest priority to the lowest: //======================================= if((err_l2 == 1) || (latch_err_l2 == 1)) { //Major error => flashing red latch_err_l2 = 1; //Latching it, will require a reset to be normal again r = flash_red; g = 0; b = 0; } else { if(err_l1 == 1) { //Intermediate error => Steady Red r = 1; g = 0; b = 0; } else { if(err_l0 == 1) { //Software error => Steady Yellow r = 1; g = 1; b = 0; } else { if(comm_blue == 1) { //Communication timeout, blue r = 0; g = 0; b = 1; } else { //Normal, green r = 0; g = 1; b = 0; } } } } //Assign the color to the RGB LED: set_led_rgb(r, g, b); }