simplified state machine for aggressive powersaving in WX + GSM mode, inhibiting powersave state machine when GSM module may be busy on sending weather packet

master
Mateusz Lubecki 2023-10-31 13:33:32 +01:00
rodzic 502a1e0048
commit d22917b322
8 zmienionych plików z 93 dodań i 77 usunięć

Wyświetl plik

@ -97,7 +97,7 @@ telemetry_description_t aprsis_send_description_telemetry(uint8_t async,
void aprsis_igate_to_aprsis(AX25Msg *msg, const char * callsign_with_ssid);
void aprsis_send_server_conn_status(const char * callsign_with_ssid);
void aprsis_send_loginstring(const char * callsign_with_ssid, uint8_t rtc_ok);
void aprsis_send_loginstring(const char * callsign_with_ssid, uint8_t rtc_ok, uint16_t voltage);
void aprsis_send_gpsstatus(const char * callsign_with_ssid);
char * aprsis_get_tx_buffer(void);

Wyświetl plik

@ -19,12 +19,12 @@
/**
* This is the restore voltage a battery must be charged to for ParaMETEO to restore it's normal operation
*/
#define PWR_SAVE_STARTUP_RESTORE_VOLTAGE_DEF 1230u // 12.3V
#define PWR_SAVE_STARTUP_RESTORE_VOLTAGE_DEF 1200u // 12.0V
/**
* This is voltage above which controller will switch to PWSAVE_AGGRESV
*/
#define PWR_SAVE_AGGRESIVE_POWERSAVE_VOLTAGE 1150u // 11.5V
#define PWR_SAVE_AGGRESIVE_POWERSAVE_VOLTAGE 1130u // 11.3V
/**
* How long in minutes the controller will sleep in L7 state between checking

Wyświetl plik

@ -14,6 +14,7 @@ typedef struct packet_tx_counter_values_t {
uint8_t beacon_counter;
uint8_t wx_counter;
uint8_t gsm_wx_counter;
uint8_t telemetry_counter;
uint8_t telemetry_desc_counter;
uint8_t kiss_counter;
@ -28,6 +29,7 @@ void packet_tx_handler(const config_data_basic_t * const config_basic, const con
void packet_tx_get_current_counters(packet_tx_counter_values_t * out);
void packet_tx_set_current_counters(packet_tx_counter_values_t * in);
int16_t packet_tx_get_minutes_to_next_wx(void);
uint8_t packet_tx_is_gsm_meteo_pending(void);
void packet_tx_force_gsm_status(void);
#endif /* PACKET_TX_HANDLER_H_ */

Wyświetl plik

@ -79,7 +79,7 @@
*
*
* Transitions between states depends on configuration and value of config_data_powersave_mode_t.
* If 'powersave_keep_gsm_always_enabled' is set to one, the controller will swtich to modem M4a instead of M4
* If 'powersave_keep_gsm_always_enabled' is set to one, the controller will switch to modem M4a instead of M4
*
* ====================================================================================================================================|
* | Mode | Powersave Mode | |
@ -93,14 +93,19 @@
* | DIGI + WX + GSM | PWSAVE_NORMAL | C3 --- (1 minute before WX frame)---> C0 -> C3 ; if WX_INTERVAL < 5 minutes |
* | DIGI + WX + GSM | PWSAVE_AGGRESV | C2 --- (1 minute before WX frame)---> C0 -> C2 ; no matter WX_INTERVAL |
* | WX + GSM | PWSAVE_NONE | C0 |
* | WX + GSM | PWSAVE_NORMAL | M4 --- (1 minute before WX frame)---> C0 -> M4 |
* | WX + GSM (only) | PWSAVE_AGGRESV | L6 --- (2 minute before WX frame)---> C0 -> L6 ; if WX_INTERVAL < 5 minutes |
* | WX + GSM (only) | PWSAVE_AGGRESV | L7 --- (2 minute before WX frame)---> M4 --- (30 sec before)---> C0 -> L7 |
* | WX + GSM | PWSAVE_NORMAL | M4 --- (2 minute before WX frame)---> C0 -> M4 |
* | WX + GSM (only) | PWSAVE_AGGRESV | L7 --- (2 minute before WX frame)---> C0 -> L7 |
* | WX | PWSAVE_NONE | M4 --- (2 minute before WX frame)---> C1 -> M4 |
* | WX | PWSAVE_NORMAL | L7 --- (2 minute before WX frame)---> C1 -> L7 |
* | WX | PWSAVE_AGGRESV | L7 --- (1 minute before WX frame)---> M4 --- (30 sec before)---> C1 -> L7 |
* ====================================================================================================================================|
*
* Note from October 31st. State machine has been changed sligtly for
* PWSAVE_NORMAL and PWSAVE_AGGRESIVE for WX + GSM configuration. It was
* simplified by turning GSM module off completely when it is not needed.
* It has more sense and it is less risky, as it eliminate a possible situation
* when GSM module will change it internal state while controller is sleeping
* (like GPRS will die for some reason, or a SIM card will stop working)
*/

Wyświetl plik

@ -932,7 +932,7 @@ void aprsis_send_server_conn_status(const char * callsign_with_ssid) {
gsm_sim800_tcpip_async_write((uint8_t *)aprsis_packet_tx_buffer, aprsis_packet_tx_message_size, aprsis_serial_port, aprsis_gsm_modem_state);
}
void aprsis_send_loginstring(const char * callsign_with_ssid, uint8_t rtc_ok) {
void aprsis_send_loginstring(const char * callsign_with_ssid, uint8_t rtc_ok, uint16_t voltage) {
if (aprsis_logged == 0) {
return;
@ -945,10 +945,11 @@ void aprsis_send_loginstring(const char * callsign_with_ssid, uint8_t rtc_ok) {
aprsis_packet_tx_message_size = snprintf(
aprsis_packet_tx_buffer,
APRSIS_TX_BUFFER_LN - 1,
"%s>AKLPRZ,qAR,%s:>[rtc_ok: %d][aprsis]%s\r\n",
"%s>AKLPRZ,qAR,%s:>[rtc_ok: %d][vbat: %d][aprsis]%s\r\n",
callsign_with_ssid,
callsign_with_ssid,
rtc_ok,
voltage,
aprsis_login_string_reveived);
gsm_sim800_tcpip_async_write((uint8_t *)aprsis_packet_tx_buffer, aprsis_packet_tx_message_size, aprsis_serial_port, aprsis_gsm_modem_state);

Wyświetl plik

@ -1263,7 +1263,7 @@ int main(int argc, char* argv[]){
if (rte_main_trigger_gsm_loginstring_packet == 1 && gsm_sim800_tcpip_tx_busy() == 0) {
rte_main_trigger_gsm_loginstring_packet = 0;
aprsis_send_loginstring((const char *)&main_callsign_with_ssid, system_is_rtc_ok());
aprsis_send_loginstring((const char *)&main_callsign_with_ssid, system_is_rtc_ok(), rte_main_battery_voltage);
}
if (rte_main_trigger_gsm_telemetry_values == 1 && gsm_sim800_tcpip_tx_busy() == 0) {
@ -1638,7 +1638,7 @@ int main(int argc, char* argv[]){
}
// inhibit any power save switching when modem transmits data
if (!main_afsk.sending && rte_main_woken_up == 0) {
if (!main_afsk.sending && rte_main_woken_up == 0 && packet_tx_is_gsm_meteo_pending() == 0) {
pwr_save_pooling_handler(main_config_data_mode, main_config_data_basic, packet_tx_get_minutes_to_next_wx(), rte_main_average_battery_voltage, rte_main_battery_voltage);
}

Wyświetl plik

@ -64,6 +64,9 @@ uint8_t packet_tx_trigger_tcp = 0;
uint8_t packet_tx_meteo_gsm_interval = 2;
uint8_t packet_tx_meteo_gsm_counter = 0;
//!< Flag set to one after weather packet has been just send to APRS-IS via GPRS modem and the modem is probably transmitting now
uint8_t packet_tx_meteo_gsm_has_been_sent = 0;
#define API_TRIGGER_STATUS (1 << 1)
#define API_TRIGGER_METEO (1 << 2)
#define APRSIS_TRIGGER_METEO (1 << 3)
@ -131,32 +134,14 @@ inline void packet_tx_multi_per_call_handler(void) {
void packet_tx_tcp_handler(void) {
#ifdef STM32L471xx
// TODO: fixme currently there is no way to have APRS-IS and rest api
// client working at the same time
aprsis_return_t aprsis_result = APRSIS_UNKNOWN;
if ((packet_tx_trigger_tcp & APRSIS_TRIGGER_METEO) != 0) {
// TODO: fixme
if (gsm_sim800_tcpip_tx_busy() == 0) {
if (gsm_sim800_tcpip_tx_busy() == 0 && aprsis_connected == 1) {
if (aprsis_connected == 0) {
aprsis_result = aprsis_connect_and_login_default(0);
if (aprsis_result == APRSIS_OK) {
// send APRS-IS frame, if APRS-IS is not connected this function will return immediately
aprsis_send_wx_frame(
rte_wx_average_windspeed,
rte_wx_max_windspeed,
rte_wx_average_winddirection,
rte_wx_temperature_average_external_valid,
rte_wx_pressure_valid,
rte_wx_humidity_valid,
main_callsign_with_ssid,
main_string_latitude,
main_string_longitude,
main_config_data_basic);
}
}
else {
// send APRS-IS frame, if APRS-IS is not connected this function will return immediately
aprsis_send_wx_frame(
rte_wx_average_windspeed,
rte_wx_max_windspeed,
@ -168,11 +153,16 @@ void packet_tx_tcp_handler(void) {
main_string_latitude,
main_string_longitude,
main_config_data_basic);
// clear the flag requesting weather packet transmission
packet_tx_trigger_tcp ^= APRSIS_TRIGGER_METEO;
// set this flag to one to inhibit power saving state machine
// for a while (10 seconds) when GPRS modem is communicating
// with the GSM radio network and sending the data independently
// from the controller
packet_tx_meteo_gsm_has_been_sent = 1;
}
// TODO: fixme
// clear the bit
packet_tx_trigger_tcp ^= APRSIS_TRIGGER_METEO;
}
}
else if ((packet_tx_trigger_tcp & API_TRIGGER_STATUS) != 0) {
@ -222,6 +212,11 @@ void packet_tx_tcp_handler(void) {
packet_tx_trigger_tcp ^= RECONNECT_APRSIS;
// }
}
else {
// after 10 second from setting this flag the packet should be
// sent
packet_tx_meteo_gsm_has_been_sent = 0;
}
#endif
}
@ -337,7 +332,7 @@ void packet_tx_handler(const config_data_basic_t * const config_basic, const con
#endif
#ifdef PARAMETEO
if (packet_tx_meteo_gsm_counter >= packet_tx_meteo_gsm_interval) {
if (packet_tx_meteo_gsm_counter >= packet_tx_meteo_gsm_interval && gsm_sim800_gprs_ready == 1) {
if (main_config_data_gsm->aprsis_enable == 0 && main_config_data_gsm->api_enable == 1) {
// and trigger API wx packet transmission
packet_tx_trigger_tcp |= API_TRIGGER_METEO;
@ -612,6 +607,7 @@ void packet_tx_get_current_counters(packet_tx_counter_values_t * out) {
if (out != 0x00) {
out->beacon_counter = packet_tx_beacon_counter;
out->wx_counter = packet_tx_meteo_counter;
out->gsm_wx_counter = packet_tx_meteo_gsm_counter;
out->telemetry_counter = packet_tx_telemetry_counter;
out->telemetry_desc_counter = packet_tx_telemetry_descr_counter;
out->kiss_counter = packet_tx_meteo_kiss_counter;
@ -635,16 +631,26 @@ void packet_tx_set_current_counters(packet_tx_counter_values_t * in) {
if (in->kiss_counter != 0)
packet_tx_meteo_kiss_counter = in->kiss_counter;
if (in->gsm_wx_counter != 0)
packet_tx_meteo_gsm_counter = in->gsm_wx_counter;
}
else {
packet_tx_beacon_counter = 0;
packet_tx_meteo_counter = 2;
packet_tx_meteo_gsm_counter = 0;
packet_tx_telemetry_counter = 0;
packet_tx_telemetry_descr_counter = 10;
packet_tx_meteo_kiss_counter = 0;
}
}
/**
* Returns how many minutes is left to next weather packet (on radio network!!).
* Used in power saving state machine and to periodically reset VHF radio
* if this feature is enabled in configuration
* @return
*/
int16_t packet_tx_get_minutes_to_next_wx(void) {
if (packet_tx_meteo_interval != 0) {
return packet_tx_meteo_interval - packet_tx_meteo_counter;
@ -654,6 +660,30 @@ int16_t packet_tx_get_minutes_to_next_wx(void) {
}
}
/**
* This function checks if at the moment any weather packet is scheduled to be sent
* to APRS-IS server, or this packet has been just sent and GPRS module probably
* communicate with GSM network now. The result of this check is used to
* inhibit power saving state machine temporary, not to turn off or disable
* GSM modem while it is talking with GSM radio network.
* @return
*/
uint8_t packet_tx_is_gsm_meteo_pending(void) {
uint8_t out = 0;
#ifdef STM32L471xx
if (gsm_sim800_gprs_ready == 1 && (packet_tx_trigger_tcp & APRSIS_TRIGGER_METEO) != 0) {
out = 1;
}
if (packet_tx_meteo_gsm_has_been_sent != 0) {
out = 1;
}
#endif
return out;
}
void packet_tx_force_gsm_status(void) {
#ifdef STM32L471xx
packet_tx_gsm_status_sent = 0;

Wyświetl plik

@ -246,6 +246,7 @@ static void pwr_save_exit_after_last_stop2_cycle(void) {
// rewind all timers in packet tx handler as they were no updated when micro was sleeping
// sleep shall be always set as wx packet interval minus one minute
timers.wx_counter += (pwr_save_sleep_time_in_seconds / 60);
timers.gsm_wx_counter += (pwr_save_sleep_time_in_seconds / 60);
timers.beacon_counter += (pwr_save_sleep_time_in_seconds / 60);
timers.kiss_counter += (pwr_save_sleep_time_in_seconds / 60);
timers.telemetry_counter += (pwr_save_sleep_time_in_seconds / 60);
@ -350,6 +351,8 @@ int pwr_save_switch_mode_to_c1(void) {
// disconnect APRS-IS connection if it is established
aprsis_disconnect();
NVIC_DisableIRQ( USART3_IRQn );
// close and deconfigure port used for communication with GPRS module
srl_close(main_gsm_srl_ctx_ptr);
@ -397,6 +400,8 @@ void pwr_save_switch_mode_to_c2(void) {
// disconnect APRS-IS connection if it is established
aprsis_disconnect();
NVIC_DisableIRQ( USART3_IRQn );
// close and deconfigure port used for communication with GPRS module
srl_close(main_gsm_srl_ctx_ptr);
@ -478,6 +483,8 @@ int pwr_save_switch_mode_to_m4(void) {
// disconnect APRS-IS connection if it is established
aprsis_disconnect();
NVIC_DisableIRQ( USART3_IRQn );
// close and deconfigure port used for communication with GPRS module
srl_close(main_gsm_srl_ctx_ptr);
@ -560,6 +567,8 @@ void pwr_save_switch_mode_to_i5(void) {
// disconnect APRS-IS connection if it is established
aprsis_disconnect();
NVIC_DisableIRQ( USART3_IRQn );
// close and deconfigure port used for communication with GPRS module
srl_close(main_gsm_srl_ctx_ptr);
@ -1109,49 +1118,18 @@ config_data_powersave_mode_t pwr_save_pooling_handler( const config_data_mode_t
}
else { // WX + GSM (only)
if (timers->wx_transmit_period >= 5) {
// if stations is configured to send wx packet less frequent than every 5 minutes
if (minutes_to_wx > WAKEUP_PERIOD_BEFORE_WX_FRAME_IN_MINUTES) {
backup_reg_set_monitor(17);
if (minutes_to_wx > WAKEUP_PERIOD_BEFORE_WX_FRAME_IN_MINUTES) {
backup_reg_set_monitor(17);
// if there is more than WAKEUP_PERIOD_BEFORE_WX_FRAME_IN_MINUTES minutes to wx packet
pwr_save_switch_mode_to_l7((timers->wx_transmit_period * 60) - (WAKEUP_PERIOD_BEFORE_WX_FRAME_IN_MINUTES * 60)); // TODO: !!!
// if there is more than one minute to wx packet
pwr_save_switch_mode_to_l7((timers->wx_transmit_period * 60) - (WAKEUP_PERIOD_BEFORE_WX_FRAME_IN_MINUTES * 60)); // TODO: !!!
reinit_gprs = 1;
reinit_gprs = 1;
}
else {
if (pwr_save_seconds_to_wx <= 50) {
// if there is 30 seconds or less to next wx packet
reinit_sensors = pwr_save_switch_mode_to_c0();
}
else {
// if there is 30 to 60 seconds to next wx packet
if (config->powersave_keep_gsm_always_enabled == 0){
reinit_sensors = pwr_save_switch_mode_to_m4();
//reinit_gprs = 1;
}
else {
reinit_sensors = pwr_save_switch_mode_to_m4a();
}
}
}
}
else {
// if station is configured to sent wx packet in every 5 minutes or more often
if (minutes_to_wx > WAKEUP_PERIOD_BEFORE_WX_FRAME_IN_MINUTES) {
backup_reg_set_monitor(17);
pwr_save_switch_mode_to_l6((timers->wx_transmit_period * 60) - (WAKEUP_PERIOD_BEFORE_WX_FRAME_IN_MINUTES * 60)); // TODO: !!!
reinit_gprs = 0;
}
else {
reinit_sensors = pwr_save_switch_mode_to_c0();
}
// if there is 30 seconds or less to next wx packet
reinit_sensors = pwr_save_switch_mode_to_c0();
}
}
}
@ -1169,7 +1147,7 @@ config_data_powersave_mode_t pwr_save_pooling_handler( const config_data_mode_t
if (minutes_to_wx > WAKEUP_PERIOD_BEFORE_WX_FRAME_IN_MINUTES) {
backup_reg_set_monitor(17);
// if there is more than one minute to send wx packet
// if there is more than WAKEUP_PERIOD_BEFORE_WX_FRAME_IN_MINUTES minutes to send wx packet
pwr_save_switch_mode_to_l7((timers->wx_transmit_period * 60) - (WAKEUP_PERIOD_BEFORE_WX_FRAME_IN_MINUTES * 60));
reinit_gprs = 1;