dacowars 1 сар өмнө
commit
471ff518fc

+ 2 - 0
.clangd

@@ -0,0 +1,2 @@
+CompileFlags:
+    Remove: [-f*, -m*]

+ 13 - 0
.devcontainer/Dockerfile

@@ -0,0 +1,13 @@
+ARG DOCKER_TAG=latest
+FROM espressif/idf:${DOCKER_TAG}
+
+ENV LC_ALL=C.UTF-8
+ENV LANG=C.UTF-8
+
+RUN apt-get update -y && apt-get install udev -y
+
+RUN echo "source /opt/esp/idf/export.sh > /dev/null 2>&1" >> ~/.bashrc
+
+ENTRYPOINT [ "/opt/esp/entrypoint.sh" ]
+
+CMD ["/bin/bash", "-c"]

+ 19 - 0
.devcontainer/devcontainer.json

@@ -0,0 +1,19 @@
+{
+	"name": "ESP-IDF QEMU",
+	"build": {
+		"dockerfile": "Dockerfile"
+	},
+	"customizations": {
+		"vscode": {
+			"settings": {
+				"terminal.integrated.defaultProfile.linux": "bash",
+				"idf.gitPath": "/usr/bin/git"
+			},
+			"extensions": [
+				"espressif.esp-idf-extension",
+				"espressif.esp-idf-web"
+			]
+		}
+	},
+	"runArgs": ["--privileged"]
+}

+ 78 - 0
.gitignore

@@ -0,0 +1,78 @@
+# macOS
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Directory metadata
+.directory
+
+# Temporary files
+*~
+*.swp
+*.swo
+*.bak
+*.tmp
+
+# Log files
+*.log
+
+# Build artifacts and directories
+**/build/
+build/
+*.o
+*.a
+*.out
+*.exe # For any host-side utilities compiled on Windows
+
+# ESP-IDF specific build outputs
+*.bin
+*.elf
+*.map
+flasher_args.json # Generated in build directory
+sdkconfig.old
+sdkconfig
+
+# ESP-IDF dependencies
+# For older versions or manual component management
+/components/.idf/
+**/components/.idf/
+# For modern ESP-IDF component manager
+managed_components/
+# If ESP-IDF tools are installed/referenced locally to the project
+.espressif/
+
+# CMake generated files
+CMakeCache.txt
+CMakeFiles/
+cmake_install.cmake
+install_manifest.txt
+CTestTestfile.cmake
+
+# Python environment files
+*.pyc
+*.pyo
+*.pyd
+__pycache__/
+*.egg-info/
+dist/
+
+# Virtual environment folders
+venv/
+.venv/
+env/
+
+# Language Servers
+.clangd/
+.ccls-cache/
+compile_commands.json
+
+# Windows specific
+Thumbs.db
+ehthumbs.db
+Desktop.ini
+
+# User-specific configuration files
+*.user
+*.workspace # General workspace files, can be from various tools
+*.suo       # Visual Studio Solution User Options
+*.sln.docstates # Visual Studio

+ 23 - 0
.vscode/c_cpp_properties.json

@@ -0,0 +1,23 @@
+{
+  "configurations": [
+    {
+      "name": "ESP-IDF",
+      "compilerPath": "/Users/daniel/.espressif/tools/xtensa-esp-elf/esp-14.2.0_20251107/xtensa-esp-elf/bin/xtensa-esp32-elf-gcc",
+      "compileCommands": "${workspaceFolder}/build/compile_commands.json",
+      "includePath": [
+        "${workspaceFolder}/**"
+      ],
+      "browse": {
+        "path": [
+          "${workspaceFolder}/**"
+        ],
+        "limitSymbolsToIncludedHeaders": true
+      },
+      "defines": [],
+      "cStandard": "c17",
+      "cppStandard": "c++17",
+      "intelliSenseMode": "gcc-x64"
+    }
+  ],
+  "version": 4
+}

+ 10 - 0
.vscode/launch.json

@@ -0,0 +1,10 @@
+{
+  "version": "0.2.0",
+  "configurations": [
+    {
+      "type": "gdbtarget",
+      "request": "attach",
+      "name": "Eclipse CDT GDB Adapter"
+    }
+  ]
+}

+ 18 - 0
.vscode/settings.json

@@ -0,0 +1,18 @@
+{
+  "C_Cpp.intelliSenseEngine": "default",
+  "idf.openOcdConfigs": [
+    "board/esp32-wrover-kit-3.3v.cfg"
+  ],
+  "idf.port": "/dev/tty.usbserial-110",
+  "idf.currentSetup": "/Users/daniel/.espressif/v5.5.3/esp-idf",
+  "idf.customExtraVars": {
+    "IDF_TARGET": "esp32"
+  },
+  "clangd.path": "/Users/daniel/.espressif/tools/esp-clang/esp-19.1.2_20250312/esp-clang/bin/clangd",
+  "clangd.arguments": [
+    "--background-index",
+    "--query-driver=**",
+    "--compile-commands-dir=/Users/daniel/Documents/Proyectos/dht22/build"
+  ],
+  "idf.flashType": "UART"
+}

+ 6 - 0
CMakeLists.txt

@@ -0,0 +1,6 @@
+# The following five lines of boilerplate have to be in your project's
+# CMakeLists in this exact order for cmake to work correctly
+cmake_minimum_required(VERSION 3.16)
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+project(dht22)

+ 2 - 0
main/CMakeLists.txt

@@ -0,0 +1,2 @@
+idf_component_register(SRCS "main.c"
+                    INCLUDE_DIRS ".")

+ 129 - 0
main/main.c

@@ -0,0 +1,129 @@
+#include <stdio.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "driver/gpio.h"
+#include "esp_rom_sys.h"
+#include "esp_log.h"
+
+#define DHT_PIN GPIO_NUM_4
+#define US_DELAY 3
+#define DHT_DATA_BITS 40
+
+static const char *TAG = "DHT22";
+
+// Macro to check the return value of a function and log an error if it is not ESP_OK
+#define CHECK_LOGE(x, msg, ...) do { \
+        esp_err_t __; \
+        if ((__ = x) != ESP_OK) { \
+            portEXIT_CRITICAL(&mux); \
+            ESP_LOGE(TAG, msg, ## __VA_ARGS__); \
+            return __; \
+        } \
+    } while (0)
+
+gpio_num_t dht_pin = DHT_PIN;
+
+static portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
+
+static esp_err_t dht_attach_pin(gpio_num_t pin){
+    if (pin < GPIO_NUM_0 || pin >= GPIO_NUM_MAX) {
+        ESP_LOGE(TAG, "Invalid GPIO pin number: %d", pin);
+        return ESP_ERR_INVALID_ARG;
+    }
+    gpio_set_direction(pin, GPIO_MODE_INPUT_OUTPUT_OD);
+    gpio_set_level(pin, 1); // Set the pin high by default
+    return ESP_OK;
+}
+
+static esp_err_t get_change_time(gpio_num_t pin, uint8_t timeout_us, bool expected_level, uint32_t *time_us){
+    *time_us = 0;
+    while (*time_us < timeout_us){
+        if (gpio_get_level(pin) == expected_level) {
+            return ESP_OK;
+        }
+        *time_us += US_DELAY;
+        esp_rom_delay_us(US_DELAY);
+    }
+    return ESP_ERR_TIMEOUT;
+}
+
+static inline esp_err_t dht_communication(gpio_num_t pin, uint32_t *data){
+    uint32_t high_time;
+    uint32_t low_time;
+    uint8_t checksum;
+
+    // Send start signal
+    gpio_set_direction(pin, GPIO_MODE_INPUT_OUTPUT_OD);
+    gpio_set_level(pin, 0);
+    esp_rom_delay_us(1500); // Pull low for at least 1ms
+    gpio_set_level(pin, 1); // Release the line
+
+    CHECK_LOGE(get_change_time(pin, 40, 1, &low_time), "Failed to get dht response"); // Wait for the sensor to pull low 20-40us
+    CHECK_LOGE(get_change_time(pin, 80, 0, &high_time), "Failed to get dht response"); // Wait for the sensor to pull high 80us
+    CHECK_LOGE(get_change_time(pin, 80, 1, &low_time), "Failed to get dht response"); // Wait for the sensor to pull low 80us
+
+    for (uint8_t i = DHT_DATA_BITS; i > 0; i--){
+        
+        // Wait for the sensor to pull low 50us
+        CHECK_LOGE(get_change_time(pin, 50, 0, &low_time), "Failed dht transmission"); 
+        
+        // Wait for the sensor to pull high 26-28us for 0 and 70us for 1
+        CHECK_LOGE(get_change_time(pin, 70, 1, &high_time), "Failed dht transmission"); 
+
+        if (i < 9){
+            checksum |= (high_time > low_time) << (i - 1);
+        }
+        else {
+            *data |= (high_time > low_time) << (i - 9);
+        }
+
+    }
+
+    if (checksum != ((uint8_t)(*data >> 24) + (uint8_t)(*data >> 16) + (uint8_t)(*data >> 8) + (uint8_t)(*data))) {
+        ESP_LOGE(TAG, "DHT22 checksum mismatch");
+        return ESP_ERR_INVALID_CRC;
+    }
+
+    return ESP_OK;
+}
+
+
+esp_err_t dht_read(gpio_num_t pin, float *temperature, float *humidity){
+    uint32_t data;
+
+    gpio_set_direction(pin, GPIO_MODE_INPUT_OUTPUT_OD);
+    gpio_set_level(pin, 1); 
+
+    portENTER_CRITICAL(&mux);
+    CHECK_LOGE(dht_communication(pin, &data), "Failed to read dht data");
+    portEXIT_CRITICAL(&mux);
+
+    gpio_set_direction(pin, GPIO_MODE_INPUT_OUTPUT_OD);
+    gpio_set_level(pin, 1); 
+
+    *humidity = ((int16_t)(data >> 16)) / 10.0;
+    *temperature = ((int16_t)(data & 0xFFFF)) / 10.0;
+    return ESP_OK;
+}
+
+void app_main(void)
+{
+    float temperature;
+    float humidity;
+    esp_err_t err = dht_attach_pin(dht_pin);
+    if (err != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to attach DHT pin: %s", esp_err_to_name(err));
+        vTaskDelay(pdMS_TO_TICKS(5000)); // Wait for 5 seconds before retrying
+        return;
+    }
+
+    while (1) {
+        if (dht_read(dht_pin, &temperature, &humidity) == ESP_OK) {
+            ESP_LOGI(TAG, "Temperature: %.1f°C, Humidity: %.1f%%", temperature, humidity);
+        } else {
+            ESP_LOGE(TAG, "Failed to read from DHT22 sensor");
+        }
+        vTaskDelay(pdMS_TO_TICKS(5000)); // Wait for 5 seconds before the next reading
+    }
+
+}