[FL-2866, FL-2865] SubGhz: add frequency analyzer history (#1810)
* SubGhz: frequency analyzer history * SubGhz: add vibro * SubGhz: turn on the display when receiving a signal * SubGhz: add signal reception indicator * SubGhz: fix indicator * SubGhz: fix FA history Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		| @@ -71,6 +71,8 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { | |||||||
|         .frequency_coarse = 0, .rssi_coarse = 0, .frequency_fine = 0, .rssi_fine = 0}; |         .frequency_coarse = 0, .rssi_coarse = 0, .frequency_fine = 0, .rssi_fine = 0}; | ||||||
|     float rssi = 0; |     float rssi = 0; | ||||||
|     uint32_t frequency = 0; |     uint32_t frequency = 0; | ||||||
|  |     float rssi_temp = 0; | ||||||
|  |     uint32_t frequency_temp = 0; | ||||||
|     CC1101Status status; |     CC1101Status status; | ||||||
|  |  | ||||||
|     //Start CC1101 |     //Start CC1101 | ||||||
| @@ -194,6 +196,9 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { | |||||||
|                 TAG, "=:%u:%f", frequency_rssi.frequency_fine, (double)frequency_rssi.rssi_fine); |                 TAG, "=:%u:%f", frequency_rssi.frequency_fine, (double)frequency_rssi.rssi_fine); | ||||||
|  |  | ||||||
|             instance->sample_hold_counter = 20; |             instance->sample_hold_counter = 20; | ||||||
|  |             rssi_temp = frequency_rssi.rssi_fine; | ||||||
|  |             frequency_temp = frequency_rssi.frequency_fine; | ||||||
|  |  | ||||||
|             if(instance->filVal) { |             if(instance->filVal) { | ||||||
|                 frequency_rssi.frequency_fine = |                 frequency_rssi.frequency_fine = | ||||||
|                     subghz_frequency_analyzer_worker_expRunningAverageAdaptive( |                     subghz_frequency_analyzer_worker_expRunningAverageAdaptive( | ||||||
| @@ -202,7 +207,10 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { | |||||||
|             // Deliver callback |             // Deliver callback | ||||||
|             if(instance->pair_callback) { |             if(instance->pair_callback) { | ||||||
|                 instance->pair_callback( |                 instance->pair_callback( | ||||||
|                     instance->context, frequency_rssi.frequency_fine, frequency_rssi.rssi_fine); |                     instance->context, | ||||||
|  |                     frequency_rssi.frequency_fine, | ||||||
|  |                     frequency_rssi.rssi_fine, | ||||||
|  |                     true); | ||||||
|             } |             } | ||||||
|         } else if( // Deliver results coarse |         } else if( // Deliver results coarse | ||||||
|             (frequency_rssi.rssi_coarse > SUBGHZ_FREQUENCY_ANALYZER_THRESHOLD) && |             (frequency_rssi.rssi_coarse > SUBGHZ_FREQUENCY_ANALYZER_THRESHOLD) && | ||||||
| @@ -214,6 +222,8 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { | |||||||
|                 (double)frequency_rssi.rssi_coarse); |                 (double)frequency_rssi.rssi_coarse); | ||||||
|  |  | ||||||
|             instance->sample_hold_counter = 20; |             instance->sample_hold_counter = 20; | ||||||
|  |             rssi_temp = frequency_rssi.rssi_coarse; | ||||||
|  |             frequency_temp = frequency_rssi.frequency_coarse; | ||||||
|             if(instance->filVal) { |             if(instance->filVal) { | ||||||
|                 frequency_rssi.frequency_coarse = |                 frequency_rssi.frequency_coarse = | ||||||
|                     subghz_frequency_analyzer_worker_expRunningAverageAdaptive( |                     subghz_frequency_analyzer_worker_expRunningAverageAdaptive( | ||||||
| @@ -224,14 +234,22 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { | |||||||
|                 instance->pair_callback( |                 instance->pair_callback( | ||||||
|                     instance->context, |                     instance->context, | ||||||
|                     frequency_rssi.frequency_coarse, |                     frequency_rssi.frequency_coarse, | ||||||
|                     frequency_rssi.rssi_coarse); |                     frequency_rssi.rssi_coarse, | ||||||
|  |                     true); | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             if(instance->sample_hold_counter > 0) { |             if(instance->sample_hold_counter > 0) { | ||||||
|                 instance->sample_hold_counter--; |                 instance->sample_hold_counter--; | ||||||
|  |                 if(instance->sample_hold_counter == 18) { | ||||||
|  |                     if(instance->pair_callback) { | ||||||
|  |                         instance->pair_callback( | ||||||
|  |                             instance->context, frequency_temp, rssi_temp, false); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|             } else { |             } else { | ||||||
|                 instance->filVal = 0; |                 instance->filVal = 0; | ||||||
|                 if(instance->pair_callback) instance->pair_callback(instance->context, 0, 0); |                 if(instance->pair_callback) | ||||||
|  |                     instance->pair_callback(instance->context, 0, 0, false); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -5,8 +5,11 @@ | |||||||
|  |  | ||||||
| typedef struct SubGhzFrequencyAnalyzerWorker SubGhzFrequencyAnalyzerWorker; | typedef struct SubGhzFrequencyAnalyzerWorker SubGhzFrequencyAnalyzerWorker; | ||||||
|  |  | ||||||
| typedef void ( | typedef void (*SubGhzFrequencyAnalyzerWorkerPairCallback)( | ||||||
|     *SubGhzFrequencyAnalyzerWorkerPairCallback)(void* context, uint32_t frequency, float rssi); |     void* context, | ||||||
|  |     uint32_t frequency, | ||||||
|  |     float rssi, | ||||||
|  |     bool signal); | ||||||
|  |  | ||||||
| typedef struct { | typedef struct { | ||||||
|     uint32_t frequency_coarse; |     uint32_t frequency_coarse; | ||||||
|   | |||||||
| @@ -21,6 +21,8 @@ bool subghz_scene_frequency_analyzer_on_event(void* context, SceneManagerEvent e | |||||||
|     if(event.type == SceneManagerEventTypeCustom) { |     if(event.type == SceneManagerEventTypeCustom) { | ||||||
|         if(event.event == SubGhzCustomEventSceneAnalyzerLock) { |         if(event.event == SubGhzCustomEventSceneAnalyzerLock) { | ||||||
|             notification_message(subghz->notifications, &sequence_set_green_255); |             notification_message(subghz->notifications, &sequence_set_green_255); | ||||||
|  |             notification_message(subghz->notifications, &sequence_single_vibro); | ||||||
|  |             notification_message(subghz->notifications, &sequence_display_backlight_on); | ||||||
|             return true; |             return true; | ||||||
|         } else if(event.event == SubGhzCustomEventSceneAnalyzerUnlock) { |         } else if(event.event == SubGhzCustomEventSceneAnalyzerUnlock) { | ||||||
|             notification_message(subghz->notifications, &sequence_reset_rgb); |             notification_message(subghz->notifications, &sequence_reset_rgb); | ||||||
|   | |||||||
| @@ -25,6 +25,8 @@ struct SubGhzFrequencyAnalyzer { | |||||||
| typedef struct { | typedef struct { | ||||||
|     uint32_t frequency; |     uint32_t frequency; | ||||||
|     float rssi; |     float rssi; | ||||||
|  |     uint32_t history_frequency[3]; | ||||||
|  |     bool signal; | ||||||
| } SubGhzFrequencyAnalyzerModel; | } SubGhzFrequencyAnalyzerModel; | ||||||
|  |  | ||||||
| void subghz_frequency_analyzer_set_callback( | void subghz_frequency_analyzer_set_callback( | ||||||
| @@ -38,8 +40,8 @@ void subghz_frequency_analyzer_set_callback( | |||||||
| } | } | ||||||
|  |  | ||||||
| void subghz_frequency_analyzer_draw_rssi(Canvas* canvas, float rssi) { | void subghz_frequency_analyzer_draw_rssi(Canvas* canvas, float rssi) { | ||||||
|     uint8_t x = 48; |     uint8_t x = 20; | ||||||
|     uint8_t y = 56; |     uint8_t y = 64; | ||||||
|     uint8_t column_number = 0; |     uint8_t column_number = 0; | ||||||
|     if(rssi) { |     if(rssi) { | ||||||
|         rssi = (rssi + 90) / 3; |         rssi = (rssi + 90) / 3; | ||||||
| @@ -53,6 +55,31 @@ void subghz_frequency_analyzer_draw_rssi(Canvas* canvas, float rssi) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void subghz_frequency_analyzer_history_frequency_draw( | ||||||
|  |     Canvas* canvas, | ||||||
|  |     SubGhzFrequencyAnalyzerModel* model) { | ||||||
|  |     char buffer[64]; | ||||||
|  |     uint8_t x = 66; | ||||||
|  |     uint8_t y = 43; | ||||||
|  |  | ||||||
|  |     canvas_set_font(canvas, FontKeyboard); | ||||||
|  |     for(uint8_t i = 0; i < 3; i++) { | ||||||
|  |         if(model->history_frequency[i]) { | ||||||
|  |             snprintf( | ||||||
|  |                 buffer, | ||||||
|  |                 sizeof(buffer), | ||||||
|  |                 "%03ld.%03ld", | ||||||
|  |                 model->history_frequency[i] / 1000000 % 1000, | ||||||
|  |                 model->history_frequency[i] / 1000 % 1000); | ||||||
|  |             canvas_draw_str(canvas, x, y + i * 10, buffer); | ||||||
|  |         } else { | ||||||
|  |             canvas_draw_str(canvas, x, y + i * 10, "---.---"); | ||||||
|  |         } | ||||||
|  |         canvas_draw_str(canvas, x + 44, y + i * 10, "MHz"); | ||||||
|  |     } | ||||||
|  |     canvas_set_font(canvas, FontSecondary); | ||||||
|  | } | ||||||
|  |  | ||||||
| void subghz_frequency_analyzer_draw(Canvas* canvas, SubGhzFrequencyAnalyzerModel* model) { | void subghz_frequency_analyzer_draw(Canvas* canvas, SubGhzFrequencyAnalyzerModel* model) { | ||||||
|     char buffer[64]; |     char buffer[64]; | ||||||
|  |  | ||||||
| @@ -60,9 +87,11 @@ void subghz_frequency_analyzer_draw(Canvas* canvas, SubGhzFrequencyAnalyzerModel | |||||||
|     canvas_set_font(canvas, FontSecondary); |     canvas_set_font(canvas, FontSecondary); | ||||||
|     canvas_draw_str(canvas, 20, 8, "Frequency Analyzer"); |     canvas_draw_str(canvas, 20, 8, "Frequency Analyzer"); | ||||||
|  |  | ||||||
|     canvas_draw_str(canvas, 28, 60, "RSSI"); |     canvas_draw_str(canvas, 0, 64, "RSSI"); | ||||||
|     subghz_frequency_analyzer_draw_rssi(canvas, model->rssi); |     subghz_frequency_analyzer_draw_rssi(canvas, model->rssi); | ||||||
|  |  | ||||||
|  |     subghz_frequency_analyzer_history_frequency_draw(canvas, model); | ||||||
|  |  | ||||||
|     //Frequency |     //Frequency | ||||||
|     canvas_set_font(canvas, FontBigNumbers); |     canvas_set_font(canvas, FontBigNumbers); | ||||||
|     snprintf( |     snprintf( | ||||||
| @@ -71,8 +100,14 @@ void subghz_frequency_analyzer_draw(Canvas* canvas, SubGhzFrequencyAnalyzerModel | |||||||
|         "%03ld.%03ld", |         "%03ld.%03ld", | ||||||
|         model->frequency / 1000000 % 1000, |         model->frequency / 1000000 % 1000, | ||||||
|         model->frequency / 1000 % 1000); |         model->frequency / 1000 % 1000); | ||||||
|     canvas_draw_str(canvas, 8, 35, buffer); |     if(model->signal) { | ||||||
|     canvas_draw_icon(canvas, 96, 24, &I_MHz_25x11); |         canvas_draw_box(canvas, 4, 12, 121, 22); | ||||||
|  |         canvas_set_color(canvas, ColorWhite); | ||||||
|  |     } else { | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     canvas_draw_str(canvas, 8, 30, buffer); | ||||||
|  |     canvas_draw_icon(canvas, 96, 19, &I_MHz_25x11); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool subghz_frequency_analyzer_input(InputEvent* event, void* context) { | bool subghz_frequency_analyzer_input(InputEvent* event, void* context) { | ||||||
| @@ -85,12 +120,24 @@ bool subghz_frequency_analyzer_input(InputEvent* event, void* context) { | |||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| void subghz_frequency_analyzer_pair_callback(void* context, uint32_t frequency, float rssi) { | void subghz_frequency_analyzer_pair_callback( | ||||||
|  |     void* context, | ||||||
|  |     uint32_t frequency, | ||||||
|  |     float rssi, | ||||||
|  |     bool signal) { | ||||||
|     SubGhzFrequencyAnalyzer* instance = context; |     SubGhzFrequencyAnalyzer* instance = context; | ||||||
|     if((rssi == 0.f) && (instance->locked)) { |     if((rssi == 0.f) && (instance->locked)) { | ||||||
|         if(instance->callback) { |         if(instance->callback) { | ||||||
|             instance->callback(SubGhzCustomEventSceneAnalyzerUnlock, instance->context); |             instance->callback(SubGhzCustomEventSceneAnalyzerUnlock, instance->context); | ||||||
|         } |         } | ||||||
|  |         //update history | ||||||
|  |         with_view_model( | ||||||
|  |             instance->view, (SubGhzFrequencyAnalyzerModel * model) { | ||||||
|  |                 model->history_frequency[2] = model->history_frequency[1]; | ||||||
|  |                 model->history_frequency[1] = model->history_frequency[0]; | ||||||
|  |                 model->history_frequency[0] = model->frequency; | ||||||
|  |                 return false; | ||||||
|  |             }); | ||||||
|     } else if((rssi != 0.f) && (!instance->locked)) { |     } else if((rssi != 0.f) && (!instance->locked)) { | ||||||
|         if(instance->callback) { |         if(instance->callback) { | ||||||
|             instance->callback(SubGhzCustomEventSceneAnalyzerLock, instance->context); |             instance->callback(SubGhzCustomEventSceneAnalyzerLock, instance->context); | ||||||
| @@ -102,6 +149,7 @@ void subghz_frequency_analyzer_pair_callback(void* context, uint32_t frequency, | |||||||
|         instance->view, (SubGhzFrequencyAnalyzerModel * model) { |         instance->view, (SubGhzFrequencyAnalyzerModel * model) { | ||||||
|             model->rssi = rssi; |             model->rssi = rssi; | ||||||
|             model->frequency = frequency; |             model->frequency = frequency; | ||||||
|  |             model->signal = signal; | ||||||
|             return true; |             return true; | ||||||
|         }); |         }); | ||||||
| } | } | ||||||
| @@ -124,6 +172,9 @@ void subghz_frequency_analyzer_enter(void* context) { | |||||||
|         instance->view, (SubGhzFrequencyAnalyzerModel * model) { |         instance->view, (SubGhzFrequencyAnalyzerModel * model) { | ||||||
|             model->rssi = 0; |             model->rssi = 0; | ||||||
|             model->frequency = 0; |             model->frequency = 0; | ||||||
|  |             model->history_frequency[2] = 0; | ||||||
|  |             model->history_frequency[1] = 0; | ||||||
|  |             model->history_frequency[0] = 0; | ||||||
|             return true; |             return true; | ||||||
|         }); |         }); | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user