ardupilot/ArduCopter/leds.pde

416 lines
16 KiB
Plaintext
Raw Normal View History

/// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
static void update_lights()
{
2012-08-16 21:50:03 -03:00
switch(led_mode) {
case NORMAL_LEDS:
update_motor_light();
update_GPS_light();
break;
case SAVE_TRIM_LEDS:
2012-08-16 21:50:03 -03:00
dancing_light();
break;
}
}
static void update_GPS_light(void)
{
2012-08-16 21:50:03 -03:00
// GPS LED on if we have a fix or Blink GPS LED if we are receiving data
// ---------------------------------------------------------------------
switch (g_gps->status()) {
case GPS::NO_FIX:
case GPS::GPS_OK_FIX_2D:
// check if we've blinked since the last gps update
if (g_gps->valid_read) {
g_gps->valid_read = false;
ap_system.GPS_light = !ap_system.GPS_light; // Toggle light on and off to indicate gps messages being received, but no GPS fix lock
if (ap_system.GPS_light) {
digitalWrite(C_LED_PIN, LED_OFF);
}else{
digitalWrite(C_LED_PIN, LED_ON);
}
}
break;
2012-08-16 21:50:03 -03:00
case GPS::GPS_OK_FIX_3D:
if(ap.home_is_set) {
digitalWrite(C_LED_PIN, LED_ON); //Turn LED C on when gps has valid fix AND home is set.
} else {
digitalWrite(C_LED_PIN, LED_OFF);
}
break;
2012-08-16 21:50:03 -03:00
default:
digitalWrite(C_LED_PIN, LED_OFF);
break;
2012-08-16 21:50:03 -03:00
}
}
static void update_motor_light(void)
{
2012-08-16 21:50:03 -03:00
if(motors.armed() == false) {
ap_system.motor_light = !ap_system.motor_light;
2012-08-16 21:50:03 -03:00
// blink
if(ap_system.motor_light) {
digitalWrite(A_LED_PIN, LED_ON);
2012-08-16 21:50:03 -03:00
}else{
digitalWrite(A_LED_PIN, LED_OFF);
2012-08-16 21:50:03 -03:00
}
}else{
if(!ap_system.motor_light) {
ap_system.motor_light = true;
digitalWrite(A_LED_PIN, LED_ON);
2012-08-16 21:50:03 -03:00
}
}
}
static void dancing_light()
{
static uint8_t step;
2012-08-16 21:50:03 -03:00
if (step++ == 3)
step = 0;
switch(step)
{
case 0:
digitalWrite(C_LED_PIN, LED_OFF);
digitalWrite(A_LED_PIN, LED_ON);
2012-08-16 21:50:03 -03:00
break;
case 1:
digitalWrite(A_LED_PIN, LED_OFF);
digitalWrite(B_LED_PIN, LED_ON);
2012-08-16 21:50:03 -03:00
break;
case 2:
digitalWrite(B_LED_PIN, LED_OFF);
digitalWrite(C_LED_PIN, LED_ON);
2012-08-16 21:50:03 -03:00
break;
}
}
static void clear_leds()
{
digitalWrite(A_LED_PIN, LED_OFF);
digitalWrite(B_LED_PIN, LED_OFF);
digitalWrite(C_LED_PIN, LED_OFF);
ap_system.motor_light = false;
2012-08-16 21:50:03 -03:00
led_mode = NORMAL_LEDS;
}
/////////////////////////////////////////////////////////////////////////////////////////////
// Copter LEDS by Robert Lefebvre
// Based on the work of U4eake, Bill Sanford, Max Levine, and Oliver
// g.copter_leds_mode controls the copter leds function via bitmath
2012-08-16 21:50:03 -03:00
// Zeroeth bit turns motor leds on and off: 00000001
// First bit turns GPS function on and off: 00000010
// Second bit turns Aux function on and off: 00000100
// Third bit turns on Beeper (legacy Piezo) function: 00001000
// Fourth bit toggles between Fast Flash or Oscillate on Low Battery: 00010000 (0) does Fast Flash, (1) does Oscillate
// Fifth bit causes motor LEDs to Nav Blink: 00100000
// Sixth bit causes GPS LEDs to Nav Blink: 01000000
// This code is written in order to be backwards compatible with the old Motor_LEDS code
// I hope to include at least some of the Show_LEDS code in the future
// copter_leds_GPS_blink controls the blinking of the GPS LEDS
// copter_leds_motor_blink controls the blinking of the motor LEDS
// Piezo Code and beeps once on Startup to verify operation
// Piezo Enables Tone on reaching low battery or current alert
/////////////////////////////////////////////////////////////////////////////////////////////
#define COPTER_LEDS_BITMASK_ENABLED 0x01 // bit #0
#define COPTER_LEDS_BITMASK_GPS 0x02 // bit #1
#define COPTER_LEDS_BITMASK_AUX 0x04 // bit #2
#define COPTER_LEDS_BITMASK_BEEPER 0x08 // bit #3
#define COPTER_LEDS_BITMASK_BATT_OSCILLATE 0x10 // bit #4
#define COPTER_LEDS_BITMASK_MOTOR_NAV_BLINK 0x20 // bit #5
#define COPTER_LEDS_BITMASK_GPS_NAV_BLINK 0x40 // bit #6
#if COPTER_LEDS == ENABLED
static void copter_leds_init(void)
{
pinMode(COPTER_LED_1, OUTPUT); //Motor LED
pinMode(COPTER_LED_2, OUTPUT); //Motor LED
pinMode(COPTER_LED_3, OUTPUT); //Motor LED
pinMode(COPTER_LED_4, OUTPUT); //Motor LED
pinMode(COPTER_LED_5, OUTPUT); //Motor or Aux LED
pinMode(COPTER_LED_6, OUTPUT); //Motor or Aux LED
pinMode(COPTER_LED_7, OUTPUT); //Motor or GPS LED
pinMode(COPTER_LED_8, OUTPUT); //Motor or GPS LED
if (!(g.copter_leds_mode & COPTER_LEDS_BITMASK_BEEPER)) {
piezo_beep();
}
}
static void update_copter_leds(void)
{
2012-08-16 21:50:03 -03:00
if (g.copter_leds_mode == 0) {
2012-11-10 01:55:51 -04:00
copter_leds_reset(); //method of reintializing LED state
2012-08-16 21:50:03 -03:00
}
// motor leds control
if (g.copter_leds_mode & COPTER_LEDS_BITMASK_ENABLED) {
if (motors.armed()) {
if (ap.low_battery) {
if (g.copter_leds_mode & COPTER_LEDS_BITMASK_BATT_OSCILLATE) {
2012-11-10 01:55:51 -04:00
copter_leds_oscillate(); //if motors are armed, but battery level is low, motor leds fast blink
2012-08-16 21:50:03 -03:00
} else {
2012-11-10 01:55:51 -04:00
copter_leds_fast_blink(); //if motors are armed, but battery level is low, motor leds oscillate
2012-08-16 21:50:03 -03:00
}
} else {
if (g.copter_leds_mode & COPTER_LEDS_BITMASK_MOTOR_NAV_BLINK) {
if (copter_leds_nav_blink > 0) {
copter_leds_slow_blink(); //if nav command was seen, blink LEDs.
} else {
copter_leds_on();
}
2012-08-16 21:50:03 -03:00
} else {
copter_leds_on(); //if motors are armed, battery level OK, all motor leds ON
2012-08-16 21:50:03 -03:00
}
}
} else {
2012-11-10 01:55:51 -04:00
copter_leds_slow_blink(); //if motors are not armed, blink motor leds
2012-08-16 21:50:03 -03:00
}
}
// GPS led control
if (g.copter_leds_mode & COPTER_LEDS_BITMASK_GPS) {
2012-08-16 21:50:03 -03:00
// GPS LED on if we have a fix or Blink GPS LED if we are receiving data
// ---------------------------------------------------------------------
switch (g_gps->status()) {
case GPS::NO_GPS:
copter_leds_GPS_off(); //if no valid GPS signal, turn GPS LED off
break;
case GPS::NO_FIX:
copter_leds_GPS_slow_blink(); //if GPS has valid reads, but no fix, blink GPS LED slow
break;
case GPS::GPS_OK_FIX_2D:
case GPS::GPS_OK_FIX_3D:
2012-11-10 01:55:51 -04:00
if(ap.home_is_set) {
if (g.copter_leds_mode & COPTER_LEDS_BITMASK_GPS_NAV_BLINK) {
if (copter_leds_nav_blink >0) {
2012-11-10 01:55:51 -04:00
copter_leds_GPS_slow_blink(); //if nav command was seen, blink LEDs.
2012-08-16 21:50:03 -03:00
} else {
copter_leds_GPS_on();
}
} else {
copter_leds_GPS_on(); //Turn GPS LEDs on when gps has valid fix AND home is set
2012-08-16 21:50:03 -03:00
}
} else {
2012-11-10 01:55:51 -04:00
copter_leds_GPS_fast_blink(); //if GPS has fix, but home is not set, blink GPS LED fast
2012-08-16 21:50:03 -03:00
}
break;
}
}
// AUX led control
if (g.copter_leds_mode & COPTER_LEDS_BITMASK_AUX) {
if (ap_system.CH7_flag) {
2012-11-10 01:55:51 -04:00
copter_leds_aux_on(); //if sub-control of Ch7 is high, turn Aux LED on
} else {
2012-11-10 01:55:51 -04:00
copter_leds_aux_off(); //if sub-control of Ch7 is low, turn Aux LED off
2012-08-16 21:50:03 -03:00
}
}
}
static void copter_leds_reset(void) {
digitalWrite(COPTER_LED_1, COPTER_LED_OFF);
digitalWrite(COPTER_LED_2, COPTER_LED_OFF);
digitalWrite(COPTER_LED_3, COPTER_LED_OFF);
digitalWrite(COPTER_LED_4, COPTER_LED_OFF);
digitalWrite(COPTER_LED_5, COPTER_LED_OFF);
digitalWrite(COPTER_LED_6, COPTER_LED_OFF);
digitalWrite(COPTER_LED_7, COPTER_LED_OFF);
digitalWrite(COPTER_LED_8, COPTER_LED_OFF);
}
static void copter_leds_on(void) {
if (!(g.copter_leds_mode & COPTER_LEDS_BITMASK_AUX)) {
digitalWrite(COPTER_LED_1, COPTER_LED_ON);
2012-08-16 21:50:03 -03:00
}
#if CONFIG_HAL_BOARD == HAL_BOARD_APM2
if (!(g.copter_leds_mode & COPTER_LEDS_BITMASK_BEEPER)) {
digitalWrite(COPTER_LED_2, COPTER_LED_ON);
2012-08-16 21:50:03 -03:00
}
#else
digitalWrite(COPTER_LED_2, COPTER_LED_ON);
2012-08-16 21:50:03 -03:00
#endif
if (!(g.copter_leds_mode & COPTER_LEDS_BITMASK_GPS) ) {
digitalWrite(COPTER_LED_3, COPTER_LED_ON);
2012-08-16 21:50:03 -03:00
}
digitalWrite(COPTER_LED_4, COPTER_LED_ON);
digitalWrite(COPTER_LED_5, COPTER_LED_ON);
digitalWrite(COPTER_LED_6, COPTER_LED_ON);
digitalWrite(COPTER_LED_7, COPTER_LED_ON);
digitalWrite(COPTER_LED_8, COPTER_LED_ON);
}
static void copter_leds_off(void) {
if (!(g.copter_leds_mode & COPTER_LEDS_BITMASK_AUX)) {
digitalWrite(COPTER_LED_1, COPTER_LED_OFF);
2012-08-16 21:50:03 -03:00
}
#if CONFIG_HAL_BOARD == HAL_BOARD_APM2
if (!(g.copter_leds_mode & COPTER_LEDS_BITMASK_BEEPER)) {
digitalWrite(COPTER_LED_2, COPTER_LED_OFF);
2012-08-16 21:50:03 -03:00
}
#else
digitalWrite(COPTER_LED_2, COPTER_LED_OFF);
2012-08-16 21:50:03 -03:00
#endif
if (!(g.copter_leds_mode & COPTER_LEDS_BITMASK_GPS)) {
digitalWrite(COPTER_LED_3, COPTER_LED_OFF);
2012-08-16 21:50:03 -03:00
}
digitalWrite(COPTER_LED_4, COPTER_LED_OFF);
digitalWrite(COPTER_LED_5, COPTER_LED_OFF);
digitalWrite(COPTER_LED_6, COPTER_LED_OFF);
digitalWrite(COPTER_LED_7, COPTER_LED_OFF);
digitalWrite(COPTER_LED_8, COPTER_LED_OFF);
}
static void copter_leds_slow_blink(void) {
copter_leds_motor_blink++; // this increments once every 1/10 second because it is in the 10hz loop
if ( 0 < copter_leds_motor_blink && copter_leds_motor_blink < 6 ) { // when the counter reaches 5 (1/2 sec), then toggle the leds
2012-08-16 21:50:03 -03:00
copter_leds_off();
// if blinking is called by the Nav Blinker decrement the Nav Blink counter
if ((g.copter_leds_mode & COPTER_LEDS_BITMASK_MOTOR_NAV_BLINK) && !(g.copter_leds_mode & COPTER_LEDS_BITMASK_GPS_NAV_BLINK) && copter_leds_nav_blink >0 ) {
copter_leds_nav_blink--;
2012-08-16 21:50:03 -03:00
}
}else if (5 < copter_leds_motor_blink && copter_leds_motor_blink < 11) {
copter_leds_on();
}else{
copter_leds_motor_blink = 0; // start blink cycle again
2012-08-16 21:50:03 -03:00
}
}
static void copter_leds_fast_blink(void) {
copter_leds_motor_blink++; // this increments once every 1/10 second because it is in the 10hz loop
if ( 0 < copter_leds_motor_blink && copter_leds_motor_blink < 3 ) { // when the counter reaches 3 (1/5 sec), then toggle the leds
2012-08-16 21:50:03 -03:00
copter_leds_on();
}else if (2 < copter_leds_motor_blink && copter_leds_motor_blink < 5) {
copter_leds_off();
}else{
copter_leds_motor_blink = 0; // start blink cycle again
2012-08-16 21:50:03 -03:00
}
}
static void copter_leds_oscillate(void) {
copter_leds_motor_blink++; // this increments once every 1/10 second because it is in the 10hz loop
if ( 0 < copter_leds_motor_blink && copter_leds_motor_blink < 3 ) { // when the counter reaches 3 (1/5 sec), then toggle the leds
if ( !(g.copter_leds_mode & COPTER_LEDS_BITMASK_AUX)) {
digitalWrite(COPTER_LED_1, COPTER_LED_ON);
2012-08-16 21:50:03 -03:00
}
#if CONFIG_HAL_BOARD == HAL_BOARD_APM2
if ( !(g.copter_leds_mode & COPTER_LEDS_BITMASK_BEEPER)) {
digitalWrite(COPTER_LED_2, COPTER_LED_ON);
2012-08-16 21:50:03 -03:00
}
#else
digitalWrite(COPTER_LED_2, COPTER_LED_ON);
2012-08-16 21:50:03 -03:00
#endif
if ( !(g.copter_leds_mode & COPTER_LEDS_BITMASK_GPS)) {
digitalWrite(COPTER_LED_3, COPTER_LED_OFF);
2012-08-16 21:50:03 -03:00
}
digitalWrite(COPTER_LED_4, COPTER_LED_OFF);
digitalWrite(COPTER_LED_5, COPTER_LED_ON);
digitalWrite(COPTER_LED_6, COPTER_LED_ON);
digitalWrite(COPTER_LED_7, COPTER_LED_OFF);
digitalWrite(COPTER_LED_8, COPTER_LED_OFF);
2012-08-16 21:50:03 -03:00
}else if (2 < copter_leds_motor_blink && copter_leds_motor_blink < 5) {
if ( !(g.copter_leds_mode & COPTER_LEDS_BITMASK_AUX)) {
digitalWrite(COPTER_LED_1, COPTER_LED_OFF);
2012-08-16 21:50:03 -03:00
}
#if CONFIG_HAL_BOARD == HAL_BOARD_APM2
if ( !(g.copter_leds_mode & COPTER_LEDS_BITMASK_BEEPER)) {
digitalWrite(COPTER_LED_2, COPTER_LED_OFF);
2012-08-16 21:50:03 -03:00
}
#else
digitalWrite(COPTER_LED_2, COPTER_LED_OFF);
2012-08-16 21:50:03 -03:00
#endif
if ( !(g.copter_leds_mode & COPTER_LEDS_BITMASK_GPS) ) {
digitalWrite(COPTER_LED_3, COPTER_LED_ON);
2012-08-16 21:50:03 -03:00
}
digitalWrite(COPTER_LED_4, COPTER_LED_ON);
digitalWrite(COPTER_LED_5, COPTER_LED_OFF);
digitalWrite(COPTER_LED_6, COPTER_LED_OFF);
digitalWrite(COPTER_LED_7, COPTER_LED_ON);
digitalWrite(COPTER_LED_8, COPTER_LED_ON);
}else{
copter_leds_motor_blink = 0; // start blink cycle again
2012-08-16 21:50:03 -03:00
}
}
static void copter_leds_GPS_on(void) {
digitalWrite(COPTER_LED_3, COPTER_LED_ON);
}
static void copter_leds_GPS_off(void) {
digitalWrite(COPTER_LED_3, COPTER_LED_OFF);
}
static void copter_leds_GPS_slow_blink(void) {
2012-11-10 01:55:51 -04:00
copter_leds_GPS_blink++; // this increments once every 1/10 second because it is in the 10hz loop
if ( 0 < copter_leds_GPS_blink && copter_leds_GPS_blink < 6 ) { // when the counter reaches 5 (1/2 sec), then toggle the leds
2012-08-16 21:50:03 -03:00
copter_leds_GPS_off();
if ((g.copter_leds_mode & COPTER_LEDS_BITMASK_GPS_NAV_BLINK) && copter_leds_nav_blink >0 ) { // if blinking is called by the Nav Blinker...
2012-08-16 21:50:03 -03:00
copter_leds_nav_blink--; // decrement the Nav Blink counter
}
}else if (5 < copter_leds_GPS_blink && copter_leds_GPS_blink < 11) {
copter_leds_GPS_on();
}
2012-11-10 01:55:51 -04:00
else copter_leds_GPS_blink = 0; // start blink cycle again
}
static void copter_leds_GPS_fast_blink(void) {
2012-11-10 01:55:51 -04:00
copter_leds_GPS_blink++; // this increments once every 1/10 second because it is in the 10hz loop
if ( 0 < copter_leds_GPS_blink && copter_leds_GPS_blink < 3 ) { // when the counter reaches 3 (1/5 sec), then toggle the leds
2012-08-16 21:50:03 -03:00
copter_leds_GPS_off();
}else if (2 < copter_leds_GPS_blink && copter_leds_GPS_blink < 5) {
copter_leds_GPS_on();
}
2012-11-10 01:55:51 -04:00
else copter_leds_GPS_blink = 0; // start blink cycle again
}
2012-05-15 11:07:03 -03:00
static void copter_leds_aux_off(void){
digitalWrite(COPTER_LED_1, COPTER_LED_OFF);
}
2012-05-15 11:07:03 -03:00
static void copter_leds_aux_on(void){
digitalWrite(COPTER_LED_1, COPTER_LED_ON);
}
void piezo_on(){
if (g.copter_leds_mode & COPTER_LEDS_BITMASK_BEEPER) {
digitalWrite(PIEZO_PIN,HIGH);
}
}
void piezo_off(){
if (g.copter_leds_mode & COPTER_LEDS_BITMASK_BEEPER) {
digitalWrite(PIEZO_PIN,LOW);
}
}
2012-11-10 01:55:51 -04:00
void piezo_beep(){ // Note! This command should not be used in time sensitive loops
if (g.copter_leds_mode & COPTER_LEDS_BITMASK_BEEPER) {
piezo_on();
delay(100);
piezo_off();
}
}
void piezo_beep_twice(){ // Note! This command should not be used in time sensitive loops
if (g.copter_leds_mode & COPTER_LEDS_BITMASK_BEEPER) {
piezo_beep();
delay(50);
piezo_beep();
}
}
#endif //COPTER_LEDS