Summary Files Commits Branches @commit @diff @stats
diff options
context:
space:
mode:
Commit6270409b28e06b34a9e2e911843d7feca2e68b79 (patch)
Author
 Syndamia <kamen@syndamia.com>
2024-05-28 15:00:39 +0300
Committer
 Syndamia <kamen@syndamia.com>
2024-05-28 15:00:39 +0300
Files8eb05ec73a040504ab098b9e16b4fae1e5c9a128
uni-projects-6270409b28e06b34a9e2e911843d7feca2e68b79.tar
uni-projects-6270409b28e06b34a9e2e911843d7feca2e68b79.tar.gz
uni-projects-6270409b28e06b34a9e2e911843d7feca2e68b79.zip
Parent0607d35298790368b02b429b1baa7f14e97aaaf2 (diff)
[iot/goam] Implemented timelapse
diff --git a/Year 3/Internet of things/goam/main/buttons.c b/Year 3/Internet of things/goam/main/buttons.c
index 2f30622..d9799d7 100644
--- a/Year 3/Internet of things/goam/main/buttons.c
+++ b/Year 3/Internet of things/goam/main/buttons.c
@@ -23,7 +23,6 @@ static void IRAM_ATTR gpio_button_interrupt_handler(void* arg)
}
static void (*button_on[40])() = { NULL };
-static void (*button_off[40])() = { NULL };
#define BUTTON_ACTION_COMPLETED_BIT 0b1
@@ -31,12 +30,7 @@ static TaskHandle_t on_button_event_handle = NULL;
static void button_action(void* arg) {
uint32_t io_num = *(uint32_t*)arg;
- if (gpio_get_level(io_num)) {
- if (button_on[io_num]) button_on[io_num]();
- }
- else {
- if (button_off[io_num]) button_off[io_num]();
- }
+ if (button_on[io_num]) button_on[io_num]();
xTaskNotify(on_button_event_handle, BUTTON_ACTION_COMPLETED_BIT, eSetBits);
vTaskDelete(NULL);
@@ -92,7 +86,7 @@ void buttons_init() {
#define gpio_to_bitmask(pin) (1ULL << pin)
-void add_push_button(unsigned pin, void (*on_press)(), void (*off_press)()) {
+void add_push_button(unsigned pin, void (*on_press)()) {
gpio_config_t o_conf = {
.intr_type = GPIO_INTR_POSEDGE,
//set as output mode
@@ -111,7 +105,10 @@ void add_push_button(unsigned pin, void (*on_press)(), void (*off_press)()) {
// handler
gpio_isr_handler_add(pin, gpio_button_interrupt_handler, (void*)pin);
button_on[pin] = on_press;
- button_off[pin] = off_press;
- ESP_LOGD(TAG, "GPIO[%d] added intr handlers, on_press: %d, off_press: %d", pin, on_press != NULL, off_press != NULL);
+ ESP_LOGD(TAG, "GPIO[%d] added intr handler, on_press: %d", pin, on_press != NULL);
+}
+
+void press_push_button(int gpio_num) {
+ xQueueSend(gpio_button_queue, &gpio_num, 100 / portTICK_PERIOD_MS);
}
diff --git a/Year 3/Internet of things/goam/main/buttons.h b/Year 3/Internet of things/goam/main/buttons.h
index 7586973..71d306b 100644
--- a/Year 3/Internet of things/goam/main/buttons.h
+++ b/Year 3/Internet of things/goam/main/buttons.h
@@ -1,4 +1,5 @@
#pragma once
void buttons_init();
-void add_push_button(unsigned pin, void (*on_press)(), void (*off_press)());
+void add_push_button(unsigned pin, void (*on_press)());
+void press_push_button(int gpio_num);
diff --git a/Year 3/Internet of things/goam/main/main.c b/Year 3/Internet of things/goam/main/main.c
index 32a49a2..b785efe 100644
--- a/Year 3/Internet of things/goam/main/main.c
+++ b/Year 3/Internet of things/goam/main/main.c
@@ -9,6 +9,7 @@
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
+#include "freertos/timers.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "driver/gpio.h"
@@ -122,6 +123,35 @@ void main_store_invertion(int32_t value) {
display_invertion((enum Inversion)inv);
}
+static TimerHandle_t timelapse_timer = NULL;
+
+void main_store_timelapse_period(int32_t value) {
+ if (value < 10) {
+ ESP_LOGE(TAG, "Tried to set a timelapse period, that is less than 10s");
+ return;
+ }
+
+ nvs_write_i32("timelapse", pdMS_TO_TICKS(value * 1000));
+ if (xTimerChangePeriod(timelapse_timer, pdMS_TO_TICKS(value * 1000), 100) != pdPASS) {
+ ESP_LOGE(TAG, "Failed to change timer duration!");
+ }
+ if (xTimerStop(timelapse_timer, 100) != pdPASS) {
+ ESP_LOGE(TAG, "Failed to stop the timer afte duration change!");
+ }
+}
+
+void main_start_timelapse() {
+ if (xTimerStart(timelapse_timer, 100) != pdPASS) {
+ ESP_LOGE(TAG, "Failed to start the timer!");
+ }
+}
+
+void main_stop_timelapse() {
+ if (xTimerStop(timelapse_timer, 100) != pdPASS) {
+ ESP_LOGE(TAG, "Failed to stop the timer!");
+ }
+}
+
/*
* On button press
*/
@@ -158,6 +188,11 @@ static void take_photo() {
free(image);
}
+static void timelapse_callback(TimerHandle_t timer) {
+ press_push_button(BTN_SHOOT_PIN);
+ ESP_LOGI(TAG, "Taking timelapse photo");
+}
+
/*
* On boot
*/
@@ -194,7 +229,7 @@ void app_main(void)
// they're in a task or not
spiffs_init();
buttons_init();
- add_push_button(BTN_SHOOT_PIN, take_photo, NULL);
+ add_push_button(BTN_SHOOT_PIN, take_photo);
display_init();
display_printat(DCHAR_NO_CAMERA,
@@ -212,12 +247,15 @@ void app_main(void)
webserver_init();
wifi_launch(); // Automatically starts server too
+ int32_t time = 10000;
+ nvs_read_i32("timelapse", &time);
+ timelapse_timer = xTimerCreate("timelapse_timer", time, pdTRUE, (void*)0, timelapse_callback);
+
long unsigned int notification = 0;
while (!(notification & INIT_CAMERA_BIT)) {
xTaskNotifyWait(0, 0, &notification, 50 / portTICK_PERIOD_MS);
}
-
while (true) {
xTaskNotifyWait(ULONG_MAX, 0, &notification, 5000 / portTICK_PERIOD_MS);
}
diff --git a/Year 3/Internet of things/goam/main/main.h b/Year 3/Internet of things/goam/main/main.h
index 27eb2e3..ec8f1af 100644
--- a/Year 3/Internet of things/goam/main/main.h
+++ b/Year 3/Internet of things/goam/main/main.h
@@ -3,3 +3,7 @@
void main_store_saveimage(int32_t value);
void main_store_resolution(int32_t value);
void main_store_invertion(int32_t value);
+
+void main_store_timelapse_period(int32_t value);
+void main_start_timelapse();
+void main_stop_timelapse();
diff --git a/Year 3/Internet of things/goam/main/webserver.c b/Year 3/Internet of things/goam/main/webserver.c
index 9298b5b..1c23867 100644
--- a/Year 3/Internet of things/goam/main/webserver.c
+++ b/Year 3/Internet of things/goam/main/webserver.c
@@ -91,6 +91,38 @@ static const httpd_uri_t get_image = {
.handler = get_image_handler,
};
+static const char timelapse_started[] = "Timelapse started!";
+
+static esp_err_t get_start_timelapse_handler(httpd_req_t *req)
+{
+ main_start_timelapse();
+ httpd_resp_send(req, timelapse_started, sizeof(timelapse_started));
+
+ logi_get(req);
+ return ESP_OK;
+}
+static const httpd_uri_t get_start_timelapse = {
+ .uri = "/start_timelapse",
+ .method = HTTP_GET,
+ .handler = get_start_timelapse_handler,
+};
+
+static const char timelapse_stopped[] = "Timelapse stopped!";
+
+static esp_err_t get_stop_timelapse_handler(httpd_req_t *req)
+{
+ main_stop_timelapse();
+ httpd_resp_send(req, timelapse_stopped, sizeof(timelapse_stopped));
+
+ logi_get(req);
+ return ESP_OK;
+}
+static const httpd_uri_t get_stop_timelapse = {
+ .uri = "/stop_timelapse",
+ .method = HTTP_GET,
+ .handler = get_stop_timelapse_handler,
+};
+
static void logi_post(httpd_req_t *req) {
/* After sending the HTTP response the old HTTP request
* headers are lost. Check if HTTP request headers can be read now. */
@@ -186,6 +218,24 @@ static const httpd_uri_t post_invertion = {
.handler = post_invertion_handler,
};
+static esp_err_t post_timelapse_period_handler(httpd_req_t *req) {
+ char* buffer = malloc(req->content_len + 1);
+ httpd_req_recv(req, buffer, req->content_len);
+
+ main_store_timelapse_period((int32_t)atoi(strchr(buffer, '=') + 1));
+ free(buffer);
+
+ httpd_resp_send(req, "", 0);
+
+ logi_post(req);
+ return ESP_OK;
+}
+static const httpd_uri_t post_timelapse_period = {
+ .uri = "/timelapse_period",
+ .method = HTTP_POST,
+ .handler = post_timelapse_period_handler,
+};
+
static esp_err_t ws_camera_handler(httpd_req_t *req) {
if (req->method == HTTP_GET) {
ESP_LOGI(TAG, "Established websocket connection");
@@ -254,6 +304,7 @@ void webserver_start()
config.httpd.lru_purge_enable = true;
config.httpd.uri_match_fn = httpd_uri_match_wildcard;
config.httpd.max_open_sockets = MAX_CLIENTS;
+ config.httpd.max_uri_handlers = 16;
SET_EMBEDDED_PTR(config.servercert, config.servercert_len, cacert, "cacert_pem");
SET_EMBEDDED_PTR(config.prvtkey_pem, config.prvtkey_len, prvtkey, "prvtkey_pem");
@@ -267,10 +318,13 @@ void webserver_start()
httpd_register_uri_handler(server, &get_index);
httpd_register_uri_handler(server, &get_favicon);
httpd_register_uri_handler(server, &get_image);
+ httpd_register_uri_handler(server, &get_start_timelapse);
+ httpd_register_uri_handler(server, &get_stop_timelapse);
httpd_register_uri_handler(server, &post_network);
httpd_register_uri_handler(server, &post_imagesave);
httpd_register_uri_handler(server, &post_resolution);
httpd_register_uri_handler(server, &post_invertion);
+ httpd_register_uri_handler(server, &post_timelapse_period);
httpd_register_uri_handler(server, &ws_camera);
ESP_LOGI(TAG, "Started server on port %d", config.httpd.server_port);
diff --git a/Year 3/Internet of things/goam/webserver/index.html b/Year 3/Internet of things/goam/webserver/index.html
index 42e7e92..c43bdac 100644
--- a/Year 3/Internet of things/goam/webserver/index.html
+++ b/Year 3/Internet of things/goam/webserver/index.html
@@ -69,6 +69,20 @@ iframe {
<input class="button" type="submit" value="Save">
</form>
+ <h1>Configure timelapse</h1>
+ <form action="/timelapse_period" target="dummyframe" method="POST">
+ <input name="timelapse_period" type="number" placeholder="Timelapse period" min="10">
+ <input class="button" type="submit" value="Save">
+ </form>
+
+ <form action="/start_timelapse" target="dummyframe" method="GET">
+ <input class="button" type="submit" value="Start timelapse">
+ </form>
+
+ <form action="/stop_timelapse" target="dummyframe" method="GET">
+ <input class="button" type="submit" value="Stop timelapse">
+ </form>
+
<h1>Configure behaviour</h1>
<p><i>Beware, these values may not represent what the device is doing! To be certain, always check the display!</i></p>
<form action="/imagesave" target="dummyframe" method="POST">