From 1fd97b74dce8318d9d0d7367896dbe3b21823d65 Mon Sep 17 00:00:00 2001 From: Christian Segundo Date: Tue, 4 Apr 2023 18:33:04 +0200 Subject: first commit --- src/main.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/wifi.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/wifi.h | 4 +++ 3 files changed, 189 insertions(+) create mode 100644 src/main.c create mode 100644 src/wifi.c create mode 100644 src/wifi.h (limited to 'src') diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..4908709 --- /dev/null +++ b/src/main.c @@ -0,0 +1,92 @@ +#include "esp_http_client.h" +#include "esp_sleep.h" +#include "lwip/netdb.h" +#include "wifi.h" +#include +#include + +#define ST(A) #A +#define STR(A) ST(A) + +#ifndef MAX_SENSOR_COUNT +#define MAX_SENSOR_COUNT 10 +#endif + +#ifndef TEMPERATURE_SENSOR_PIN +#define TEMPERATURE_SENSOR_PIN GPIO_NUM_17 +#endif + +static float temps[MAX_SENSOR_COUNT]; + +esp_err_t _http_event_handler(esp_http_client_event_t *evt) { return ESP_OK; } + +void app_main() { + const int wakeup_time_sec = 900; + const wifi_sta_config_t wifi_config = { + .ssid = STR(WIFI_SSID), + .password = STR(WIFI_PASS), + }; + + ds18x20_addr_t addrs[MAX_SENSOR_COUNT]; + size_t sensor_count = 0; + + gpio_config_t io_conf = {}; + io_conf.pin_bit_mask = (1ULL << TEMPERATURE_SENSOR_PIN); + io_conf.mode = GPIO_MODE_INPUT; + io_conf.intr_type = GPIO_INTR_DISABLE; + io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; + io_conf.pull_up_en = GPIO_PULLUP_DISABLE; + gpio_config(&io_conf); + + ESP_ERROR_CHECK(ds18x20_scan_devices(TEMPERATURE_SENSOR_PIN, addrs, + MAX_SENSOR_COUNT, &sensor_count)); + printf("Found %d sensors\n", sensor_count); + + ESP_ERROR_CHECK(wifi_init(&wifi_config)); + + esp_http_client_config_t config = { + .host = STR(PUSH_GATEWAY_HOST), + .port = PUSH_GATEWAY_PORT, + .path = "/metrics/job/ds1820", + .transport_type = HTTP_TRANSPORT_OVER_TCP, + .event_handler = _http_event_handler, + }; + + esp_http_client_handle_t client = esp_http_client_init(&config); + + ds18x20_measure_and_read_multi(TEMPERATURE_SENSOR_PIN, addrs, sensor_count, + temps); + for (int i = 0; i < sensor_count; i++) { + char *post_data; + char *url; + + if (0 > asprintf(&post_data, + "# TYPE ds1820_sensor " + "gauge\nds1820_sensor %f\n", + temps[i])) { + free(post_data); + goto sleep; + } + + if (0 > asprintf(&url, "/metrics/job/ds1820/addr/%08x", (uint32_t)addrs[i])) { + free(post_data); + free(url); + goto sleep; + } + + printf("Sensor: %08x - %fC\n", (uint32_t)addrs[i], temps[i]); + + esp_http_client_set_url(client, url); + esp_http_client_set_method(client, HTTP_METHOD_POST); + esp_http_client_set_post_field(client, post_data, strlen(post_data)); + esp_http_client_perform(client); + free(post_data); + free(url); + } + +sleep: + esp_http_client_cleanup(client); + _wifi_deinit(); + esp_sleep_enable_timer_wakeup(wakeup_time_sec * 1000000); + esp_deep_sleep_start(); +} diff --git a/src/wifi.c b/src/wifi.c new file mode 100644 index 0000000..593cf72 --- /dev/null +++ b/src/wifi.c @@ -0,0 +1,93 @@ +#include "esp_log.h" +#include "esp_wifi.h" +#include "freertos/event_groups.h" +#include "nvs_flash.h" + +/* FreeRTOS event group to signal when we are connected*/ +static EventGroupHandle_t s_wifi_event_group; + +/* The event group allows multiple bits for each event, but we only care about + * two events: + * - we are connected to the AP with an IP + * - we failed to connect after the maximum amount of retries */ +#define WIFI_CONNECTED_BIT BIT0 +#define WIFI_FAIL_BIT BIT1 + +static const char *TAG = "wifi"; + +static int s_retry_num = 0; +static int s_retry_max = 0; + +static void event_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) { + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { + esp_wifi_connect(); + } else if (event_base == WIFI_EVENT && + event_id == WIFI_EVENT_STA_DISCONNECTED) { + if (s_retry_num < s_retry_max) { + esp_wifi_connect(); + s_retry_num++; + ESP_LOGI(TAG, "retry to connect to the AP"); + } else { + xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); + } + ESP_LOGI(TAG, "connect to the AP fail"); + } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { + ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; + ESP_LOGI(TAG, "IP:" IPSTR, IP2STR(&event->ip_info.ip)); + s_retry_num = 0; + xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); + } +} + +esp_err_t _wifi_deinit(void) { return esp_wifi_stop(); } + +esp_err_t wifi_init(wifi_sta_config_t const *sta_config, uint8_t retries) { + esp_event_handler_instance_t instance_any_id; + esp_event_handler_instance_t instance_got_ip; + wifi_config_t wifi_config = {.sta = *sta_config}; + + s_retry_max = retries; + + ESP_ERROR_CHECK(nvs_flash_init()); + ESP_ERROR_CHECK(esp_netif_init()); + + ESP_LOGI(TAG, "SSID: '%s'", sta_config->ssid); + ESP_LOGI(TAG, "PASS: '%s'", sta_config->password); + + s_wifi_event_group = xEventGroupCreate(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + esp_netif_create_default_wifi_sta(); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + + ESP_ERROR_CHECK(esp_event_handler_instance_register( + WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, &instance_any_id)); + ESP_ERROR_CHECK(esp_event_handler_instance_register( + IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance_got_ip)); + + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); + + /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or + * connection failed for the maximum number of re-tries (WIFI_FAIL_BIT). The + * bits are set by event_handler() (see above) */ + EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, + WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, + pdFALSE, pdFALSE, portMAX_DELAY); + + /* xEventGroupWaitBits() returns the bits before the call returned, hence we + * can test which event actually happened. */ + if (bits & WIFI_CONNECTED_BIT) { + ESP_LOGI(TAG, "CONNECTED"); + return ESP_OK; + } else if (bits & WIFI_FAIL_BIT) { + ESP_LOGI(TAG, "FAIL TO CONNECT"); + return ESP_FAIL; + } else { + ESP_LOGE(TAG, "UNEXPECTED EVENT"); + return ESP_FAIL; + } +} diff --git a/src/wifi.h b/src/wifi.h new file mode 100644 index 0000000..8898a4b --- /dev/null +++ b/src/wifi.h @@ -0,0 +1,4 @@ +#include "esp_wifi.h" + +esp_err_t wifi_init(wifi_sta_config_t const *sta_config); +esp_err_t _wifi_deinit(void); -- cgit v1.2.3