diff options
Diffstat (limited to 'main')
| -rw-r--r-- | main/component.mk | 0 | ||||
| -rw-r--r-- | main/dht.c | 121 | ||||
| -rw-r--r-- | main/dht.h | 10 | ||||
| -rw-r--r-- | main/main.c | 36 | ||||
| -rw-r--r-- | main/mqtt.c | 69 | ||||
| -rw-r--r-- | main/net.h | 10 | ||||
| -rw-r--r-- | main/wifi.c | 49 |
7 files changed, 295 insertions, 0 deletions
diff --git a/main/component.mk b/main/component.mk new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/main/component.mk diff --git a/main/dht.c b/main/dht.c new file mode 100644 index 0000000..669f797 --- /dev/null +++ b/main/dht.c @@ -0,0 +1,121 @@ +Copyright (c) 2015, SuperHouse Automation Pty Ltd +Copyright (c) 2016, Jonathan Hartsuiker (https://github.com/jsuiker) +Copyright (c) 2019, Fonger (https://github.com/fonger) + +#include <freertos/FreeRTOS.h> +#include <freertos/task.h> + +#include <driver/gpio.h> +#include <esp8266/gpio_struct.h> +#include <rom/ets_sys.h> +#include <esp_log.h> + +#include "dht.h" + +#define DHT_PIN GPIO_NUM_2 +#define DHT_DATA_LEN 40 + +static const char *tag = "dht"; + +static inline int dht_get_pin_state() +{ + return (GPIO.in >> DHT_PIN) & 0x1; +} + +static inline int dht_await_pin_state(int state, int timeout) +{ + int t; + static const uint16_t delta = 1; + + for (t = 0; t < timeout; t += delta) { + os_delay_us(delta); + if (dht_get_pin_state() == state) + return t; + } + return 0; +} + +static inline int dht_get_raw_data(uint8_t buf[DHT_DATA_LEN]) +{ + uint8_t i, pwl, pwh; + + gpio_set_level(DHT_PIN, 0); + os_delay_us(1100); + gpio_set_level(DHT_PIN, 1); + + if (!dht_await_pin_state(0, 40)) { + ESP_LOGI(tag, "start sequence phase 1 error"); + return 0; + } + if (!dht_await_pin_state(1, 80)) { + ESP_LOGI(tag, "start sequence phase 2 error"); + return 0; + } + if (!dht_await_pin_state(0, 80)) { + ESP_LOGI(tag, "start sequence phase 3 error"); + return 0; + } + + for (i = 0; i < DHT_DATA_LEN; i++) { + if (!(pwl = dht_await_pin_state(1, 50))) { + ESP_LOGI(tag, "low bit timed out"); + return 0; + } + if (!(pwh = dht_await_pin_state(0, 70))) { + ESP_LOGI(tag, "high bit timed out"); + return 0; + } + buf[i] = pwh > pwl; + } + return 1; +} + +static inline int dht_verify_checksum(const uint8_t data[5]) +{ + return data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF); +} + +int16_t dht_decode_data(uint8_t msb, uint8_t lsb) +{ + int16_t x; + + x = msb & 0x7F; + x <<= 8; + x |= lsb; + if (msb >> 7) + x = 0 - x; + return x; +} + +int dht_get_data(uint8_t result[5]) +{ + uint8_t i, rc, buf[DHT_DATA_LEN]; + + vPortETSIntrLock(); + rc = dht_get_raw_data(buf); + vPortETSIntrUnlock(); + + if (rc) { + for (i = 0; i < DHT_DATA_LEN; i++) { + result[i / 8] <<= 1; + result[i / 8] |= buf[i]; + } + if (dht_verify_checksum(result)) + return 1; + else + ESP_LOGI(tag, "checksum failed"); + } + return 0; +} + +void dht_init(void) +{ + gpio_config_t io_conf; + + io_conf.pin_bit_mask = 1UL << DHT_PIN; + io_conf.mode = GPIO_MODE_OUTPUT_OD; + gpio_config(&io_conf); + gpio_set_level(DHT_PIN, 1); + + vTaskDelay(1000 / portTICK_PERIOD_MS); +} diff --git a/main/dht.h b/main/dht.h new file mode 100644 index 0000000..483f2b4 --- /dev/null +++ b/main/dht.h @@ -0,0 +1,10 @@ +#ifndef DHT_H +#define DHT_H + +void dht_init(void); + +int dht_get_data(uint8_t result[5]); + +int16_t dht_decode_data(uint8_t msb, uint8_t lsb); + +#endif diff --git a/main/main.c b/main/main.c new file mode 100644 index 0000000..86e6256 --- /dev/null +++ b/main/main.c @@ -0,0 +1,36 @@ +#include <freertos/FreeRTOS.h> +#include <freertos/task.h> + +#include <esp_event.h> +#include <esp_netif.h> +#include <esp_log.h> + +#include "dht.h" +#include "net.h" + +static const char *tag = "app"; +static const char *topic = "weather-data"; + +void app_main() +{ + char data[5]; + uint16_t rh, tc; + esp_mqtt_client_handle_t client; + + esp_netif_init(); + esp_event_loop_create_default(); + + dht_init(); + wifi_connect(); + client = mqtt_connect(); + + for (;;) { + if (dht_get_data((uint8_t *)data)) { + rh = dht_decode_data(data[0], data[1]); + tc = dht_decode_data(data[2], data[3]); + esp_mqtt_client_publish(client, topic, data, 4, 0, 0); + ESP_LOGI(tag, "temperature: %dC, humidity: %d%%", tc, rh); + } + vTaskDelay(2000 / portTICK_PERIOD_MS); + } +} diff --git a/main/mqtt.c b/main/mqtt.c new file mode 100644 index 0000000..6a06aea --- /dev/null +++ b/main/mqtt.c @@ -0,0 +1,69 @@ +#include <freertos/FreeRTOS.h> +#include <freertos/task.h> +#include "freertos/event_groups.h" + +#include <esp_event.h> +#include <esp_netif.h> +#include <esp_log.h> + +#include "net.h" + +#define MQTT_CONNECTED_BIT BIT0 + +static const char *tag = "mqtt"; + +static EventGroupHandle_t mqtt_evt_group; + +static void mqtt_evt_handler(void *args, esp_event_base_t eb, int32_t evt_id, void *data) +{ + esp_mqtt_event_handle_t evt = (esp_mqtt_event_handle_t) data; + switch (evt_id) { + case MQTT_EVENT_CONNECTED: + ESP_LOGI(tag, "MQTT_EVENT_CONNECTED"); + xEventGroupSetBits(mqtt_evt_group, MQTT_CONNECTED_BIT); + break; + case MQTT_EVENT_PUBLISHED: + ESP_LOGI(tag, "MQTT_EVENT_PUBLISHED, msg_id=%d", evt->msg_id); + break; + default: + ESP_LOGI(tag, "MQTT event id:%d", evt->event_id); + break; + } +} + +esp_mqtt_client_handle_t mqtt_connect(void) +{ + esp_mqtt_client_handle_t client = NULL; + + const esp_mqtt_client_config_t cfg = { + .host = CONFIG_BROKER_HOST, + .username = CONFIG_BROKER_USERNAME, + .password = CONFIG_BROKER_PASSWORD, + .client_id = CONFIG_BROKER_CLIENT_ID, + .transport = MQTT_TRANSPORT_OVER_SSL, + .protocol_ver = MQTT_PROTOCOL_V_3_1_1 + }; + + if (!(client = esp_mqtt_client_init(&cfg))) { + ESP_LOGI(tag, "esp_mqtt_client_init() failed"); + return NULL; + } + + ESP_LOGI(tag, "MQTT broker: %s", cfg.host); + + esp_mqtt_client_register_event(client, + ESP_EVENT_ANY_ID, + mqtt_evt_handler, + client); + + mqtt_evt_group = xEventGroupCreate(); + ESP_ERROR_CHECK(esp_mqtt_client_start(client)); + + xEventGroupWaitBits(mqtt_evt_group, + MQTT_CONNECTED_BIT, + pdFALSE, + pdFALSE, + portMAX_DELAY); + + return client; +} diff --git a/main/net.h b/main/net.h new file mode 100644 index 0000000..622fd01 --- /dev/null +++ b/main/net.h @@ -0,0 +1,10 @@ +#ifndef NET_H +#define NET_H + +#include <mqtt_client.h> + +void wifi_connect(void); + +esp_mqtt_client_handle_t mqtt_connect(void); + +#endif diff --git a/main/wifi.c b/main/wifi.c new file mode 100644 index 0000000..a661de3 --- /dev/null +++ b/main/wifi.c @@ -0,0 +1,49 @@ +#include <freertos/FreeRTOS.h> +#include <freertos/task.h> +#include "freertos/event_groups.h" + +#include <esp_log.h> +#include <esp_wifi.h> + +#include "net.h" + +#define WIFI_CONNECTED_BIT BIT0 + +static EventGroupHandle_t wifi_evt_group; +static const char *tag = "wifi"; + +static void wifi_evt_handler(void *arg, esp_event_base_t eb, int32_t id, void *data) +{ + ip_event_got_ip_t *event = (ip_event_got_ip_t *) data; + ESP_LOGI(tag, "ip: %s", ip4addr_ntoa(&event->ip_info.ip)); + xEventGroupSetBits(wifi_evt_group, WIFI_CONNECTED_BIT); +} + +void wifi_connect(void) +{ + wifi_evt_group = xEventGroupCreate(); + + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + esp_wifi_init(&cfg); + + wifi_config_t wifi_config = { + .sta = { + .ssid = CONFIG_WIFI_SSID, + .password = CONFIG_WIFI_PASS, + .threshold.authmode = WIFI_AUTH_WPA2_PSK + }, + }; + esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config); + esp_wifi_set_mode(WIFI_MODE_STA); + + esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_evt_handler, 0); + + ESP_ERROR_CHECK(esp_wifi_start()); + ESP_ERROR_CHECK(esp_wifi_connect()); + + xEventGroupWaitBits(wifi_evt_group, + WIFI_CONNECTED_BIT, + pdFALSE, + pdFALSE, + portMAX_DELAY); +} |
