int BlinkM::play_script(const char *script_name) { /* handle HTML colour encoding */ if (isxdigit(script_name[0]) && (strlen(script_name) == 6)) { char code[3]; uint8_t r, g, b; code[2] = '\0'; code[0] = script_name[1]; code[1] = script_name[2]; r = strtol(code, 0, 16); code[0] = script_name[3]; code[1] = script_name[4]; g = strtol(code, 0, 16); code[0] = script_name[5]; code[1] = script_name[6]; b = strtol(code, 0, 16); stop_script(); return set_rgb(r, g, b); } for (unsigned i = 0; script_names[i] != nullptr; i++) if (!strcasecmp(script_name, script_names[i])) return play_script(i); return -1; }
int BlinkM::setMode(int mode) { if(mode == 1) { if(systemstate_run == false) { stop_script(); set_rgb(0,0,0); systemstate_run = true; work_queue(LPWORK, &_work, (worker_t)&BlinkM::led_trampoline, this, 1); } } else { systemstate_run = false; } return OK; }
int BlinkM::init() { int ret; ret = I2C::init(); if (ret != OK) { warnx("I2C init failed"); return ret; } stop_script(); set_rgb(0,0,0); return OK; }
void BlinkM::led() { static int vehicle_status_sub_fd; static int vehicle_gps_position_sub_fd; static int num_of_cells = 0; static int detected_cells_runcount = 0; static int t_led_color[8] = { 0, 0, 0, 0, 0, 0, 0, 0}; static int t_led_blink = 0; static int led_thread_runcount=0; static int led_interval = 1000; static int no_data_vehicle_status = 0; static int no_data_vehicle_gps_position = 0; static bool topic_initialized = false; static bool detected_cells_blinked = false; static bool led_thread_ready = true; int num_of_used_sats = 0; if(!topic_initialized) { vehicle_status_sub_fd = orb_subscribe(ORB_ID(vehicle_status)); orb_set_interval(vehicle_status_sub_fd, 1000); vehicle_gps_position_sub_fd = orb_subscribe(ORB_ID(vehicle_gps_position)); orb_set_interval(vehicle_gps_position_sub_fd, 1000); topic_initialized = true; } if(led_thread_ready == true) { if(!detected_cells_blinked) { if(num_of_cells > 0) { t_led_color[0] = LED_PURPLE; } if(num_of_cells > 1) { t_led_color[1] = LED_PURPLE; } if(num_of_cells > 2) { t_led_color[2] = LED_PURPLE; } if(num_of_cells > 3) { t_led_color[3] = LED_PURPLE; } if(num_of_cells > 4) { t_led_color[4] = LED_PURPLE; } t_led_color[5] = LED_OFF; t_led_color[6] = LED_OFF; t_led_color[7] = LED_OFF; t_led_blink = LED_BLINK; } else { t_led_color[0] = led_color_1; t_led_color[1] = led_color_2; t_led_color[2] = led_color_3; t_led_color[3] = led_color_4; t_led_color[4] = led_color_5; t_led_color[5] = led_color_6; t_led_color[6] = led_color_7; t_led_color[7] = led_color_8; t_led_blink = led_blink; } led_thread_ready = false; } if (led_thread_runcount & 1) { if (t_led_blink) setLEDColor(LED_OFF); led_interval = LED_OFFTIME; } else { setLEDColor(t_led_color[(led_thread_runcount / 2) % 8]); //led_interval = (led_thread_runcount & 1) : LED_ONTIME; led_interval = LED_ONTIME; } if (led_thread_runcount == 15) { /* obtained data for the first file descriptor */ struct vehicle_status_s vehicle_status_raw; struct vehicle_gps_position_s vehicle_gps_position_raw; memset(&vehicle_status_raw, 0, sizeof(vehicle_status_raw)); memset(&vehicle_gps_position_raw, 0, sizeof(vehicle_gps_position_raw)); bool new_data_vehicle_status; bool new_data_vehicle_gps_position; orb_check(vehicle_status_sub_fd, &new_data_vehicle_status); if (new_data_vehicle_status) { orb_copy(ORB_ID(vehicle_status), vehicle_status_sub_fd, &vehicle_status_raw); no_data_vehicle_status = 0; } else { no_data_vehicle_status++; if(no_data_vehicle_status >= 3) no_data_vehicle_status = 3; } orb_check(vehicle_gps_position_sub_fd, &new_data_vehicle_gps_position); if (new_data_vehicle_gps_position) { orb_copy(ORB_ID(vehicle_gps_position), vehicle_gps_position_sub_fd, &vehicle_gps_position_raw); no_data_vehicle_gps_position = 0; } else { no_data_vehicle_gps_position++; if(no_data_vehicle_gps_position >= 3) no_data_vehicle_gps_position = 3; } /* get number of used satellites in navigation */ num_of_used_sats = 0; //for(int satloop=0; satloop<20; satloop++) { for(int satloop=0; satloop<sizeof(vehicle_gps_position_raw.satellite_used); satloop++) { if(vehicle_gps_position_raw.satellite_used[satloop] == 1) { num_of_used_sats++; } } if(new_data_vehicle_status || no_data_vehicle_status < 3){ if(num_of_cells == 0) { /* looking for lipo cells that are connected */ printf("<blinkm> checking cells\n"); for(num_of_cells = 2; num_of_cells < 7; num_of_cells++) { if(vehicle_status_raw.voltage_battery < num_of_cells * MAX_CELL_VOLTAGE) break; } printf("<blinkm> cells found:%u\n", num_of_cells); } else { if(vehicle_status_raw.battery_warning == VEHICLE_BATTERY_WARNING_WARNING) { /* LED Pattern for battery low warning */ led_color_1 = LED_YELLOW; led_color_2 = LED_YELLOW; led_color_3 = LED_YELLOW; led_color_4 = LED_YELLOW; led_color_5 = LED_YELLOW; led_color_6 = LED_YELLOW; led_color_7 = LED_YELLOW; led_color_8 = LED_YELLOW; led_blink = LED_BLINK; } else if(vehicle_status_raw.battery_warning == VEHICLE_BATTERY_WARNING_ALERT) { /* LED Pattern for battery critical alerting */ led_color_1 = LED_RED; led_color_2 = LED_RED; led_color_3 = LED_RED; led_color_4 = LED_RED; led_color_5 = LED_RED; led_color_6 = LED_RED; led_color_7 = LED_RED; led_color_8 = LED_RED; led_blink = LED_BLINK; } else { /* no battery warnings here */ if(vehicle_status_raw.flag_system_armed == false) { /* system not armed */ led_color_1 = LED_RED; led_color_2 = LED_RED; led_color_3 = LED_RED; led_color_4 = LED_RED; led_color_5 = LED_RED; led_color_6 = LED_RED; led_color_7 = LED_RED; led_color_8 = LED_RED; led_blink = LED_NOBLINK; } else { /* armed system - initial led pattern */ led_color_1 = LED_RED; led_color_2 = LED_RED; led_color_3 = LED_RED; led_color_4 = LED_OFF; led_color_5 = LED_OFF; led_color_6 = LED_OFF; led_color_7 = LED_OFF; led_color_8 = LED_OFF; led_blink = LED_BLINK; /* handle 4th led - flightmode indicator */ switch((int)vehicle_status_raw.flight_mode) { case VEHICLE_FLIGHT_MODE_MANUAL: led_color_4 = LED_AMBER; break; case VEHICLE_FLIGHT_MODE_STAB: led_color_4 = LED_YELLOW; break; case VEHICLE_FLIGHT_MODE_HOLD: led_color_4 = LED_BLUE; break; case VEHICLE_FLIGHT_MODE_AUTO: led_color_4 = LED_GREEN; break; } if(new_data_vehicle_gps_position || no_data_vehicle_gps_position < 3) { /* handling used sat´s */ if(num_of_used_sats >= 7) { led_color_1 = LED_OFF; led_color_2 = LED_OFF; led_color_3 = LED_OFF; } else if(num_of_used_sats == 6) { led_color_2 = LED_OFF; led_color_3 = LED_OFF; } else if(num_of_used_sats == 5) { led_color_3 = LED_OFF; } } else { /* no vehicle_gps_position data */ led_color_1 = LED_WHITE; led_color_2 = LED_WHITE; led_color_3 = LED_WHITE; } } } } } else { /* LED Pattern for general Error - no vehicle_status can retrieved */ led_color_1 = LED_WHITE; led_color_2 = LED_WHITE; led_color_3 = LED_WHITE; led_color_4 = LED_WHITE; led_color_5 = LED_WHITE; led_color_6 = LED_WHITE; led_color_7 = LED_WHITE; led_color_8 = LED_WHITE; led_blink = LED_BLINK; } /* printf( "<blinkm> Volt:%8.4f\tArmed:%4u\tMode:%4u\tCells:%4u\tNDVS:%4u\tNDSAT:%4u\tSats:%4u\tFix:%4u\tVisible:%4u\n", vehicle_status_raw.voltage_battery, vehicle_status_raw.flag_system_armed, vehicle_status_raw.flight_mode, num_of_cells, no_data_vehicle_status, no_data_vehicle_gps_position, num_of_used_sats, vehicle_gps_position_raw.fix_type, vehicle_gps_position_raw.satellites_visible); */ led_thread_runcount=0; led_thread_ready = true; led_interval = LED_OFFTIME; if(detected_cells_runcount < 4){ detected_cells_runcount++; } else { detected_cells_blinked = true; } } else { led_thread_runcount++; } if(systemstate_run == true) { /* re-queue ourselves to run again later */ work_queue(LPWORK, &_work, (worker_t)&BlinkM::led_trampoline, this, led_interval); } else { stop_script(); set_rgb(0,0,0); } }
void t9() { int s, oc, c, e; uint32_t p[10]; printf("Script store/run/status/stop/delete tests.\n"); gpio_write(GPIO, 0); /* need known state */ /* 100 loops per second p0 number of loops p1 GPIO */ char *script="\ lda p0\ sta v0\ tag 0\ w p1 1\ mils 5\ w p1 0\ mils 5\ dcr v0\ lda v0\ sta p9\ jp 0"; callback(GPIO, RISING_EDGE, t9cbf); s = store_script(script); oc = t9_count; p[0] = 99; p[1] = GPIO; run_script(s, 2, p); time_sleep(2); c = t9_count - oc; CHECK(9, 1, c, 100, 0, "store/run script"); oc = t9_count; p[0] = 200; p[1] = GPIO; run_script(s, 2, p); while (1) { e = script_status(s, p); if (e != PI_SCRIPT_RUNNING) break; time_sleep(0.5); } c = t9_count - oc; time_sleep(0.1); CHECK(9, 2, c, 201, 0, "run script/script status"); oc = t9_count; p[0] = 2000; p[1] = GPIO; run_script(s, 2, p); while (1) { e = script_status(s, p); if (e != PI_SCRIPT_RUNNING) break; if (p[9] < 1900) stop_script(s); time_sleep(0.1); } c = t9_count - oc; time_sleep(0.1); CHECK(9, 3, c, 110, 10, "run/stop script/script status"); e = delete_script(s); CHECK(9, 4, e, 0, 0, "delete script"); }
void BlinkM::led() { if (!topic_initialized) { vehicle_status_sub_fd = orb_subscribe(ORB_ID(vehicle_status)); orb_set_interval(vehicle_status_sub_fd, 250); vehicle_control_mode_sub_fd = orb_subscribe(ORB_ID(vehicle_control_mode)); orb_set_interval(vehicle_control_mode_sub_fd, 250); actuator_armed_sub_fd = orb_subscribe(ORB_ID(actuator_armed)); orb_set_interval(actuator_armed_sub_fd, 250); vehicle_gps_position_sub_fd = orb_subscribe(ORB_ID(vehicle_gps_position)); orb_set_interval(vehicle_gps_position_sub_fd, 250); /* Subscribe to safety topic */ safety_sub_fd = orb_subscribe(ORB_ID(safety)); orb_set_interval(safety_sub_fd, 250); topic_initialized = true; } if (led_thread_ready == true) { if (!detected_cells_blinked) { if (num_of_cells > 0) { t_led_color[0] = LED_PURPLE; } if (num_of_cells > 1) { t_led_color[1] = LED_PURPLE; } if (num_of_cells > 2) { t_led_color[2] = LED_PURPLE; } if (num_of_cells > 3) { t_led_color[3] = LED_PURPLE; } if (num_of_cells > 4) { t_led_color[4] = LED_PURPLE; } if (num_of_cells > 5) { t_led_color[5] = LED_PURPLE; } t_led_color[6] = LED_OFF; t_led_color[7] = LED_OFF; t_led_blink = LED_BLINK; } else { t_led_color[0] = led_color_1; t_led_color[1] = led_color_2; t_led_color[2] = led_color_3; t_led_color[3] = led_color_4; t_led_color[4] = led_color_5; t_led_color[5] = led_color_6; t_led_color[6] = led_color_7; t_led_color[7] = led_color_8; t_led_blink = led_blink; } led_thread_ready = false; } if (led_thread_runcount & 1) { if (t_led_blink) { setLEDColor(LED_OFF); } led_interval = LED_OFFTIME; } else { setLEDColor(t_led_color[(led_thread_runcount / 2) % 8]); //led_interval = (led_thread_runcount & 1) : LED_ONTIME; led_interval = LED_ONTIME; } if (led_thread_runcount == 15) { /* obtained data for the first file descriptor */ struct vehicle_status_s vehicle_status_raw; struct vehicle_control_mode_s vehicle_control_mode; struct actuator_armed_s actuator_armed; struct vehicle_gps_position_s vehicle_gps_position_raw; struct safety_s safety; memset(&vehicle_status_raw, 0, sizeof(vehicle_status_raw)); memset(&vehicle_gps_position_raw, 0, sizeof(vehicle_gps_position_raw)); memset(&safety, 0, sizeof(safety)); bool new_data_vehicle_status; bool new_data_vehicle_control_mode; bool new_data_actuator_armed; bool new_data_vehicle_gps_position; bool new_data_safety; orb_check(vehicle_status_sub_fd, &new_data_vehicle_status); int no_data_vehicle_status = 0; int no_data_vehicle_control_mode = 0; int no_data_actuator_armed = 0; int no_data_vehicle_gps_position = 0; if (new_data_vehicle_status) { orb_copy(ORB_ID(vehicle_status), vehicle_status_sub_fd, &vehicle_status_raw); no_data_vehicle_status = 0; } else { no_data_vehicle_status++; if (no_data_vehicle_status >= 3) { no_data_vehicle_status = 3; } } orb_check(vehicle_control_mode_sub_fd, &new_data_vehicle_control_mode); if (new_data_vehicle_control_mode) { orb_copy(ORB_ID(vehicle_control_mode), vehicle_control_mode_sub_fd, &vehicle_control_mode); no_data_vehicle_control_mode = 0; } else { no_data_vehicle_control_mode++; if (no_data_vehicle_control_mode >= 3) { no_data_vehicle_control_mode = 3; } } orb_check(actuator_armed_sub_fd, &new_data_actuator_armed); if (new_data_actuator_armed) { orb_copy(ORB_ID(actuator_armed), actuator_armed_sub_fd, &actuator_armed); no_data_actuator_armed = 0; } else { no_data_actuator_armed++; if (no_data_actuator_armed >= 3) { no_data_actuator_armed = 3; } } orb_check(vehicle_gps_position_sub_fd, &new_data_vehicle_gps_position); if (new_data_vehicle_gps_position) { orb_copy(ORB_ID(vehicle_gps_position), vehicle_gps_position_sub_fd, &vehicle_gps_position_raw); no_data_vehicle_gps_position = 0; } else { no_data_vehicle_gps_position++; if (no_data_vehicle_gps_position >= 3) { no_data_vehicle_gps_position = 3; } } /* update safety topic */ orb_check(safety_sub_fd, &new_data_safety); if (new_data_safety) { orb_copy(ORB_ID(safety), safety_sub_fd, &safety); } /* get number of used satellites in navigation */ num_of_used_sats = vehicle_gps_position_raw.satellites_used; if (new_data_vehicle_status || no_data_vehicle_status < 3) { if (num_of_cells == 0) { /* looking for lipo cells that are connected */ printf("<blinkm> checking cells\n"); for (num_of_cells = 2; num_of_cells < 7; num_of_cells++) { if (vehicle_status_raw.battery_voltage < num_of_cells * MAX_CELL_VOLTAGE) { break; } } printf("<blinkm> cells found:%d\n", num_of_cells); } else { if (vehicle_status_raw.battery_warning == vehicle_status_s::VEHICLE_BATTERY_WARNING_CRITICAL) { /* LED Pattern for battery critical alerting */ led_color_1 = LED_RED; led_color_2 = LED_RED; led_color_3 = LED_RED; led_color_4 = LED_RED; led_color_5 = LED_RED; led_color_6 = LED_RED; led_color_7 = LED_RED; led_color_8 = LED_RED; led_blink = LED_BLINK; } else if (vehicle_status_raw.rc_signal_lost) { /* LED Pattern for FAILSAFE */ led_color_1 = LED_BLUE; led_color_2 = LED_BLUE; led_color_3 = LED_BLUE; led_color_4 = LED_BLUE; led_color_5 = LED_BLUE; led_color_6 = LED_BLUE; led_color_7 = LED_BLUE; led_color_8 = LED_BLUE; led_blink = LED_BLINK; } else if (vehicle_status_raw.battery_warning == vehicle_status_s::VEHICLE_BATTERY_WARNING_LOW) { /* LED Pattern for battery low warning */ led_color_1 = LED_YELLOW; led_color_2 = LED_YELLOW; led_color_3 = LED_YELLOW; led_color_4 = LED_YELLOW; led_color_5 = LED_YELLOW; led_color_6 = LED_YELLOW; led_color_7 = LED_YELLOW; led_color_8 = LED_YELLOW; led_blink = LED_BLINK; } else { /* no battery warnings here */ if (actuator_armed.armed == false) { /* system not armed */ if (safety.safety_off) { led_color_1 = LED_ORANGE; led_color_2 = LED_ORANGE; led_color_3 = LED_ORANGE; led_color_4 = LED_ORANGE; led_color_5 = LED_ORANGE; led_color_6 = LED_ORANGE; led_color_7 = LED_ORANGE; led_color_8 = LED_ORANGE; led_blink = LED_BLINK; } else { led_color_1 = LED_CYAN; led_color_2 = LED_CYAN; led_color_3 = LED_CYAN; led_color_4 = LED_CYAN; led_color_5 = LED_CYAN; led_color_6 = LED_CYAN; led_color_7 = LED_CYAN; led_color_8 = LED_CYAN; led_blink = LED_NOBLINK; } } else { /* armed system - initial led pattern */ led_color_1 = LED_RED; led_color_2 = LED_RED; led_color_3 = LED_RED; led_color_4 = LED_OFF; led_color_5 = LED_OFF; led_color_6 = LED_OFF; led_color_7 = LED_OFF; led_color_8 = LED_OFF; led_blink = LED_BLINK; if (new_data_vehicle_control_mode || no_data_vehicle_control_mode < 3) { /* indicate main control state */ if (vehicle_status_raw.main_state == vehicle_status_s::MAIN_STATE_POSCTL) { led_color_4 = LED_GREEN; } /* TODO: add other Auto modes */ else if (vehicle_status_raw.main_state == vehicle_status_s::MAIN_STATE_AUTO_MISSION) { led_color_4 = LED_BLUE; } else if (vehicle_status_raw.main_state == vehicle_status_s::MAIN_STATE_ALTCTL) { led_color_4 = LED_YELLOW; } else if (vehicle_status_raw.main_state == vehicle_status_s::MAIN_STATE_MANUAL) { led_color_4 = LED_WHITE; } else { led_color_4 = LED_OFF; } led_color_5 = led_color_4; } if (new_data_vehicle_gps_position || no_data_vehicle_gps_position < 3) { /* handling used satus */ if (num_of_used_sats >= 7) { led_color_1 = LED_OFF; led_color_2 = LED_OFF; led_color_3 = LED_OFF; } else if (num_of_used_sats == 6) { led_color_2 = LED_OFF; led_color_3 = LED_OFF; } else if (num_of_used_sats == 5) { led_color_3 = LED_OFF; } } else { /* no vehicle_gps_position data */ led_color_1 = LED_WHITE; led_color_2 = LED_WHITE; led_color_3 = LED_WHITE; } } } } } else { /* LED Pattern for general Error - no vehicle_status can retrieved */ led_color_1 = LED_WHITE; led_color_2 = LED_WHITE; led_color_3 = LED_WHITE; led_color_4 = LED_WHITE; led_color_5 = LED_WHITE; led_color_6 = LED_WHITE; led_color_7 = LED_WHITE; led_color_8 = LED_WHITE; led_blink = LED_BLINK; } /* printf( "<blinkm> Volt:%8.4f\tArmed:%4u\tMode:%4u\tCells:%4u\tNDVS:%4u\tNDSAT:%4u\tSats:%4u\tFix:%4u\tVisible:%4u\n", vehicle_status_raw.voltage_battery, vehicle_status_raw.flag_system_armed, vehicle_status_raw.flight_mode, num_of_cells, no_data_vehicle_status, no_data_vehicle_gps_position, num_of_used_sats, vehicle_gps_position_raw.fix_type, vehicle_gps_position_raw.satellites_visible); */ led_thread_runcount = 0; led_thread_ready = true; led_interval = LED_OFFTIME; if (detected_cells_runcount < 4) { detected_cells_runcount++; } else { detected_cells_blinked = true; } } else { led_thread_runcount++; } if (systemstate_run == true) { /* re-queue ourselves to run again later */ work_queue(LPWORK, &_work, (worker_t)&BlinkM::led_trampoline, this, led_interval); } else { stop_script(); set_rgb(0, 0, 0); } }
void t9(int pi) { int s, oc, c, e, id; uint32_t p[10]; printf("Script store/run/status/stop/delete tests.\n"); gpio_write(pi, GPIO, 0); /* need known state */ /* 100 loops per second p0 number of loops p1 GPIO */ char *script="\ ld p9 p0\ tag 0\ w p1 1\ mils 5\ w p1 0\ mils 5\ dcr p9\ jp 0"; id = callback(pi, GPIO, RISING_EDGE, t9cbf); s = store_script(pi, script); /* Wait for script to finish initing. */ while (1) { time_sleep(0.1); e = script_status(pi, s, p); if (e != PI_SCRIPT_INITING) break; } oc = t9_count; p[0] = 99; p[1] = GPIO; run_script(pi, s, 2, p); time_sleep(2); c = t9_count - oc; CHECK(9, 1, c, 100, 0, "store/run script"); oc = t9_count; p[0] = 200; p[1] = GPIO; run_script(pi, s, 2, p); while (1) { time_sleep(0.1); e = script_status(pi, s, p); if (e != PI_SCRIPT_RUNNING) break; } c = t9_count - oc; time_sleep(0.1); CHECK(9, 2, c, 201, 0, "run script/script status"); oc = t9_count; p[0] = 2000; p[1] = GPIO; run_script(pi, s, 2, p); while (1) { time_sleep(0.1); e = script_status(pi, s, p); if (e != PI_SCRIPT_RUNNING) break; if (p[9] < 1600) stop_script(pi, s); } c = t9_count - oc; time_sleep(0.1); CHECK(9, 3, c, 410, 10, "run/stop script/script status"); e = delete_script(pi, s); CHECK(9, 4, e, 0, 0, "delete script"); callback_cancel(id); }