#include "dht.h"
#include "wifi.h"
#include "http.h"
#include "tm1637.h"
#include <cJSON.h>
#include <rom/ets_sys.h>
const gpio_num_t FRQ_CLK = GPIO_NUM_12;
const gpio_num_t FRQ_DTA = GPIO_NUM_14;
const gpio_num_t DHT_CLK = GPIO_NUM_18;
const gpio_num_t DHT_DTA = GPIO_NUM_19;
const gpio_num_t HTTP_CLK = GPIO_NUM_22;
const gpio_num_t HTTP_DTA = GPIO_NUM_23;
static int servoFreq = 0;
static int servoPulseState = 0;
static int indoorTempF = 0;
static int outdoorTempF = 0;
static tm1637_led_t *http_display;
static tm1637_led_t *dht_display;
static tm1637_led_t *freq_display;
static char http_buffer [512];
static void http_error()
{
for(int i = 0; i < 4; ++i)
{
tm1637_set_segment_number(http_display, i, 14, false);
}
while(1)
{
for (int i = 0; i < 7 ; i++)
{
tm1637_set_brightness(http_display, i);
vTaskDelay(300 / portTICK_PERIOD_MS);
}
for (int i = 7; i > 0 ; i--)
{
tm1637_set_brightness(http_display, i);
vTaskDelay(300 / portTICK_PERIOD_MS);
}
}
}
static void dht_error()
{
for(int i = 0; i < 4; ++i)
{
tm1637_set_segment_number(dht_display, i, 14, false);
}
while(1)
{
for (int i = 0; i < 7 ; i++)
{
tm1637_set_brightness(dht_display, i);
vTaskDelay(300 / portTICK_PERIOD_MS);
}
for (int i = 7; i > 0 ; i--)
{
tm1637_set_brightness(dht_display, i);
vTaskDelay(300 / portTICK_PERIOD_MS);
}
}
}
static int read_dht()
{
float tempC, humidity;
if (dht_read_float_data(DHT_TYPE_AM2301, GPIO_NUM_2, &humidity, &tempC) != ESP_OK)
{
dht_error();
}
int tempF = (tempC * 1.8) + 32.0;
ESP_LOGI("main", "indoor temp celsius: %f", tempC);
ESP_LOGI("main", "indoor temp fahrenheit: %i", tempF);
return tempF;
}
static int get_temp(char* weather)
{
int tempC = 999;
const cJSON *temperature = NULL;
const cJSON *current_weather = NULL;
cJSON *weather_json = cJSON_Parse(weather);
if (weather_json == NULL)
{
const char *error_ptr = cJSON_GetErrorPtr();
if (error_ptr != NULL)
{
ESP_LOGE("main", "Error before: %s\n", error_ptr);
cJSON_Delete(weather_json);
http_error();
}
}
current_weather = cJSON_GetObjectItemCaseSensitive(weather_json, "current_weather");
temperature = cJSON_GetObjectItemCaseSensitive(current_weather, "temperature");
if (!cJSON_IsNumber(temperature))
{
cJSON_Delete(weather_json);
ESP_LOGE("main", "Temperature NaN");
http_error();
}
else
{
tempC = temperature->valuedouble;
ESP_LOGI("main", "Successfully parsed JSON response.");
}
cJSON_Delete(weather_json);
return tempC;
}
static void main_loop(void *pvParameters)
{
while(1)
{
http_params params = {
METEO_SERVER,
METEO_PORT,
METEO_REQUEST,
http_buffer,
512
};
if (http_request(params) == 0)
{
http_error();
}
int outdoorTempC = get_temp(http_buffer);
outdoorTempF = (outdoorTempC * 1.8) + 32.0;
ESP_LOGI("main", "outdoor temp celsius: %i", outdoorTempC);
ESP_LOGI("main", "outdoor temp fahrenheit: %i", outdoorTempF);
tm1637_set_number(http_display, outdoorTempF);
for(int countdown = 300; countdown >= 0; countdown--)
{
ESP_LOGI("main", "%d... ", countdown);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
}
static void calcFreq(void *pvParameters)
{
while(1)
{
int tempDiff = indoorTempF - outdoorTempF;
tempDiff = tempDiff < 0 ? 0 : tempDiff;
int newFreq = 500 + (tempDiff * 100);
newFreq = newFreq > 2500 ? 2500 : newFreq;
servoFreq = servoFreq < 500 ? 500 : servoFreq;
if (newFreq > servoFreq)
{
servoFreq++;
}
if (newFreq < servoFreq)
{
servoFreq--;
}
tm1637_set_number(freq_display, servoFreq);
vTaskDelay(1 / portTICK_PERIOD_MS);
}
}
static void dht(void *pvParameters)
{
while (1)
{
indoorTempF = read_dht();
tm1637_set_number(dht_display, indoorTempF);
vTaskDelay(5000 / portTICK_PERIOD_MS);
}
}
static void servo(void *pvParameters)
{
while(1)
{
gpio_set_level(GPIO_NUM_4, servoPulseState);
servoPulseState = servoPulseState == 0 ? 1 : 0;
ets_delay_us(servoFreq);
}
}
void app_main(void)
{
gpio_set_direction(GPIO_NUM_4, GPIO_MODE_OUTPUT);
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
{
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
wifi_init_sta();
http_display = tm1637_init(HTTP_CLK, HTTP_DTA);
dht_display = tm1637_init(DHT_CLK, DHT_DTA);
freq_display = tm1637_init(FRQ_CLK, FRQ_DTA);
tm1637_set_brightness(http_display, 5);
tm1637_set_brightness(dht_display, 5);
xTaskCreate(&main_loop, "main_loop", 4096, NULL, 5, NULL);
xTaskCreate(&calcFreq, "calcFreq", 4096, NULL, 5, NULL);
xTaskCreate(&servo, "servo", 4096, NULL, 5, NULL);
xTaskCreate(&dht, "dht", 4096, NULL, 5, NULL);
}