From 29272d43bc7bf77cf6f4dc08ecc00c4cc36c73d7 Mon Sep 17 00:00:00 2001 From: Martin Brodbeck Date: Mon, 9 Jan 2023 08:10:35 +0100 Subject: [PATCH 1/7] WIP: try to safe energy (deinit pio) --- src/abfall.cpp | 43 +++++++++++++++++++++++++------------------ src/ws2812.cpp | 6 ++++-- src/ws2812.h | 2 ++ 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/abfall.cpp b/src/abfall.cpp index a69218b..ef5bebe 100644 --- a/src/abfall.cpp +++ b/src/abfall.cpp @@ -32,7 +32,7 @@ int main() { #endif printf("Firmware version: %s\n", PROJECT_VERSION); - WS2812 led(WS2812_PIN); + // WS2812 led(WS2812_PIN); wifi_enable(); // Enable Wifi in order to set time and retrieve data @@ -96,22 +96,26 @@ int main() { while (currentTime < timestamp) { size_t index = count % wasteDate.wasteTypes.size(); - switch (wasteDate.wasteTypes.at(index)) { - case Waste::GelberSack: - led.switchColor(Color::YELLOW); - break; - case Waste::Restmuell: - led.switchColor(Color::RED); - break; - case Waste::Papiertonne: - led.switchColor(Color::BLUE); - break; - case Waste::Problemstoffmobil: - led.switchColor(Color::CYAN); - break; - case Waste::Biotonne: - led.switchColor(Color::GREEN); - break; + { + WS2812 led(WS2812_PIN); + + switch (wasteDate.wasteTypes.at(index)) { + case Waste::GelberSack: + led.switchColor(Color::YELLOW); + break; + case Waste::Restmuell: + led.switchColor(Color::RED); + break; + case Waste::Papiertonne: + led.switchColor(Color::BLUE); + break; + case Waste::Problemstoffmobil: + led.switchColor(Color::CYAN); + break; + case Waste::Biotonne: + led.switchColor(Color::GREEN); + break; + } } auto timeLeft = timestamp - currentTime; @@ -127,7 +131,10 @@ int main() { } } else { - led.blinkReady(); + { + WS2812 led(WS2812_PIN); + led.blinkReady(); + } sleep_until(static_cast(timestamp)); } } diff --git a/src/ws2812.cpp b/src/ws2812.cpp index c7ad5ac..12d2a34 100644 --- a/src/ws2812.cpp +++ b/src/ws2812.cpp @@ -1,11 +1,13 @@ #include "ws2812.h" WS2812::WS2812(uint gpio, PIO pio, uint sm) : m_pio{pio}, m_sm{sm} { - uint offset = pio_add_program(m_pio, &ws2812_program); - ws2812_program_init(m_pio, m_sm, offset, gpio, 800000, true); + m_offset = pio_add_program(m_pio, &ws2812_program); + ws2812_program_init(m_pio, m_sm, m_offset, gpio, 800000, true); switchColor(Color::OFF); } +WS2812::~WS2812() { pio_remove_program(m_pio, &ws2812_program, m_offset); } + void WS2812::switchColor(Color color) { putPixel(static_cast(color)); } void WS2812::blinkReady() { diff --git a/src/ws2812.h b/src/ws2812.h index 229fccf..2d0d05c 100644 --- a/src/ws2812.h +++ b/src/ws2812.h @@ -17,6 +17,7 @@ enum class Color : uint32_t { class WS2812 { public: WS2812(uint gpio, PIO pio = pio0, uint sm = 0); + virtual ~WS2812(); void switchColor(Color color); void blinkReady(); @@ -24,4 +25,5 @@ class WS2812 { void putPixel(uint32_t pixel_rgb); PIO m_pio; uint m_sm; + uint m_offset{0}; }; From a2a7521e1db6375c699ecd3a7cad13689761dc2b Mon Sep 17 00:00:00 2001 From: Martin Brodbeck Date: Mon, 9 Jan 2023 08:51:10 +0100 Subject: [PATCH 2/7] WIP: try to save energy --- src/abfall.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/abfall.cpp b/src/abfall.cpp index ef5bebe..94d20dc 100644 --- a/src/abfall.cpp +++ b/src/abfall.cpp @@ -89,7 +89,7 @@ int main() { printf("%d-%02d-%02d %02d:%02d.%02d\n", dt.year, dt.month, dt.day, hour, dt.min, dt.sec); // If there was a waste bin pickup found AND we are in the evening (>= 18:00) … - if (it != dates.end() && hour >= 18) { + if (it != dates.end() && hour >= 18 && hour < 23) { auto wasteDate = *it; size_t count{0}; auto currentTime = time_us_64(); From aaa2c6dac4039caecafb9dfffadb40b2c8fc43c8 Mon Sep 17 00:00:00 2001 From: Martin Brodbeck Date: Tue, 10 Jan 2023 08:39:51 +0100 Subject: [PATCH 3/7] Revert "WIP: try to safe energy (deinit pio)" This reverts commit 29272d43bc7bf77cf6f4dc08ecc00c4cc36c73d7. --- src/abfall.cpp | 43 ++++++++++++++++++------------------------- src/ws2812.cpp | 6 ++---- src/ws2812.h | 2 -- 3 files changed, 20 insertions(+), 31 deletions(-) diff --git a/src/abfall.cpp b/src/abfall.cpp index 94d20dc..aaeb08b 100644 --- a/src/abfall.cpp +++ b/src/abfall.cpp @@ -32,7 +32,7 @@ int main() { #endif printf("Firmware version: %s\n", PROJECT_VERSION); - // WS2812 led(WS2812_PIN); + WS2812 led(WS2812_PIN); wifi_enable(); // Enable Wifi in order to set time and retrieve data @@ -96,26 +96,22 @@ int main() { while (currentTime < timestamp) { size_t index = count % wasteDate.wasteTypes.size(); - { - WS2812 led(WS2812_PIN); - - switch (wasteDate.wasteTypes.at(index)) { - case Waste::GelberSack: - led.switchColor(Color::YELLOW); - break; - case Waste::Restmuell: - led.switchColor(Color::RED); - break; - case Waste::Papiertonne: - led.switchColor(Color::BLUE); - break; - case Waste::Problemstoffmobil: - led.switchColor(Color::CYAN); - break; - case Waste::Biotonne: - led.switchColor(Color::GREEN); - break; - } + switch (wasteDate.wasteTypes.at(index)) { + case Waste::GelberSack: + led.switchColor(Color::YELLOW); + break; + case Waste::Restmuell: + led.switchColor(Color::RED); + break; + case Waste::Papiertonne: + led.switchColor(Color::BLUE); + break; + case Waste::Problemstoffmobil: + led.switchColor(Color::CYAN); + break; + case Waste::Biotonne: + led.switchColor(Color::GREEN); + break; } auto timeLeft = timestamp - currentTime; @@ -131,10 +127,7 @@ int main() { } } else { - { - WS2812 led(WS2812_PIN); - led.blinkReady(); - } + led.blinkReady(); sleep_until(static_cast(timestamp)); } } diff --git a/src/ws2812.cpp b/src/ws2812.cpp index 12d2a34..c7ad5ac 100644 --- a/src/ws2812.cpp +++ b/src/ws2812.cpp @@ -1,13 +1,11 @@ #include "ws2812.h" WS2812::WS2812(uint gpio, PIO pio, uint sm) : m_pio{pio}, m_sm{sm} { - m_offset = pio_add_program(m_pio, &ws2812_program); - ws2812_program_init(m_pio, m_sm, m_offset, gpio, 800000, true); + uint offset = pio_add_program(m_pio, &ws2812_program); + ws2812_program_init(m_pio, m_sm, offset, gpio, 800000, true); switchColor(Color::OFF); } -WS2812::~WS2812() { pio_remove_program(m_pio, &ws2812_program, m_offset); } - void WS2812::switchColor(Color color) { putPixel(static_cast(color)); } void WS2812::blinkReady() { diff --git a/src/ws2812.h b/src/ws2812.h index 2d0d05c..229fccf 100644 --- a/src/ws2812.h +++ b/src/ws2812.h @@ -17,7 +17,6 @@ enum class Color : uint32_t { class WS2812 { public: WS2812(uint gpio, PIO pio = pio0, uint sm = 0); - virtual ~WS2812(); void switchColor(Color color); void blinkReady(); @@ -25,5 +24,4 @@ class WS2812 { void putPixel(uint32_t pixel_rgb); PIO m_pio; uint m_sm; - uint m_offset{0}; }; From 377dd3c4e6ec41e3236272f24c32855cf8185cf3 Mon Sep 17 00:00:00 2001 From: Martin Brodbeck Date: Tue, 10 Jan 2023 11:27:15 +0100 Subject: [PATCH 4/7] WIP: trying deep sleep --- .vscode/c_cpp_properties.json | 3 +- CMakeLists.txt | 3 ++ pico_extras_import.cmake | 62 ++++++++++++++++++++++++++++++ src/CMakeLists.txt | 1 + src/abfall.cpp | 29 +++++++++++--- src/ntp_client.cpp | 26 ++++++------- src/utils.cpp | 72 ++++++++++++++++++++++++++++++++--- src/utils.h | 10 ++++- 8 files changed, 177 insertions(+), 29 deletions(-) create mode 100644 pico_extras_import.cmake diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index e385a5e..17ff0c9 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -4,7 +4,8 @@ "name": "Linux", "includePath": [ "${workspaceFolder}/**", - "${env:PICO_SDK_PATH}/**" + "${env:PICO_SDK_PATH}/**", + "${env:PICO_EXTRAS_PATH}/**" ], "defines": [], "compilerPath": "/usr/bin/arm-none-eabi-gcc", diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ce34f8..2c088b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,9 @@ set(PICO_BOARD pico_w CACHE STRING "Board type") # Pull in Raspberry Pi Pico SDK (must be before project) include(pico_sdk_import.cmake) +# Pull in Raspberry Pi Pico Extras +include(pico_extras_import.cmake) + if (PICO_SDK_VERSION_STRING VERSION_LESS "1.4.0") message(FATAL_ERROR "Raspberry Pi Pico SDK version 1.4.0 (or later) required. Your version is ${PICO_SDK_VERSION_STRING}") endif() diff --git a/pico_extras_import.cmake b/pico_extras_import.cmake new file mode 100644 index 0000000..b75b9b3 --- /dev/null +++ b/pico_extras_import.cmake @@ -0,0 +1,62 @@ +# This is a copy of /external/pico_extras_import.cmake + +# This can be dropped into an external project to help locate pico-extras +# It should be include()ed prior to project() + +if (DEFINED ENV{PICO_EXTRAS_PATH} AND (NOT PICO_EXTRAS_PATH)) + set(PICO_EXTRAS_PATH $ENV{PICO_EXTRAS_PATH}) + message("Using PICO_EXTRAS_PATH from environment ('${PICO_EXTRAS_PATH}')") +endif () + +if (DEFINED ENV{PICO_EXTRAS_FETCH_FROM_GIT} AND (NOT PICO_EXTRAS_FETCH_FROM_GIT)) + set(PICO_EXTRAS_FETCH_FROM_GIT $ENV{PICO_EXTRAS_FETCH_FROM_GIT}) + message("Using PICO_EXTRAS_FETCH_FROM_GIT from environment ('${PICO_EXTRAS_FETCH_FROM_GIT}')") +endif () + +if (DEFINED ENV{PICO_EXTRAS_FETCH_FROM_GIT_PATH} AND (NOT PICO_EXTRAS_FETCH_FROM_GIT_PATH)) + set(PICO_EXTRAS_FETCH_FROM_GIT_PATH $ENV{PICO_EXTRAS_FETCH_FROM_GIT_PATH}) + message("Using PICO_EXTRAS_FETCH_FROM_GIT_PATH from environment ('${PICO_EXTRAS_FETCH_FROM_GIT_PATH}')") +endif () + +if (NOT PICO_EXTRAS_PATH) + if (PICO_EXTRAS_FETCH_FROM_GIT) + include(FetchContent) + set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) + if (PICO_EXTRAS_FETCH_FROM_GIT_PATH) + get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_EXTRAS_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") + endif () + FetchContent_Declare( + pico_extras + GIT_REPOSITORY https://github.com/raspberrypi/pico-extras + GIT_TAG master + ) + if (NOT pico_extras) + message("Downloading Raspberry Pi Pico Extras") + FetchContent_Populate(pico_extras) + set(PICO_EXTRAS_PATH ${pico_extras_SOURCE_DIR}) + endif () + set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) + else () + if (PICO_SDK_PATH AND EXISTS "${PICO_SDK_PATH}/../pico-extras") + set(PICO_EXTRAS_PATH ${PICO_SDK_PATH}/../pico-extras) + message("Defaulting PICO_EXTRAS_PATH as sibling of PICO_SDK_PATH: ${PICO_EXTRAS_PATH}") + else() + message(FATAL_ERROR + "PICO EXTRAS location was not specified. Please set PICO_EXTRAS_PATH or set PICO_EXTRAS_FETCH_FROM_GIT to on to fetch from git." + ) + endif() + endif () +endif () + +set(PICO_EXTRAS_PATH "${PICO_EXTRAS_PATH}" CACHE PATH "Path to the PICO EXTRAS") +set(PICO_EXTRAS_FETCH_FROM_GIT "${PICO_EXTRAS_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of PICO EXTRAS from git if not otherwise locatable") +set(PICO_EXTRAS_FETCH_FROM_GIT_PATH "${PICO_EXTRAS_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download EXTRAS") + +get_filename_component(PICO_EXTRAS_PATH "${PICO_EXTRAS_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") +if (NOT EXISTS ${PICO_EXTRAS_PATH}) + message(FATAL_ERROR "Directory '${PICO_EXTRAS_PATH}' not found") +endif () + +set(PICO_EXTRAS_PATH ${PICO_EXTRAS_PATH} CACHE PATH "Path to the PICO EXTRAS" FORCE) + +add_subdirectory(${PICO_EXTRAS_PATH} pico_extras) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0bea1be..2a23ef7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -61,6 +61,7 @@ target_link_libraries(${CMAKE_PROJECT_NAME} pico_lwip_sntp hardware_rtc hardware_pio + hardware_sleep ) pico_add_extra_outputs(${CMAKE_PROJECT_NAME}) diff --git a/src/abfall.cpp b/src/abfall.cpp index aaeb08b..ccfdb3f 100644 --- a/src/abfall.cpp +++ b/src/abfall.cpp @@ -8,6 +8,7 @@ #include "hardware/pio.h" #include "hardware/rtc.h" +#include "hardware/structs/scb.h" #include "pico/cyw43_arch.h" #include "pico/stdlib.h" @@ -63,13 +64,18 @@ int main() { NtpClient::stop(); wifi_disable(); // We don't need Wifi anymore - datetime_t dt; - auto dates = parseCsv(csv); #ifdef DEBUG printf("Number of Dates: %d\n", dates.size()); #endif + datetime_t dt; + + // save values for later + uint scb_orig = scb_hw->scr; + uint clock0_orig = clocks_hw->sleep_en0; + uint clock1_orig = clocks_hw->sleep_en1; + while (true) { auto timestamp = time_us_64() + 60'000'000ull; @@ -82,9 +88,7 @@ int main() { return date.date == tomorrowYMD; }); - int8_t hour = dt.hour + 1; // MEZ - if (isDST(dt.day, dt.month, dt.dotw)) - ++hour; // MESZ + int8_t hour = isDST(dt) ? dt.hour + 1 : dt.hour; printf("%d-%02d-%02d %02d:%02d.%02d\n", dt.year, dt.month, dt.day, hour, dt.min, dt.sec); @@ -127,8 +131,21 @@ int main() { } } else { + // If we start already close to a full hour, dont't do a deep sleep yet + if (dt.min == 59 && dt.sec >= 57) { + sleep_ms((60 - dt.sec) * 1'000); + continue; + } + led.blinkReady(); - sleep_until(static_cast(timestamp)); + + datetime_t dtUntil = dt; + add_one_hour(dtUntil); // next hour + dtUntil.sec = 0; + dtUntil.min = 0; + + perform_sleep(dtUntil); + recover_from_sleep(scb_orig, clock0_orig, clock1_orig); } } diff --git a/src/ntp_client.cpp b/src/ntp_client.cpp index d187a5f..af43122 100644 --- a/src/ntp_client.cpp +++ b/src/ntp_client.cpp @@ -8,24 +8,20 @@ // Called by lwip sntp in order to set the time void set_system_time(u32_t sec) { + sec += 3600; // MEZ + time_t epoch = sec; - struct tm *utc = gmtime(&epoch); + struct tm *mez = gmtime(&epoch); datetime_t datetime; - datetime.year = utc->tm_year + 1900; - datetime.month = utc->tm_mon + 1; - datetime.day = utc->tm_mday; - datetime.hour = utc->tm_hour; - datetime.min = utc->tm_min; - datetime.sec = utc->tm_sec; - datetime.dotw = utc->tm_wday; + datetime.year = mez->tm_year + 1900; + datetime.month = mez->tm_mon + 1; + datetime.day = mez->tm_mday; + datetime.hour = mez->tm_hour; + datetime.min = mez->tm_min; + datetime.sec = mez->tm_sec; + datetime.dotw = mez->tm_wday; - bool success = rtc_set_datetime(&datetime); - -#ifdef DEBUG - if (success) { - printf("RTC successfully set.\n"); - } -#endif + rtc_set_datetime(&datetime); } void NtpClient::setDateTime() { diff --git a/src/utils.cpp b/src/utils.cpp index 391e92e..8a97c95 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -4,23 +4,30 @@ #include #include +#include "pico/sleep.h" +#include "pico/stdlib.h" +// #include "stdlib.h" +#include "hardware/clocks.h" +#include "hardware/rosc.h" +#include "hardware/structs/scb.h" + using namespace std; -bool isDST(int8_t day, int8_t month, int8_t dow) { +bool isDST(const datetime_t &dt) { // January, february, november and december are out. - if (month < 3 || month > 10) { + if (dt.month < 3 || dt.month > 10) { return false; } // April to September are in - if (month > 3 && month < 10) { + if (dt.month > 3 && dt.month < 10) { return true; } - int previousSunday = day - dow; + int previousSunday = dt.day - dt.dotw; // In march, we are DST if our previous sunday was on or after the 25th. - if (month == 3) { + if (dt.month == 3) { return previousSunday >= 25; } @@ -186,4 +193,57 @@ void wifi_disable() { cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0); cyw43_wifi_leave(&cyw43_state, CYW43_ITF_STA); cyw43_arch_deinit(); -} \ No newline at end of file +} + +void recover_from_sleep(uint scb_orig, uint clock0_orig, uint clock1_orig) { + + // Re-enable ring Oscillator control + rosc_write(&rosc_hw->ctrl, ROSC_CTRL_ENABLE_BITS); + + // reset procs back to default + scb_hw->scr = scb_orig; + clocks_hw->sleep_en0 = clock0_orig; + clocks_hw->sleep_en1 = clock1_orig; + + // reset clocks + clocks_init(); + stdio_init_all(); + + return; +} + +void perform_sleep(datetime_t &untilDt) { + printf("Going to sleep...\n"); + uart_default_tx_wait_blocking(); + + sleep_goto_sleep_until(&untilDt, nullptr); +} + +void add_one_day(datetime_t &dt) { + int daysPerMonth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + + // Is it a leap year? + if ((dt.year % 4 == 0 && dt.year % 100 != 0) || dt.year % 400 == 0) { + daysPerMonth[2] = 29; + } + + if (dt.month == 12 && dt.day == daysPerMonth[12]) { + dt.year += 1; + dt.month = 1; + dt.day = 1; + } else if (dt.day == daysPerMonth[dt.month]) { + dt.month = (dt.month + 1) % 12; + dt.day = 1; + } else { + dt.day += 1; + } +} + +void add_one_hour(datetime_t &dt) { + if (dt.hour == 23) { + add_one_day(dt); + dt.hour = 0; + } else { + dt.hour += 1; + } +} diff --git a/src/utils.h b/src/utils.h index dbcb4d2..f7c9d2c 100644 --- a/src/utils.h +++ b/src/utils.h @@ -27,4 +27,12 @@ void wifi_enable(); void wifi_disable(); -bool isDST(int8_t day, int8_t month, int8_t dow); \ No newline at end of file +bool isDST(const datetime_t &dt); + +void recover_from_sleep(uint scb_orig, uint clock0_orig, uint clock1_orig); + +void perform_sleep(datetime_t &untilDt); + +//void add_one_day(datetime_t &dt); + +void add_one_hour(datetime_t &dt); \ No newline at end of file From ce08d17a11aee6210d5aa2ad1ef53e196b55247c Mon Sep 17 00:00:00 2001 From: Martin Brodbeck Date: Tue, 10 Jan 2023 21:51:36 +0100 Subject: [PATCH 5/7] WIP: trying to deep sleep --- src/abfall.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/abfall.cpp b/src/abfall.cpp index ccfdb3f..0f133b9 100644 --- a/src/abfall.cpp +++ b/src/abfall.cpp @@ -9,8 +9,13 @@ #include "hardware/pio.h" #include "hardware/rtc.h" #include "hardware/structs/scb.h" +// #include "hardware/xosc.h" +// #nclude "hardware/rosc.h" +// #include "hardware/clocks.h" +// #include "hardware/pll.h" #include "pico/cyw43_arch.h" +#include "pico/sleep.h" #include "pico/stdlib.h" #include "pico/util/datetime.h" @@ -33,8 +38,6 @@ int main() { #endif printf("Firmware version: %s\n", PROJECT_VERSION); - WS2812 led(WS2812_PIN); - wifi_enable(); // Enable Wifi in order to set time and retrieve data NtpClient::setDateTime(); @@ -75,6 +78,10 @@ int main() { uint scb_orig = scb_hw->scr; uint clock0_orig = clocks_hw->sleep_en0; uint clock1_orig = clocks_hw->sleep_en1; + uart_default_tx_wait_blocking(); + sleep_run_from_xosc(); + + WS2812 led(WS2812_PIN); while (true) { auto timestamp = time_us_64() + 60'000'000ull; @@ -138,6 +145,7 @@ int main() { } led.blinkReady(); + sleep_ms(800); datetime_t dtUntil = dt; add_one_hour(dtUntil); // next hour From 20f912f919a56dca59d23609431548a76500b091 Mon Sep 17 00:00:00 2001 From: Martin Brodbeck Date: Wed, 11 Jan 2023 11:12:02 +0100 Subject: [PATCH 6/7] using deep sleep --- src/abfall.cpp | 12 ++++++------ src/ws2812.cpp | 25 ++++++++++++++++++++----- src/ws2812.h | 7 +++++++ 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/abfall.cpp b/src/abfall.cpp index 0f133b9..f914b7c 100644 --- a/src/abfall.cpp +++ b/src/abfall.cpp @@ -1,5 +1,4 @@ #include -#include #include #include @@ -9,10 +8,6 @@ #include "hardware/pio.h" #include "hardware/rtc.h" #include "hardware/structs/scb.h" -// #include "hardware/xosc.h" -// #nclude "hardware/rosc.h" -// #include "hardware/clocks.h" -// #include "hardware/pll.h" #include "pico/cyw43_arch.h" #include "pico/sleep.h" @@ -97,13 +92,17 @@ int main() { int8_t hour = isDST(dt) ? dt.hour + 1 : dt.hour; +#ifdef DEBUG printf("%d-%02d-%02d %02d:%02d.%02d\n", dt.year, dt.month, dt.day, hour, dt.min, dt.sec); +#endif // If there was a waste bin pickup found AND we are in the evening (>= 18:00) … if (it != dates.end() && hour >= 18 && hour < 23) { auto wasteDate = *it; size_t count{0}; auto currentTime = time_us_64(); + WS2812 led(WS2812_PIN); + while (currentTime < timestamp) { size_t index = count % wasteDate.wasteTypes.size(); @@ -145,15 +144,16 @@ int main() { } led.blinkReady(); - sleep_ms(800); datetime_t dtUntil = dt; add_one_hour(dtUntil); // next hour dtUntil.sec = 0; dtUntil.min = 0; + led.deinit(); // deinit LED before going to deep sleep perform_sleep(dtUntil); recover_from_sleep(scb_orig, clock0_orig, clock1_orig); + led.init(); // init LED again after deep sleep } } diff --git a/src/ws2812.cpp b/src/ws2812.cpp index c7ad5ac..edf35b7 100644 --- a/src/ws2812.cpp +++ b/src/ws2812.cpp @@ -1,10 +1,8 @@ #include "ws2812.h" -WS2812::WS2812(uint gpio, PIO pio, uint sm) : m_pio{pio}, m_sm{sm} { - uint offset = pio_add_program(m_pio, &ws2812_program); - ws2812_program_init(m_pio, m_sm, offset, gpio, 800000, true); - switchColor(Color::OFF); -} +WS2812::WS2812(uint gpio, PIO pio, uint sm) : m_pio{pio}, m_gpio{gpio}, m_sm{sm} { init(); } + +WS2812::~WS2812() { deinit(); } void WS2812::switchColor(Color color) { putPixel(static_cast(color)); } @@ -17,4 +15,21 @@ void WS2812::blinkReady() { } } +void WS2812::init() { + if (m_offset != 0) + return; + + m_offset = pio_add_program(m_pio, &ws2812_program); + ws2812_program_init(m_pio, m_sm, m_offset, m_gpio, 800000, true); + switchColor(Color::OFF); + sleep_ms(1); +} + +void WS2812::deinit() { + switchColor(Color::OFF); + sleep_ms(1); + pio_remove_program(m_pio, &ws2812_program, m_offset); + m_offset = 0; +} + void WS2812::putPixel(uint32_t pixel_grb) { pio_sm_put_blocking(m_pio, m_sm, pixel_grb << 8u); } \ No newline at end of file diff --git a/src/ws2812.h b/src/ws2812.h index 229fccf..f7746bb 100644 --- a/src/ws2812.h +++ b/src/ws2812.h @@ -17,11 +17,18 @@ enum class Color : uint32_t { class WS2812 { public: WS2812(uint gpio, PIO pio = pio0, uint sm = 0); + virtual ~WS2812(); + WS2812(const WS2812 &other) = delete; + WS2812 &operator=(const WS2812 &) = delete; void switchColor(Color color); void blinkReady(); + void init(); + void deinit(); private: void putPixel(uint32_t pixel_rgb); PIO m_pio; + uint m_gpio; uint m_sm; + uint m_offset{0}; }; From 1ac414e0b42be950ee6fa4ae7ad03d8897391d60 Mon Sep 17 00:00:00 2001 From: Martin Brodbeck Date: Wed, 11 Jan 2023 11:17:24 +0100 Subject: [PATCH 7/7] typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 13f5176..9603c5d 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ## Idee Das Gerät soll am Vorabend (ab 18:00 Uhr) anzeigen, welche Abfallarten am nächsten Tag abgeholt werden. Die Anzeige erfolgt über eine RGB-LED. -* Keine Abholung: minütliches blinken in **WEIß** (0xffffff / 0x000000) +* Keine Abholung: minütliches blinken in **WEIẞ** (0xffffff / 0x000000) (Daran erkennt man, dass das Gerät noch läuft.) * Restmüll: **ROT** (0xff0000) * Papier: **BLAU** (0x0000ff)