Files
SerreklimaatSensor/main/main.c
2026-04-24 23:36:36 +02:00

190 lines
5.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#include <stdio.h>
#include <inttypes.h>
#include <time.h>
#include <string.h>
#include <sys/time.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"
#include "esp_timer.h"
#include "driver/gpio.h"
// Define the GPIO pin for the DHT11 data line
#define DHT11_GPIO 0
void read_dht11(uint8_t *humidity_int, uint8_t *humidity_dec,
int8_t *temperature_int, uint8_t *temperature_dec,
uint8_t *checksum) {
uint8_t data[5] = {0};
// Send start signal: pull the line low for 20ms
gpio_set_direction(DHT11_GPIO, GPIO_MODE_OUTPUT);
gpio_set_level(DHT11_GPIO, 0);
vTaskDelay(pdMS_TO_TICKS(20));
// Release the line and wait for sensor response
gpio_set_level(DHT11_GPIO, 1);
gpio_set_direction(DHT11_GPIO, GPIO_MODE_INPUT);
// Wait for the sensor to pull the line low (~20-40us)
while (gpio_get_level(DHT11_GPIO) == 1) {
vTaskDelay(pdMS_TO_TICKS(0.1));
}
// Wait for the sensor to pull the line high (~80us)
while (gpio_get_level(DHT11_GPIO) == 0) {
vTaskDelay(pdMS_TO_TICKS(0.1));
}
// Read 40 bits of data
for (int i = 0; i < 40; i++) {
// Wait for the start of the bit (low for ~50us)
while (gpio_get_level(DHT11_GPIO) == 1) {
vTaskDelay(pdMS_TO_TICKS(0.1));
}
while (gpio_get_level(DHT11_GPIO) == 0) {
vTaskDelay(pdMS_TO_TICKS(0.1));
}
// Measure the length of the high pulse
uint32_t pulse_start = esp_timer_get_time();
while (gpio_get_level(DHT11_GPIO) == 1) {
vTaskDelay(pdMS_TO_TICKS(0.1));
}
uint32_t pulse_end = esp_timer_get_time();
// Determine if the bit is 0 or 1
uint8_t bit = (pulse_end - pulse_start) > 50 ? 1 : 0;
data[i / 8] <<= 1;
data[i / 8] |= bit;
}
// Parse the data
*humidity_int = data[0];
*humidity_dec = data[1]; // Decimal part (09)
*temperature_int = (data[2] & 0x7F); // Remove sign bit (050)
*temperature_dec = data[3]; // Decimal part (09)
*checksum = data[4];
// Validate checksum
uint8_t sum = *humidity_int + *humidity_dec + *temperature_int + *temperature_dec;
if (sum != *checksum) {
printf("Checksum failed! Retrying...\n");
vTaskDelay(pdMS_TO_TICKS(1000));
read_dht11(humidity_int, humidity_dec, temperature_int, temperature_dec, checksum);
}
}
void set_system_time_from_compiler() {
// Parse __DATE__: "Mmm dd yyyy"
char date[] = __DATE__;
char time[] = __TIME__;
struct tm tm = {0};
char month[4];
int day, year;
int hour, min, sec;
// Parse date
sscanf(date, "%3s %d %d", month, &day, &year);
// Parse time
sscanf(time, "%d:%d:%d", &hour, &min, &sec);
// Convert month abbreviation to number
const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
for (int i = 0; i < 12; i++) {
if (strcmp(month, months[i]) == 0) {
tm.tm_mon = i;
break;
}
}
tm.tm_mday = day;
tm.tm_year = year - 1900; // Years since 1900
tm.tm_hour = hour;
tm.tm_min = min;
tm.tm_sec = sec;
tm.tm_isdst = -1; // Let system determine daylight saving time
// Set system time
struct timeval tv = { .tv_sec = mktime(&tm), .tv_usec = 0 };
settimeofday(&tv, NULL);
}
void print_current_time() {
time_t now;
struct tm timeinfo;
char strftime_buf[64];
time(&now);
localtime_r(&now, &timeinfo);
strftime(strftime_buf, sizeof(strftime_buf), "%Y-%m-%d %H:%M:%S", &timeinfo);
printf("Time: %s\n", strftime_buf);
}
void print_chip_info(){
/* Print chip information */
esp_chip_info_t chip_info;
uint32_t flash_size;
esp_chip_info(&chip_info);
printf("This is %s chip with %d CPU core(s), %s%s%s%s, ",
CONFIG_IDF_TARGET,
chip_info.cores,
(chip_info.features & CHIP_FEATURE_WIFI_BGN) ? "WiFi/" : "",
(chip_info.features & CHIP_FEATURE_BT) ? "BT" : "",
(chip_info.features & CHIP_FEATURE_BLE) ? "BLE" : "",
(chip_info.features & CHIP_FEATURE_IEEE802154) ? ", 802.15.4 (Zigbee/Thread)" : "");
unsigned major_rev = chip_info.revision / 100;
unsigned minor_rev = chip_info.revision % 100;
printf("silicon revision v%d.%d, ", major_rev, minor_rev);
if(esp_flash_get_size(NULL, &flash_size) != ESP_OK) {
printf("Get flash size failed");
return;
}
printf("%" PRIu32 "MB %s flash\n", flash_size / (uint32_t)(1024 * 1024),
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");
printf("Minimum free heap size: %" PRIu32 " bytes\n", esp_get_minimum_free_heap_size());
}
void app_main(void)
{
set_system_time_from_compiler();
printf("DHT11 temperature and humidity sensor read and send out\n");
print_chip_info();
while (1) {
uint8_t humidity_int, humidity_dec, checksum;
int8_t temperature_int;
uint8_t temperature_dec;
read_dht11(&humidity_int, &humidity_dec, &temperature_int, &temperature_dec, &checksum);
// Calculate humidity and temperature
float humidity = (float)humidity_int + (float)humidity_dec / 10.0f;
float temperature = (float)temperature_int + (float)temperature_dec / 10.0f;
// Print results
print_current_time();
printf("Humidity: %.1f%%\n", humidity);
printf("Temperature: %.1f°C\n", temperature);
printf("Checksum valid: %s\n", (checksum == (humidity_int + humidity_dec + temperature_int + temperature_dec)) ? "Yes" : "No");
// Wait 1 minute before next read
vTaskDelay(pdMS_TO_TICKS(5000));
}
}