Kaynağa Gözat

alarm_task: Add task implementation to make the wake up call

Helmut Pozimski 1 yıl önce
ebeveyn
işleme
3b95b67ed4
3 değiştirilmiş dosya ile 112 ekleme ve 1 silme
  1. 1 1
      main/CMakeLists.txt
  2. 104 0
      main/alarm_task.c
  3. 7 0
      main/alarm_task.h

+ 1 - 1
main/CMakeLists.txt

@@ -1,2 +1,2 @@
-idf_component_register(SRCS "esp32_alarm_clock_main.c" "wifi.c" "storage.c" "api.c" "ds3231.c" "bcd.c" "tm1637.c" "time_sync.c" "time_display.c" "alarm.c"
+idf_component_register(SRCS "esp32_alarm_clock_main.c" "wifi.c" "storage.c" "api.c" "ds3231.c" "bcd.c" "tm1637.c" "time_sync.c" "time_display.c" "alarm.c" "time_conversion.c" "alarm_task.c"
                     INCLUDE_DIRS "")

+ 104 - 0
main/alarm_task.c

@@ -0,0 +1,104 @@
+/*
+ * SPDX-FileCopyrightText: 2023 Helmut Pozimski <helmut@pozimski.eu>
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+#include <stdint.h>
+
+#include <esp_err.h>
+#include <freertos/FreeRTOS.h>
+#include <freertos/event_groups.h>
+#include <esp_log.h>
+
+
+#include "time_conversion.h"
+#include "storage.h"
+#include "alarm.h"
+#include "ds3231.h"
+
+#define SECONDS_PER_DAY 86400
+#define TAG "alarm-task"
+
+static esp_err_t determine_wakeup_minute_for_day(struct tm* local_time, int16_t* result) {
+	esp_err_t ret = read_wakeup_time_tm(local_time, result);
+	if (ret == ESP_OK) {
+		return ESP_OK;
+	}
+	ret |= read_wakeup_time_str(WEEK_DAYS[local_time->tm_wday], result);
+	return ret;
+}
+
+static uint16_t calculate_current_minute(struct tm* local_time) {
+	return local_time->tm_hour * 60 + local_time->tm_min;
+}
+
+static uint32_t calculate_current_second(struct tm* local_time) {
+	return local_time->tm_hour * 60 * 60 + local_time->tm_min * 60 + local_time->tm_sec;
+}
+
+static uint32_t determine_next_wakeup_time(struct tm* current_time) {
+	struct tm *local_time = convert_to_local(current_time);
+	uint32_t current_second = calculate_current_second(local_time);
+	int16_t wakeup_minute_today;
+	
+	esp_err_t ret = determine_wakeup_minute_for_day(local_time, &wakeup_minute_today);
+	
+	if (ret == ESP_OK) {
+		if (wakeup_minute_today >= (current_second / 60)) {
+			return wakeup_minute_today * 60 - current_second;
+		}
+	}
+	
+	current_time->tm_mday++;
+	struct tm *local_time_tomorrow = convert_to_local(current_time);
+	int16_t wakeup_minute_tomorrow;
+	ret = determine_wakeup_minute_for_day(local_time_tomorrow, &wakeup_minute_tomorrow);
+	
+	if (ret == ESP_OK) {
+		ESP_LOGI(TAG, "Wakeup minute for tomorrow: %d", wakeup_minute_tomorrow);
+		if (wakeup_minute_tomorrow != -1) {
+			return (SECONDS_PER_DAY - current_second) + wakeup_minute_tomorrow * 60;
+		}
+	}
+	return SECONDS_PER_DAY;
+	
+}
+
+static void assert_alarm(uint8_t* button_pressed_flag) {
+	*button_pressed_flag = 0;
+	for (uint8_t i = 0; i < 60; i++) {
+		beep(100);
+		vTaskDelay(100 / portTICK_PERIOD_MS);
+		beep(100);
+		vTaskDelay(2000 / portTICK_PERIOD_MS);
+		if (*button_pressed_flag) {
+			break;		
+		}
+	}
+}
+ 
+void alarm_task(void *pvParameters) {
+	ESP_LOGI(TAG, "Starting alarm task");
+	struct tm current_time;
+	alarm_init(200);
+	uint8_t* button_pressed_flag = (uint8_t*) pvParameters;
+	
+	while (1) {
+		ds3231_read_date_time(&current_time);
+		struct tm *local_time = convert_to_local(&current_time);
+		uint16_t current_minute = calculate_current_minute(local_time);
+		int16_t wakeup_minute_today;
+		esp_err_t ret = determine_wakeup_minute_for_day(local_time, &wakeup_minute_today);
+		ESP_LOGI(TAG, "Current minute: %d", current_minute);
+		ESP_LOGI(TAG, "Wakeup minute for today: %d", wakeup_minute_today);
+		if (ret == ESP_OK && current_minute == wakeup_minute_today) {
+			assert_alarm(button_pressed_flag);
+		}
+		ds3231_read_date_time(&current_time);
+		uint32_t seconds_to_wait = determine_next_wakeup_time(&current_time);
+		ESP_LOGI(TAG, "Sleeping for %ld seconds", seconds_to_wait);
+		vTaskDelay(seconds_to_wait * 1000 / portTICK_PERIOD_MS);
+	}	
+	vTaskDelete( NULL ); 
+}

+ 7 - 0
main/alarm_task.h

@@ -0,0 +1,7 @@
+/*
+ * SPDX-FileCopyrightText: 2023 Helmut Pozimski <helmut@pozimski.eu>
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+ 
+void alarm_task(void *pvParameters);