From 84188a32dadf8a73850245a864cb4ab19af43e0e Mon Sep 17 00:00:00 2001 From: Anton Mukhin Date: Sat, 21 Jan 2023 02:50:06 +0300 Subject: [PATCH 1/4] Reworked light modes; now there are 3 modes cycled by a button taps - normal, manual on, manual off. --- firmware/.settings/language.settings.xml | 4 +- firmware/Core/Src/main.c | 91 +++++++++++++++--------- kicad/rev.2.0/DiLight_2.0.kicad_prl | 2 +- 3 files changed, 61 insertions(+), 36 deletions(-) diff --git a/firmware/.settings/language.settings.xml b/firmware/.settings/language.settings.xml index 3e3e328..ba20e13 100644 --- a/firmware/.settings/language.settings.xml +++ b/firmware/.settings/language.settings.xml @@ -5,7 +5,7 @@ - + @@ -16,7 +16,7 @@ - + diff --git a/firmware/Core/Src/main.c b/firmware/Core/Src/main.c index 9b89e51..559f173 100644 --- a/firmware/Core/Src/main.c +++ b/firmware/Core/Src/main.c @@ -41,6 +41,16 @@ struct FLASH_sector { uint32_t checksum; //Checksum to verify saved data }; +typedef enum DLMode_t_enum { + DL_normal = 0, + DL_manual_on, + DL_manual_off, + DL_need_config, + DL_config_waiting, + DL_config_accepted, + DL_error +} DLMode_t; + /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ @@ -85,10 +95,12 @@ uint8_t TOF_Ready = 0; // Flag to ignore TOF IRQ before it is initialized uint8_t curLightLevel = 0; // Current light level (0-99) uint16_t curDist = 0; // Current measured distance in mm uint16_t btn_ticks; // How many ticks the button is pressed (1 tick = 100ms) -uint8_t needConfig = 1; // Need to configure the device. Timers won't "react" to events -uint8_t startConfig = 0; // Flag to start configuration sequence +//uint8_t needConfig = 1; // Need to configure the device. Timers won't "react" to events +//uint8_t startConfig = 0; // Flag to start configuration sequence int8_t dLevel = 1; // Direction of fade: -1 for fade out; 1 for fade in; -uint8_t manualOn = 0; // Flag to indicate a manual on +//uint8_t manualOn = 0; // Flag to indicate a manual on +DLMode_t DLmode = DL_normal; // Global mode: DL_normal, DL_manual_on, DL_manual_off, DL_need_config, DL_config_waiting, DL_config_accepted, DL_error +DLMode_t prev_mode = DL_normal; /* USER CODE END PV */ @@ -134,7 +146,6 @@ volatile void loadConfig(void) { saveConfig(); //Save dafault config } // else successfully read the configuration - needConfig = 0; } //save configuration to FLASH @@ -199,15 +210,16 @@ void fastBlink(uint8_t count) { // Range configuration procedure (set on and off ranges) void configure(void) { - startConfig = 0; + //startConfig = 0; + DLmode = DL_config_waiting; - //Fast blink 3 times - needConfig = 1; - fastBlink(3); + //Fast blink 5 times + //needConfig = 1; + fastBlink(5); //Configure ON distance - needConfig = 1; // in case the button was touched during fast blinks - while (needConfig) { + //needConfig = 1; // in case the button was touched during fast blinks + while (DLmode == DL_config_waiting) { HAL_Delay(250); if (curDist > MAX_DIST - MIN_DIST_GAP) setLightLevel(0); // (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min @@ -219,12 +231,13 @@ void configure(void) { configuration.config.dist_on = curDist; // this will be checked during config save //Fast blink 2 times - needConfig = 1; + //needConfig = 1; + DLmode = DL_config_waiting; fastBlink(2); //Configure OFF distance - needConfig = 1; // in case the button was touched during fast blinks - while (needConfig) { + //needConfig = 1; // in case the button was touched during fast blinks + while (DLmode == DL_config_waiting) { HAL_Delay(250); if (curDist > MAX_DIST) setLightLevel(0); else setLightLevel((uint8_t)(50 - curDist * 50 / MAX_DIST)); // Map light level to the distance @@ -234,10 +247,10 @@ void configure(void) { saveConfig(); //Fast blink 5 times - needConfig = 1; + //needConfig = 1; fastBlink(5); - needConfig = 0; + //needConfig = 0; } /* USER CODE END 0 */ @@ -312,8 +325,10 @@ int main(void) /* USER CODE BEGIN WHILE */ while (1) { - if (startConfig) { + if (DLmode == DL_need_config) { + prev_mode = DLmode; configure(); + DLmode = prev_mode; } HAL_Delay(100); @@ -643,7 +658,7 @@ void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin) { dist = readRangeContinuousMillimeters(0); if (dist < MAX_DIST) curDist = dist; else curDist = MAX_DIST; - if (!needConfig && !manualOn) { + if (DLmode == DL_normal) { if (curDist <= configuration.config.dist_on && curLightLevel < 90) { //Turn on the lights dLevel = 2; @@ -662,38 +677,48 @@ void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin) { HAL_TIM_Base_Stop_IT(&htim16); if (btn_ticks < 60) { // Button was not held for more than 6 seconds - if (needConfig) { - needConfig = 0; + if (DLmode == DL_config_waiting) { + //needConfig = 0; + DLmode = DL_config_accepted; } else { - if (curLightLevel < 90){ - //Manual turn on - manualOn = 1; - dLevel = 2; - HAL_TIM_Base_Start_IT(&htim17); - } else { - //Manual turn off - manualOn = 0; - dLevel = -1; - HAL_TIM_Base_Start_IT(&htim17); + switch (DLmode) { + case DL_normal: + DLmode = DL_manual_on; + fastBlink(2); + dLevel = 2; + HAL_TIM_Base_Start_IT(&htim17); + break; + case DL_manual_on: + DLmode = DL_manual_off; + fastBlink(3); + dLevel = -1; + HAL_TIM_Base_Start_IT(&htim17); + break; + case DL_manual_off: + DLmode = DL_normal; + fastBlink(1); + break; + default: + break; } - setLightLevel(curLightLevel); } } } } void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { - if(htim->Instance == TIM16) { //check if the interrupt comes from TIM16 + if(htim->Instance == TIM16) { //check if the interrupt comes from TIM16 // TIM16 - ticks timer (10Hz - 100ms) if (btn_ticks < 60) { btn_ticks++; } else { // the button is held for more than 6 seconds HAL_TIM_Base_Stop_IT(&htim16); - startConfig = 1; + //startConfig = 1; + DLmode = DL_need_config; } } // Fade-in / fade-out animation - if(htim->Instance == TIM17) { //check if the interrupt comes from TIM17 + if(htim->Instance == TIM17) { //check if the interrupt comes from TIM17 // TIM17 - timer for light fading curLightLevel += dLevel; setLightLevel(curLightLevel); if (curLightLevel >= 99 || curLightLevel <= 0) { diff --git a/kicad/rev.2.0/DiLight_2.0.kicad_prl b/kicad/rev.2.0/DiLight_2.0.kicad_prl index 53e5840..fa5a42d 100644 --- a/kicad/rev.2.0/DiLight_2.0.kicad_prl +++ b/kicad/rev.2.0/DiLight_2.0.kicad_prl @@ -1,6 +1,6 @@ { "board": { - "active_layer": 36, + "active_layer": 0, "active_layer_preset": "", "auto_track_width": true, "hidden_nets": [], From e5045de31c673b1b6a35794103491af03128d045 Mon Sep 17 00:00:00 2001 From: Anton Mukhin Date: Sat, 21 Jan 2023 19:07:17 +0300 Subject: [PATCH 2/4] Moved modeswitch logic out of the ISR handler; Fixed fade in/out logic so it wont turn on the light when asked to fade out; --- firmware/Core/Src/main.c | 61 +++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/firmware/Core/Src/main.c b/firmware/Core/Src/main.c index 559f173..6709d87 100644 --- a/firmware/Core/Src/main.c +++ b/firmware/Core/Src/main.c @@ -101,6 +101,7 @@ int8_t dLevel = 1; // Direction of fade: -1 for fade out; 1 for fade in //uint8_t manualOn = 0; // Flag to indicate a manual on DLMode_t DLmode = DL_normal; // Global mode: DL_normal, DL_manual_on, DL_manual_off, DL_need_config, DL_config_waiting, DL_config_accepted, DL_error DLMode_t prev_mode = DL_normal; +uint8_t modeSwitch = 0; // Flag to switch the mode after the button tap /* USER CODE END PV */ @@ -197,8 +198,9 @@ volatile void saveConfig(void) { // Fast blink LEDs `count` times void fastBlink(uint8_t count) { - uint8_t i; + uint8_t i, pll; + pll = curLightLevel; setLightLevel(0); for (i = 0; i < count; i++) { setLightLevel(99); @@ -206,6 +208,7 @@ void fastBlink(uint8_t count) { setLightLevel(0); HAL_Delay(80); } + setLightLevel(pll); } // Range configuration procedure (set on and off ranges) @@ -326,12 +329,35 @@ int main(void) while (1) { if (DLmode == DL_need_config) { - prev_mode = DLmode; configure(); DLmode = prev_mode; } - HAL_Delay(100); + if (modeSwitch) { + modeSwitch = 0; + switch (DLmode) { + case DL_normal: + DLmode = DL_manual_on; + fastBlink(1); + dLevel = 2; + HAL_TIM_Base_Start_IT(&htim17); + break; + case DL_manual_on: + DLmode = DL_manual_off; + fastBlink(1); + dLevel = -1; + HAL_TIM_Base_Start_IT(&htim17); + break; + case DL_manual_off: + DLmode = DL_normal; + fastBlink(2); + break; + default: + break; + } + } + + HAL_Delay(50); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ @@ -681,26 +707,7 @@ void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin) { //needConfig = 0; DLmode = DL_config_accepted; } else { - switch (DLmode) { - case DL_normal: - DLmode = DL_manual_on; - fastBlink(2); - dLevel = 2; - HAL_TIM_Base_Start_IT(&htim17); - break; - case DL_manual_on: - DLmode = DL_manual_off; - fastBlink(3); - dLevel = -1; - HAL_TIM_Base_Start_IT(&htim17); - break; - case DL_manual_off: - DLmode = DL_normal; - fastBlink(1); - break; - default: - break; - } + modeSwitch = 1; } } } @@ -713,16 +720,18 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { } else { // the button is held for more than 6 seconds HAL_TIM_Base_Stop_IT(&htim16); //startConfig = 1; + prev_mode = DLmode; DLmode = DL_need_config; } } // Fade-in / fade-out animation if(htim->Instance == TIM17) { //check if the interrupt comes from TIM17 // TIM17 - timer for light fading - curLightLevel += dLevel; - setLightLevel(curLightLevel); - if (curLightLevel >= 99 || curLightLevel <= 0) { + if ((curLightLevel >= 99 && dLevel > 0) || (curLightLevel == 0 && dLevel < 0)) { HAL_TIM_Base_Stop_IT(&htim17); + } else { + curLightLevel += dLevel; + setLightLevel(curLightLevel); } } } From 353c58bfcb91c0efcb6e4bd0f3b582b25c9941e3 Mon Sep 17 00:00:00 2001 From: Anton Mukhin Date: Sat, 21 Jan 2023 19:35:12 +0300 Subject: [PATCH 3/4] Tidy up the code --- firmware/.settings/language.settings.xml | 4 +- firmware/Core/Src/main.c | 66 ++++++++++-------------- 2 files changed, 29 insertions(+), 41 deletions(-) diff --git a/firmware/.settings/language.settings.xml b/firmware/.settings/language.settings.xml index ba20e13..8a92f6c 100644 --- a/firmware/.settings/language.settings.xml +++ b/firmware/.settings/language.settings.xml @@ -5,7 +5,7 @@ - + @@ -16,7 +16,7 @@ - + diff --git a/firmware/Core/Src/main.c b/firmware/Core/Src/main.c index 6709d87..2f79dd4 100644 --- a/firmware/Core/Src/main.c +++ b/firmware/Core/Src/main.c @@ -95,13 +95,10 @@ uint8_t TOF_Ready = 0; // Flag to ignore TOF IRQ before it is initialized uint8_t curLightLevel = 0; // Current light level (0-99) uint16_t curDist = 0; // Current measured distance in mm uint16_t btn_ticks; // How many ticks the button is pressed (1 tick = 100ms) -//uint8_t needConfig = 1; // Need to configure the device. Timers won't "react" to events -//uint8_t startConfig = 0; // Flag to start configuration sequence int8_t dLevel = 1; // Direction of fade: -1 for fade out; 1 for fade in; -//uint8_t manualOn = 0; // Flag to indicate a manual on DLMode_t DLmode = DL_normal; // Global mode: DL_normal, DL_manual_on, DL_manual_off, DL_need_config, DL_config_waiting, DL_config_accepted, DL_error -DLMode_t prev_mode = DL_normal; -uint8_t modeSwitch = 0; // Flag to switch the mode after the button tap +DLMode_t prev_mode = DL_normal; // To hold the mode during temporary mode switches +uint8_t modeSwitch = 0; // Flag to switch the mode after the button tap /* USER CODE END PV */ @@ -143,7 +140,6 @@ volatile void loadConfig(void) { if (HAL_CRC_Calculate(&hcrc, configuration.data32, 2) != configuration.sector.checksum || configuration.config.token != CONF_TOKEN) { //First start or configuration is corrupted - saveConfig(); //Save dafault config } // else successfully read the configuration @@ -157,9 +153,9 @@ volatile void saveConfig(void) { uint32_t l_Error = 0; //We need it to erase a page - EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; - EraseInitStruct.Page = CONF_FLASH_PAGE; - EraseInitStruct.NbPages = 1; + EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; + EraseInitStruct.Page = CONF_FLASH_PAGE; + EraseInitStruct.NbPages = 1; if (configuration.config.token != CONF_TOKEN) { //first start @@ -213,15 +209,12 @@ void fastBlink(uint8_t count) { // Range configuration procedure (set on and off ranges) void configure(void) { - //startConfig = 0; DLmode = DL_config_waiting; //Fast blink 5 times - //needConfig = 1; fastBlink(5); //Configure ON distance - //needConfig = 1; // in case the button was touched during fast blinks while (DLmode == DL_config_waiting) { HAL_Delay(250); if (curDist > MAX_DIST - MIN_DIST_GAP) setLightLevel(0); @@ -234,12 +227,10 @@ void configure(void) { configuration.config.dist_on = curDist; // this will be checked during config save //Fast blink 2 times - //needConfig = 1; DLmode = DL_config_waiting; fastBlink(2); //Configure OFF distance - //needConfig = 1; // in case the button was touched during fast blinks while (DLmode == DL_config_waiting) { HAL_Delay(250); if (curDist > MAX_DIST) setLightLevel(0); @@ -250,10 +241,7 @@ void configure(void) { saveConfig(); //Fast blink 5 times - //needConfig = 1; fastBlink(5); - - //needConfig = 0; } /* USER CODE END 0 */ @@ -333,29 +321,30 @@ int main(void) DLmode = prev_mode; } + // Check if the button was tapped and we should switch the mode if (modeSwitch) { modeSwitch = 0; switch (DLmode) { - case DL_normal: - DLmode = DL_manual_on; - fastBlink(1); - dLevel = 2; - HAL_TIM_Base_Start_IT(&htim17); - break; - case DL_manual_on: - DLmode = DL_manual_off; - fastBlink(1); - dLevel = -1; - HAL_TIM_Base_Start_IT(&htim17); - break; - case DL_manual_off: - DLmode = DL_normal; - fastBlink(2); - break; - default: - break; + case DL_normal: + DLmode = DL_manual_on; + fastBlink(1); + dLevel = 2; + HAL_TIM_Base_Start_IT(&htim17); + break; + case DL_manual_on: + DLmode = DL_manual_off; + fastBlink(1); + dLevel = -1; + HAL_TIM_Base_Start_IT(&htim17); + break; + case DL_manual_off: + DLmode = DL_normal; + fastBlink(2); + break; + default: + break; + } } - } HAL_Delay(50); /* USER CODE END WHILE */ @@ -704,7 +693,6 @@ void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin) { if (btn_ticks < 60) { // Button was not held for more than 6 seconds if (DLmode == DL_config_waiting) { - //needConfig = 0; DLmode = DL_config_accepted; } else { modeSwitch = 1; @@ -717,9 +705,9 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim->Instance == TIM16) { //check if the interrupt comes from TIM16 // TIM16 - ticks timer (10Hz - 100ms) if (btn_ticks < 60) { btn_ticks++; - } else { // the button is held for more than 6 seconds + } else { + // the button is held for more than 6 seconds HAL_TIM_Base_Stop_IT(&htim16); - //startConfig = 1; prev_mode = DLmode; DLmode = DL_need_config; } From 5a5fb74751e67071ddddea031b48f955f2aec4ff Mon Sep 17 00:00:00 2001 From: Anton Mukhin Date: Sat, 21 Jan 2023 19:44:21 +0300 Subject: [PATCH 4/4] README.md change --- README.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/README.md b/README.md index 8dd6b36..8e65737 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Конфигурация хранится на последней странице флеш-памяти контроллера. Светильник включается если человек (или что-то другое) приближается на растояние, установленное при конфигурировании и выключается как только человек удаляется на расстояние большее, чем рысстояние выключения. -Тап по кнопке включает/выключает светильник. Мри включении вручную, светильник не реагирует на человека. +Тап по кнопке по кругу переключает ражимы работы светильника: Нормальный -> Всегда включен -> Всегда выключен. [Схема rev.2.0](/kicad/rev.2.0/DiLight_2.0.pdf) @@ -33,12 +33,6 @@ [![YouTube video](http://img.youtube.com/vi/1dccDMPywVc/0.jpg)](http://www.youtube.com/watch?v=1dccDMPywVc) -#### TODO: - -- Добавить третий режим, в котором светильник будет выключен и не будет реагировать на датчик расстояния -- Добавить обратную связь (мигнуть) при смене режимов. - - #### История: rev.2.0a: