From b9e64f49136d5784dc13ac7fa055e712d2f5cf7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Thu, 20 Feb 2020 11:45:02 +0100 Subject: [PATCH] application: commit application powering GM1351, reading its measurements, and transmitting over Bluetooth --- application.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++-- lib/usb_cdcacm.c | 2 +- 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/application.c b/application.c index d99d274..7dc4490 100644 --- a/application.c +++ b/application.c @@ -12,7 +12,7 @@ * along with this program. If not, see . * */ -/** STM32F1 application example +/** STM32F1 application to read out measurements from GM1351 sound level meter and send the over Bluetooth * @file * @author King Kévin * @date 2016-2020 @@ -47,6 +47,8 @@ #include "usb_cdcacm.h" // USB CDC ACM utilities #include "terminal.h" // handle the terminal interface #include "menu.h" // menu utilities +#include "sensor_gm1351.h" // sound level meter interface +#include "spp_tx.h" // to communicate to the Bluetooth module /** watchdog period in ms */ #define WATCHDOG_PERIOD 10000 @@ -74,6 +76,20 @@ static time_t time_start = 0; volatile bool rtc_internal_tick_flag = false; /**< flag set when internal RTC ticked */ /** @} */ +/** if we show the received value */ +static bool gm1351_show = false; + +/** show/hide received sound level + * @param[in] argument not used + */ +static void command_show(void* argument) +{ + (void)argument; // we won't use the argument + gm1351_show = !gm1351_show; // toggle setting + puts(gm1351_show ? "show" : "hide"); + puts(" decoded sound level\n"); +} + size_t putc(char c) { size_t length = 0; // number of characters printed @@ -128,6 +144,13 @@ static void command_reset(void* argument); */ static void command_bootloader(void* argument); +/** switch/toggle power of GM1351 sound level meter */ +static void command_power(void* argument) +{ + (void)argument; // we won't use the argument + sensor_gm1351_power_toggle(); // toggle power of meter +} + /** list of all supported commands */ static const struct menu_command_t menu_commands[] = { { @@ -180,6 +203,23 @@ static const struct menu_command_t menu_commands[] = { .argument_description = NULL, .command_handler = &command_bootloader, }, + // custom actions + { + .shortcut = 'p', + .name = "power", + .command_description = "switch power of GM1351 sound level meter", + .argument = MENU_ARGUMENT_NONE, + .argument_description = NULL, + .command_handler = &command_power, + }, + { + .shortcut = 's', + .name = "show", + .command_description = "show/hide decoded sound level", + .argument = MENU_ARGUMENT_NONE, + .argument_description = NULL, + .command_handler = &command_show, + }, }; static void command_help(void* argument) @@ -341,7 +381,7 @@ void main(void) uart_setup(); // setup USART (for printing) #endif usb_cdcacm_setup(); // setup USB CDC ACM (for printing) - puts("\nwelcome to the CuVoodoo STM32F1 example application\n"); // print welcome message + puts("\nwelcome to the CuVoodoo GM1351 sound level meter reader\n"); // print welcome message #if DEBUG // show reset cause @@ -394,6 +434,14 @@ void main(void) time_start = rtc_get_counter_val(); // get start time from internal RTC puts("OK\n"); + puts("setup UART to Bluetooth SPP module: "); + spp_tx_setup(); + puts("OK\n"); + + puts("setup GM1351 sound level meter: "); + sensor_gm1351_setup(); + puts("OK\n"); + // setup terminal terminal_prefix = ""; // set default prefix terminal_process = &process_command; // set central function to process commands @@ -402,6 +450,7 @@ void main(void) // start main loop bool action = false; // if an action has been performed don't go to sleep button_flag = false; // reset button flag + uint32_t gm1351_last = rtc_get_counter_val(); // last time a measurement has been received while (true) { // infinite loop iwdg_reset(); // kick the dog if (user_input_available) { // user input is available @@ -420,8 +469,28 @@ void main(void) if (rtc_internal_tick_flag) { // the internal RTC ticked rtc_internal_tick_flag = false; // reset flag action = true; // action has been performed - if (0 == (rtc_get_counter_val() % RTC_TICKS_SECOND)) { // one seond has passed + if (0 == (rtc_get_counter_val() % RTC_TICKS_SECOND)) { // one second has passed led_toggle(); // toggle LED (good to indicate if main function is stuck) + if ((rtc_get_counter_val() - gm1351_last) / RTC_TICKS_SECOND >= 3) { // no measurement has been received for some time + sensor_gm1351_power_toggle(); // toggle power of meter + gm1351_last = rtc_get_counter_val(); // restart the wait + puts("no value received from GM1351. trying to power it on\n"); + } + } + } + if (sensor_gm1351_received_flag) { // meter data has been received + action = true; // action has been performed + sensor_gm1351_received_flag = false; // reset flag + led_toggle(); // notify user about activity + gm1351_last = rtc_get_counter_val(); // remember we got a value + char measurement[10 + 1]; // to store the string with the measurement value + snprintf(measurement, LENGTH(measurement), "%u.%u dBa\n", sensor_gm1351_decidba / 10, sensor_gm1351_decidba % 10); // generate string + if (gm1351_show) { + puts(measurement); // display measurement to user + } + // sen measurement to Bluetooth module + for (uint8_t i = 0; i < LENGTH(measurement) && measurement[i] != '\0'; i++) { + spp_tx_putchar_nonblocking( measurement[i]); } } if (action) { // go to sleep if nothing had to be done, else recheck for activity diff --git a/lib/usb_cdcacm.c b/lib/usb_cdcacm.c index 95c1874..19646bd 100644 --- a/lib/usb_cdcacm.c +++ b/lib/usb_cdcacm.c @@ -242,7 +242,7 @@ static char usb_serial[] = "00112233445566778899aabb"; */ static const char* usb_strings[] = { "CuVoodoo", /**< manufacturer string */ - "CuVoodoo STM32F1xx firmware", /**< product string */ + "CuVoodoo GM1351 sound level meter reade", /**< product string */ (const char*)usb_serial, /**< device ID used as serial number */ "DFU bootloader (runtime mode)", /**< DFU interface string */ };