diff --git a/src/audio.cpp b/src/audio.cpp index 278d55ff7..07dff3f11 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -89,9 +89,9 @@ void audioQueue::heartbeat() toneFreq += toneFreqIncr; } else { - SPEAKER_OFF; if (tonePause > 0) { + SPEAKER_OFF; tonePause--; } else if (t_queueRidx != t_queueWidx) { @@ -99,10 +99,14 @@ void audioQueue::heartbeat() toneTimeLeft = queueToneLength[t_queueRidx]; toneFreqIncr = queueToneFreqIncr[t_queueRidx]; tonePause = queueTonePause[t_queueRidx]; - + if((toneFreq==0) || (toneTimeLeft==0)){ + SPEAKER_OFF; + } if (!queueToneRepeat[t_queueRidx]--) { t_queueRidx = (t_queueRidx + 1) % AUDIO_QUEUE_LENGTH; } + } else { + SPEAKER_OFF; } } #endif @@ -151,6 +155,19 @@ void audioQueue::playASAP(uint8_t tFreq, uint8_t tLen, uint8_t tPause, } } +void audioQueue::playVario(uint8_t tFreq, uint8_t tLen) +{ + uint8_t next_queueWidx = (t_queueWidx + 1) % AUDIO_QUEUE_LENGTH; + if (next_queueWidx != t_queueRidx) { + queueToneFreq[t_queueWidx] = tFreq; + queueToneLength[t_queueWidx] = tLen; + queueTonePause[t_queueWidx] = 0; + queueToneRepeat[t_queueWidx] = 0; + queueToneFreqIncr[t_queueWidx] = 0; + t_queueWidx = next_queueWidx; + } +} + void audioQueue::event(uint8_t e, uint8_t f) { s_beeper = (g_eeGeneral.beeperMode>0 || (g_eeGeneral.beeperMode==0 && e>=AU_WARNING1) || (g_eeGeneral.beeperMode>=-1 && e<=AU_ERROR)); diff --git a/src/audio.h b/src/audio.h index 8ba66e320..d932d54d1 100644 --- a/src/audio.h +++ b/src/audio.h @@ -101,6 +101,8 @@ class audioQueue void playASAP(uint8_t tFreq, uint8_t tLen, uint8_t tPause, uint8_t tRepeat=0, int8_t tFreqIncr=0); + void playVario(uint8_t tFreq, uint8_t tLen); + inline bool busy() { return (toneTimeLeft > 0); } void event(uint8_t e, uint8_t f=BEEP_DEFAULT_FREQ); diff --git a/src/board_gruvin9x.cpp b/src/board_gruvin9x.cpp index 6baa3927a..b439da66a 100644 --- a/src/board_gruvin9x.cpp +++ b/src/board_gruvin9x.cpp @@ -128,8 +128,8 @@ uint8_t vpot_mod_state = 0; ISR(USART2_RX_vect) { - //receive data from extension board - //bit 9 = 1 mean encoder number, following byte with bit 9 = 0 is increment value + //receive data from extension board + //bit 9 = 1 mean encoder number, following byte with bit 9 = 0 is increment value /* Get status and 9th bit, then data */ /* from buffer */ //uint8_t status = UCSR2A; @@ -140,19 +140,19 @@ ISR(USART2_RX_vect) /* Filter the 9th bit, then return */ resh = (resh >> 1) & 0x01; - res = ((resh << 8) | resl); + res = ((resh << 8) | resl); if((res & 0x100) == 0x100){ - vpotToChange = res & 0xff; - vpot_mod_state = 1; + vpotToChange = res & 0xff; + vpot_mod_state = 1; }else{ - if(vpot_mod_state & (vpotToChange>0) & (vpotToChange<=NUM_EXTRA_ROTARY_ENCODERS)) - { + if(vpot_mod_state & (vpotToChange>0) & (vpotToChange<=NUM_EXTRA_ROTARY_ENCODERS)) + { int8_t vpot_inc = res & 0xff; - if(vpot_inc){ - incRotaryEncoder(NUM_ROTARY_ENCODERS-NUM_EXTRA_ROTARY_ENCODERS+vpotToChange-1, vpot_inc); - } - vpot_mod_state = 0; - } + if(vpot_inc){ + incRotaryEncoder(NUM_ROTARY_ENCODERS-NUM_EXTRA_ROTARY_ENCODERS+vpotToChange-1, vpot_inc); + } + vpot_mod_state = 0; + } } } #endif //EXTRA_ROTARY_ENCODERS diff --git a/src/frsky.cpp b/src/frsky.cpp index 1b3f29283..4fa4355ad 100644 --- a/src/frsky.cpp +++ b/src/frsky.cpp @@ -243,41 +243,60 @@ void parseTelemHubByte(uint8_t byte) break; case offsetof(FrskyHubData, baroAltitude_bp): - // First received barometer altitude => Altitude offset - if (!frskyHubData.baroAltitudeOffset) - frskyHubData.baroAltitudeOffset = -frskyHubData.baroAltitude_bp; - frskyHubData.baroAltitude_bp += frskyHubData.baroAltitudeOffset; - if (frskyHubData.baroAltitude_bp > frskyHubData.maxAltitude) - frskyHubData.maxAltitude = frskyHubData.baroAltitude_bp; - if (frskyHubData.baroAltitude_bp < frskyHubData.minAltitude) - frskyHubData.minAltitude = frskyHubData.baroAltitude_bp; - - { - int16_t actVario = frskyHubData.baroAltitude_bp - frskyHubData.lastBaroAltitude_bp; - frskyHubData.varioAcc2 = frskyHubData.varioAcc2 - frskyHubData.varioQueue[frskyHubData.queuePointer]; - frskyHubData.varioQueue[frskyHubData.queuePointer] = actVario; - uint8_t tmp = frskyHubData.queuePointer + 5; - if (tmp >= 10) - tmp -= 10; - tmp = (uint8_t)frskyHubData.varioQueue[tmp]; - frskyHubData.varioAcc2 = frskyHubData.varioAcc2 + (int8_t)tmp; - frskyHubData.varioAcc1 = frskyHubData.varioAcc1 + actVario - (int8_t)tmp; - frskyHubData.varioSpeed = frskyHubData.varioAcc1 - frskyHubData.varioAcc2; - if (++frskyHubData.queuePointer >= 10) + case offsetof(FrskyHubData, baroAltitude_ap): + if((!g_model.frsky.use_baroAltitude_ap & (offsetof(FrskyHubData, baroAltitude_bp) == (uint8_t)structPos)) | + (g_model.frsky.use_baroAltitude_ap & (offsetof(FrskyHubData, baroAltitude_ap) == (uint8_t)structPos))){ + //here is baro altitude suggested 0.01m accuracy, i.e. baroAltitude_ap in range [0:99] + if(g_model.frsky.use_baroAltitude_ap){ + uint16_t alt_sign = frskyHubData.baroAltitude_bp/abs(frskyHubData.baroAltitude_bp); + frskyHubData.baroAltitude_full = frskyHubData.baroAltitude_bp*100 + frskyHubData.baroAltitude_ap*alt_sign; + }else{ + frskyHubData.baroAltitude_full = frskyHubData.baroAltitude_bp; + } + if(++frskyHubData.queuePointer>=5) frskyHubData.queuePointer = 0; - frskyHubData.lastBaroAltitude_bp = frskyHubData.baroAltitude_bp; + + int8_t tmp = frskyHubData.queuePointer + 1; + if(tmp >= 5) + tmp = 0; + + frskyHubData.baroAltitudeQueue_full[frskyHubData.queuePointer] = + frskyHubData.baroAltitude_full; + + frskyHubData.varioSpeed = + frskyHubData.baroAltitudeQueue_full[frskyHubData.queuePointer] - + frskyHubData.baroAltitudeQueue_full[tmp]; + + // First received barometer altitude => Altitude offset + if (!frskyHubData.baroAltitudeOffset) + frskyHubData.baroAltitudeOffset = -frskyHubData.baroAltitude_full; + frskyHubData.baroAltitude_full += frskyHubData.baroAltitudeOffset; + if(g_model.frsky.use_baroAltitude_only){ + if (frskyHubData.baroAltitude_full > frskyHubData.maxAltitude_full) + frskyHubData.maxAltitude_full = frskyHubData.baroAltitude_full; + if (frskyHubData.baroAltitude_full < frskyHubData.minAltitude_full) + frskyHubData.minAltitude_full = frskyHubData.baroAltitude_full; + } + + } break; case offsetof(FrskyHubData, gpsAltitude_ap): + if(g_model.frsky.use_baroAltitude_ap){ + frskyHubData.gpsAltitude_full = frskyHubData.gpsAltitude_bp*100; + } else { + frskyHubData.gpsAltitude_full = frskyHubData.gpsAltitude_bp; + } if (!frskyHubData.gpsAltitudeOffset) - frskyHubData.gpsAltitudeOffset = -frskyHubData.gpsAltitude_bp; - frskyHubData.gpsAltitude_bp += frskyHubData.gpsAltitudeOffset; - if (frskyHubData.gpsAltitude_bp > frskyHubData.maxAltitude) - frskyHubData.maxAltitude = frskyHubData.gpsAltitude_bp; - if (frskyHubData.gpsAltitude_bp < frskyHubData.minAltitude) - frskyHubData.minAltitude = frskyHubData.gpsAltitude_bp; - + frskyHubData.gpsAltitudeOffset = -frskyHubData.gpsAltitude_full; + frskyHubData.gpsAltitude_full += frskyHubData.gpsAltitudeOffset; + if(!g_model.frsky.use_baroAltitude_only){ + if (frskyHubData.gpsAltitude_full > frskyHubData.maxAltitude_full) + frskyHubData.maxAltitude_full = frskyHubData.gpsAltitude_full; + if (frskyHubData.gpsAltitude_full < frskyHubData.minAltitude_full) + frskyHubData.minAltitude_full = frskyHubData.gpsAltitude_full; + } if (!frskyHubData.pilotLatitude && !frskyHubData.pilotLongitude) { // First received GPS position => Pilot GPS position getGpsPilotPosition(); @@ -625,30 +644,36 @@ void check_frsky() if (isFunctionActive(FUNC_VARIO)) { #if defined(AUDIO) - uint8_t warble = 0; -#endif - int8_t verticalSpeed = limit((int16_t)-100, (int16_t)(frskyHubData.varioSpeed/10), (int16_t)+100); - uint16_t interval; - if (verticalSpeed == 0) { - interval = 300; - } - else { - if (verticalSpeed < 0) { - verticalSpeed = -verticalSpeed; - warble = 1; +#define VARIO_SPEED_LIMIT 10 //m/s + int16_t verticalSpeed = 0; + //vertical speed in 0.01m/s now + if(g_model.frsky.use_baroAltitude_ap)//means if additional data enabled then _ap unit is 0.01 + verticalSpeed = limit((int16_t)-VARIO_SPEED_LIMIT*100, (int16_t)(frskyHubData.varioSpeed), (int16_t)+VARIO_SPEED_LIMIT*100); + else + verticalSpeed = limit((int16_t)-VARIO_SPEED_LIMIT, (int16_t)(frskyHubData.varioSpeed), (int16_t)+VARIO_SPEED_LIMIT)*100; + + uint8_t SoundAltBeepNextFreq = (0); + uint8_t SoundAltBeepNextTime = (0); + if(verticalSpeed < g_model.varioSpeedUpMin*VARIO_LIM_MUL && verticalSpeed > g_model.varioSpeedDownMin*(-VARIO_LIM_MUL)) //check thresholds here in cm/s + { + SoundAltBeepNextFreq = (0); + SoundAltBeepNextTime = (0); + }else{ + SoundAltBeepNextFreq = (((((int32_t)verticalSpeed * 84) + 125000)/10)/10)/20;//;150000)/10)/10)/20; + SoundAltBeepNextTime = ((1600 - verticalSpeed) / 100); + if(verticalSpeed > 0){ + if ((int16_t)(g_tmr10ms - s_varioTmr) > (int16_t)(SoundAltBeepNextTime*2)) { + s_varioTmr = g_tmr10ms; + audio.playVario(SoundAltBeepNextFreq, SoundAltBeepNextTime); + } + } else {//negative vertical speed gives sound without pauses + audio.playVario(SoundAltBeepNextFreq, 1); } - interval = (uint8_t)200 / verticalSpeed; - } - if (g_tmr10ms - s_varioTmr > interval) { - s_varioTmr = g_tmr10ms; - if (warble) - AUDIO_VARIO_DOWN(); - else - AUDIO_VARIO_UP(); - } + } } -#endif +#endif //AUDIO +#endif //FRSKY_HUB || WS_HOW_HIGH } bool FRSKY_alarmRaised(uint8_t idx) @@ -795,7 +820,9 @@ void resetTelemetry() frskyHubData.cellsCount = 6; frskyHubData.gpsAltitude_bp = 50; + frskyHubData.gpsAltitude_full = 5000; frskyHubData.baroAltitude_bp = 50; + frskyHubData.baroAltitude_full = 5000; frskyHubData.minAltitude = 10; frskyHubData.maxAltitude = 500; @@ -1074,7 +1101,25 @@ void menuProcFrsky(uint8_t event) putsTime(x, 1+FH+2*FH*i, value, att, att); } else { - putsTelemetryChannel(j ? 128 : 63, i==3 ? 1+7*FH : 1+2*FH+2*FH*i, field-1, value, att); + if(g_model.frsky.use_baroAltitude_ap & + ((field == TELEM_VSPD) | + (field == TELEM_ALT) | + (field == TELEM_MIN_ALT) | + (field == TELEM_MAX_ALT))){ + switch(field){ + case TELEM_VSPD: + putsTelemetryChannel(j ? 128 : 63, i==3 ? 1+7*FH : 1+2*FH+2*FH*i, field-1, value, att|PREC2); + break; + case TELEM_ALT: + case TELEM_MIN_ALT: + case TELEM_MAX_ALT: + putsTelemetryChannel(j ? 128 : 63, i==3 ? 1+7*FH : 1+2*FH+2*FH*i, field-1, value/100, att); + break; + } + } + else { + putsTelemetryChannel(j ? 128 : 63, i==3 ? 1+7*FH : 1+2*FH+2*FH*i, field-1, value, att); + } lcd_putsiAtt(j*65, 1+FH+2*FH*i, STR_VTELEMCHNS, field, 0); } } @@ -1116,14 +1161,14 @@ void menuProcFrsky(uint8_t event) } uint8_t width = (uint8_t)limit((int16_t)0, (int16_t)(((int32_t)100 * (value - barMin)) / (barMax - barMin)), (int16_t)100); - // reversed barshade for T1/T2 - uint8_t barShade; - if (source == TELEM_T1 || source == TELEM_T2) - barShade = ((threshold < value) ? DOTTED : SOLID); - else - barShade = ((threshold > value) ? DOTTED : SOLID); - lcd_filled_rect(26, bars_height+6+1+i*(bars_height+6), width, bars_height, barShade); - + // reversed barshade for T1/T2 + uint8_t barShade; + if (source == TELEM_T1 || source == TELEM_T2) + barShade = ((threshold < value) ? DOTTED : SOLID); + else + barShade = ((threshold > value) ? DOTTED : SOLID); + lcd_filled_rect(26, bars_height+6+1+i*(bars_height+6), width, bars_height, barShade); + for (uint8_t j=50; j<125; j+=25) if (j>26+thresholdX || j>26+width) lcd_vline(j, bars_height+6+1+i*(bars_height+6), bars_height); if (thresholdX) { diff --git a/src/frsky.h b/src/frsky.h index 9da0a0e8d..0a774c8e1 100644 --- a/src/frsky.h +++ b/src/frsky.h @@ -105,33 +105,33 @@ PACK(struct FrskyHubData { int16_t accelZ; // 0x26 1/256th gram (-8g ~ +8g) uint8_t gpsDistNeeded:1; // 1bits out of 16bits spare reused int8_t gpsFix:2; // 2bits out of 16bits spare reused: -1=never fixed, 0=not fixed now, 1=fixed - uint8_t spare1:1; // + uint8_t spare1:1; // uint8_t cellsCount:4; // 4bits out of 16bits spare reused uint8_t minCellVolts; // 8bits out of 16bits spare reused uint16_t current; // 0x28 Current - int8_t varioQueue[10]; // circular-buffer - uint8_t queuePointer; // circular-buffer pointer - int8_t spare2; - int16_t lastBaroAltitude_bp; + int32_t minAltitude_full; //4 bytes from varioQueue reused + int32_t maxAltitude_full; //4 bytes from varioQueue reused + int8_t spare2[2];//varioQueue[10]; // circular-buffer 2 + uint8_t queuePointer; // circular-buffer pointer 3 + int8_t spare3;// 4 + int16_t spare4;//lastBaroAltitude; 6 int16_t varioSpeed; /* next fields must keep this order! */ - int16_t minAltitude; - int16_t maxAltitude; + int32_t gpsAltitude_full;//4 bytes fro minAltitude and maxAltitude reused uint16_t maxRpm; int16_t maxTemperature1; int16_t maxTemperature2; uint16_t maxGpsSpeed; uint16_t maxGpsDistance; /* end */ - int16_t varioAcc1; - int16_t varioAcc2; + int32_t baroAltitude_full;// 4 bytes from varioAcc1 and varioAcc2 reused uint16_t volts_bp; // 0x3A uint16_t volts_ap; // 0x3B // end of FrSky Hub data uint16_t gpsDistance; int16_t gpsAltitudeOffset; uint8_t minCellMinVolts; - + int32_t baroAltitudeQueue_full[5];//20 }); #elif defined(WS_HOW_HIGH) diff --git a/src/model_menus.cpp b/src/model_menus.cpp index a2049f4af..0ff33c6a7 100644 --- a/src/model_menus.cpp +++ b/src/model_menus.cpp @@ -746,7 +746,6 @@ void menuProcPhasesAll(uint8_t event) att = i==sub ? INVERS : 0; PhaseData *p = phaseaddress(i); #if defined(EXTRA_ROTARY_ENCODERS) -// lcd_outdezNAtt(0, y, i, att|LEFT, 1); putsFlightPhase(0, y, i+1, att|CONDENSED); #else //EXTRA_ROTARY_ENCODERS putsFlightPhase(0, y, i+1, att); @@ -2004,8 +2003,8 @@ void menuProcFunctionSwitches(uint8_t event) #define TELEM_COL2 (9*FW+2) void menuProcTelemetry(uint8_t event) { -#if defined(FRSKY_HUB) || defined(WS_HOW_HIGH) - MENU(STR_MENUTELEMETRY, menuTabModel, e_Telemetry, 27, {0, (uint8_t)-1, 1, 0, 2, 2, (uint8_t)-1, 1, 0, 2, 2, (uint8_t)-1, 1, 1, (uint8_t)-1, 0, 0, (uint8_t)-1, 1, 1, 1, 1, (uint8_t)-1, 2, 2, 2, 2}); +#if defined(FRSKY_HUB) || defined(WS_HOW_HIGH)// v v v v 4 new menu items for baro alt/vario + MENU(STR_MENUTELEMETRY, menuTabModel, e_Telemetry, 32, {0, (uint8_t)-1, 1, 0, 2, 2, (uint8_t)-1, 1, 0, 2, 2, (uint8_t)-1, 1, 1, (uint8_t)-1, 0, 0, (uint8_t)-1, 0, 0, 0, 0, (uint8_t)-1, 1, 1, 1, 1, (uint8_t)-1, 2, 2, 2, 2}); #else MENU(STR_MENUTELEMETRY, menuTabModel, e_Telemetry, 24, {0, (uint8_t)-1, 1, 0, 2, 2, (uint8_t)-1, 1, 0, 2, 2, (uint8_t)-1, 1, 1, (uint8_t)-1, 1, 1, 1, 1, (uint8_t)-1, 2, 2, 2, 2}); #endif @@ -2153,6 +2152,48 @@ void menuProcTelemetry(uint8_t event) CHECK_INCDEC_MODELVAR(event, g_model.frsky.blades, 0, 2); } subN++; + + if(s_pgOfs0 ? g_eeGeneral.calibSpanPos[i] : g_eeGeneral.calibSpanNeg[i]))); - } + } #endif if(v < -RESX) v = -RESX; diff --git a/src/translations/en.h b/src/translations/en.h index 591aab312..645f150e8 100644 --- a/src/translations/en.h +++ b/src/translations/en.h @@ -236,6 +236,11 @@ #define TR_ALARM "Alarm" #define TR_USRDATA "UsrData" #define TR_BLADES "Blades" +#define TR_BARO_VARIO "Baro Vario" +#define TR_BARO_PR "Use AP" +#define TR_BARO_ONLY "BaroOnly" +#define TR_BARO_UP_LIM "Up Lim" +#define TR_BARO_DWN_LIM "Down Lim" #define TR_BARS "Bars" #define TR_DISPLAY "Display" #ifdef AUDIO diff --git a/src/translations/fr.h b/src/translations/fr.h index adc51bc8d..10bb63f54 100644 --- a/src/translations/fr.h +++ b/src/translations/fr.h @@ -236,6 +236,11 @@ #define TR_ALARM "Alarme" #define TR_USRDATA "UsrData" #define TR_BLADES "Blades" +#define TR_BARO_VARIO "Baro Vario" +#define TR_BARO_PR "Use AP" +#define TR_BARO_ONLY "BaroOnly" +#define TR_BARO_UP_LIM "Up Lim" +#define TR_BARO_DWN_LIM "Down Lim" #define TR_BARS "Gauges" #define TR_DISPLAY "Display" #ifdef AUDIO diff --git a/src/translations/se.h b/src/translations/se.h index f8890f8e8..417f08d15 100644 --- a/src/translations/se.h +++ b/src/translations/se.h @@ -236,6 +236,11 @@ #define TR_ALARM "Alarm" #define TR_USRDATA "Anv\201ndardata" #define TR_BLADES "Blad" +#define TR_BARO_VARIO "Baro Vario" +#define TR_BARO_PR "Use AP" +#define TR_BARO_ONLY "BaroOnly" +#define TR_BARO_UP_LIM "Up Lim" +#define TR_BARO_DWN_LIM "Down Lim" #define TR_BARS "Staplar som visas" #define TR_DISPLAY "Display" #ifdef AUDIO