🎉 First WIP-prototype of ESP32 based nightlight
This commit is contained in:
parent
43bbdcc34f
commit
9972cb5bea
6 changed files with 188 additions and 0 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -6,3 +6,9 @@ build/
|
|||
sdkconfig
|
||||
sdkconfig.old
|
||||
|
||||
# added
|
||||
managed_components/
|
||||
dependencies.lock
|
||||
|
||||
# customn
|
||||
tags
|
||||
|
|
6
CMakeLists.txt
Normal file
6
CMakeLists.txt
Normal file
|
@ -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(nightlight)
|
21
dependencies.lock
Normal file
21
dependencies.lock
Normal file
|
@ -0,0 +1,21 @@
|
|||
dependencies:
|
||||
espressif/led_strip:
|
||||
component_hash: b578eb926d9f6402fd45398b53c9bd5d1b7a15c1b2974d25aa3088e6c79b0b4c
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.0'
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
version: 3.0.1
|
||||
idf:
|
||||
source:
|
||||
type: idf
|
||||
version: 5.4.1
|
||||
direct_dependencies:
|
||||
- espressif/led_strip
|
||||
- idf
|
||||
manifest_hash: a51dc977be7137e0c5d12a067d1d573535d49f17e9bfa487be8f8b97cf684d41
|
||||
target: esp32c3
|
||||
version: 2.0.0
|
2
main/CMakeLists.txt
Normal file
2
main/CMakeLists.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
idf_component_register(SRCS "nightlight.c"
|
||||
INCLUDE_DIRS ".")
|
17
main/idf_component.yml
Normal file
17
main/idf_component.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
## Required IDF version
|
||||
idf:
|
||||
version: '>=4.1.0'
|
||||
# # Put list of dependencies here
|
||||
# # For components maintained by Espressif:
|
||||
# component: "~1.0.0"
|
||||
# # For 3rd party components:
|
||||
# username/component: ">=1.0.0,<2.0.0"
|
||||
# username2/component2:
|
||||
# version: "~1.0.0"
|
||||
# # For transient dependencies `public` flag can be set.
|
||||
# # `public` flag doesn't have an effect dependencies of the `main` component.
|
||||
# # All dependencies of `main` are public by default.
|
||||
# public: true
|
||||
espressif/led_strip: ^3.0.1
|
136
main/nightlight.c
Normal file
136
main/nightlight.c
Normal file
|
@ -0,0 +1,136 @@
|
|||
#include <stdio.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/timers.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
#include "led_strip.h"
|
||||
|
||||
#define LED_STRIP_PIN 2 // WS281x
|
||||
#define PIR_PIN 3 // AM312 or other 3,7V compatible PIR sensors
|
||||
#define LIGHT_SENSOR_PIN 4 // Digitale light sensor
|
||||
#define NUM_LEDS 15 // Number of LEDs on LED strip
|
||||
#define TIMEOUT_MS 10000 // Inactivity timeout (10 seconds)
|
||||
|
||||
|
||||
static const char *TAG = "NIGHTLIGHT";
|
||||
led_strip_handle_t strip;
|
||||
TimerHandle_t off_timer;
|
||||
TaskHandle_t led_task_handle = NULL;
|
||||
|
||||
// Turn off all LEDs
|
||||
void turn_off_leds()
|
||||
{
|
||||
for (int i = 0; i < NUM_LEDS; i++) {
|
||||
led_strip_set_pixel(strip, i, 0, 0, 0);
|
||||
led_strip_refresh(strip);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
ESP_LOGI(TAG, "LEDs turned OFF");
|
||||
}
|
||||
|
||||
// Turn on LEDs
|
||||
void turn_on_leds()
|
||||
{
|
||||
for (int i = 0; i < NUM_LEDS; i++) {
|
||||
led_strip_set_pixel(strip, i, 255, 7, 0); // red
|
||||
led_strip_refresh(strip);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
ESP_LOGI(TAG, "LEDs turned ON");
|
||||
}
|
||||
|
||||
// Timer callback: turns off LED if no motion is detected
|
||||
void off_timer_callback(TimerHandle_t xTimer)
|
||||
{
|
||||
if (gpio_get_level(PIR_PIN) == 1) {
|
||||
ESP_LOGI(TAG, "Motion still detected. Resetting off timer.");
|
||||
xTimerReset(off_timer, 0);
|
||||
} else {
|
||||
// No motion detected, it's safe to turn off LEDs
|
||||
turn_off_leds();
|
||||
}
|
||||
}
|
||||
|
||||
// PIR interrupt handler notifies LED task handler
|
||||
void IRAM_ATTR pir_isr_handler(void *arg)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
vTaskNotifyGiveFromISR(led_task_handle, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
// LED task
|
||||
void led_task(void *arg)
|
||||
{
|
||||
while (1) {
|
||||
// wait for motion
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
|
||||
ESP_LOGI(TAG, "Motion detected!");
|
||||
|
||||
// Reset off timer and turn on LEDs
|
||||
xTimerReset(off_timer, 0);
|
||||
|
||||
// TODO: check light sensor GPIO value
|
||||
turn_on_leds();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "Nightlight initializing...");
|
||||
|
||||
// Initialize LED strip
|
||||
led_strip_config_t strip_config = {
|
||||
.strip_gpio_num = LED_STRIP_PIN,
|
||||
.max_leds = NUM_LEDS,
|
||||
.flags.invert_out = false,
|
||||
};
|
||||
|
||||
led_strip_rmt_config_t rmt_config = {
|
||||
.clk_src = RMT_CLK_SRC_DEFAULT,
|
||||
.resolution_hz = 10 * 1000 * 1000, // 10MHz
|
||||
.mem_block_symbols = 64,
|
||||
.flags.with_dma = false,
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &strip));
|
||||
ESP_ERROR_CHECK(led_strip_clear(strip));
|
||||
ESP_LOGI(TAG, "LED strip initialized");
|
||||
|
||||
// Configure PIR sensor GPIO
|
||||
gpio_config_t pir_conf = {
|
||||
.intr_type = GPIO_INTR_POSEDGE,
|
||||
.mode = GPIO_MODE_INPUT,
|
||||
.pull_down_en = GPIO_PULLDOWN_ENABLE,
|
||||
.pull_up_en = GPIO_PULLUP_DISABLE,
|
||||
.pin_bit_mask = (1ULL << PIR_PIN)
|
||||
};
|
||||
ESP_ERROR_CHECK(gpio_config(&pir_conf));
|
||||
ESP_LOGI(TAG, "GPIO config for PIR sensor initialized");
|
||||
|
||||
// Configure light sensor GPIO
|
||||
gpio_config_t light_conf = {
|
||||
.mode = GPIO_MODE_INPUT,
|
||||
.pull_up_en = GPIO_PULLUP_DISABLE,
|
||||
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||
.pin_bit_mask = (1ULL << LIGHT_SENSOR_PIN)
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(gpio_config(&light_conf));
|
||||
ESP_LOGI(TAG, "GPIO config for light sensor initialized");
|
||||
|
||||
ESP_ERROR_CHECK(gpio_install_isr_service(0));
|
||||
ESP_ERROR_CHECK(gpio_isr_handler_add(PIR_PIN, pir_isr_handler, NULL));
|
||||
|
||||
// Timer setup
|
||||
off_timer = xTimerCreate("off_timer", pdMS_TO_TICKS(TIMEOUT_MS), pdFALSE, NULL, off_timer_callback);
|
||||
|
||||
// LED task setup
|
||||
xTaskCreate(led_task, "led_task", 2048, NULL, 10, &led_task_handle);
|
||||
|
||||
ESP_LOGI(TAG, "System initialized.");
|
||||
vTaskSuspend(NULL); // Suspend main task
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue