mirror of
https://github.com/MrUnknownDE/OpenIris-ESPIDF.git
synced 2026-04-12 11:13:44 +02:00
Add led manager with support for Babble boards
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
idf_component_register(SRCS "Helpers/helpers.cpp"
|
||||
INCLUDE_DIRS "helpers"
|
||||
REQUIRES esp_timer
|
||||
)
|
||||
@@ -77,4 +77,9 @@ std::vector<std::string> Helpers::split(const std::string &s, char delimiter)
|
||||
parts.push_back(part);
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
int64_t Helpers::getTimeInMillis()
|
||||
{
|
||||
return (esp_timer_get_time() / 1000);
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
#ifndef HELPERS_HPP
|
||||
#define HELPERS_HPP
|
||||
#include "esp_timer.h"
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
@@ -31,6 +33,8 @@ namespace Helpers
|
||||
std::snprintf(buf.get(), size, format.c_str(), args...);
|
||||
return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
|
||||
}
|
||||
|
||||
int64_t getTimeInMillis();
|
||||
}
|
||||
|
||||
#endif // HELPERS_HPP
|
||||
|
||||
4
components/LEDManager/CMakeLists.txt
Normal file
4
components/LEDManager/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
idf_component_register(SRCS "LEDManager/LEDManager.cpp"
|
||||
INCLUDE_DIRS "LEDManager"
|
||||
REQUIRES StateManager driver esp_driver_ledc Helpers
|
||||
)
|
||||
161
components/LEDManager/LEDManager/LEDManager.cpp
Normal file
161
components/LEDManager/LEDManager/LEDManager.cpp
Normal file
@@ -0,0 +1,161 @@
|
||||
#include "LEDManager.hpp"
|
||||
|
||||
const char *LED_MANAGER_TAG = "[LED_MANAGER]";
|
||||
|
||||
LEDManager::ledStateMap_t LEDManager::ledStateMap = {
|
||||
{LEDStates_e::_LedStateNone, {{0, 500}}},
|
||||
{LEDStates_e::_Improv_Error,
|
||||
{{1, 1000}, {0, 500}, {0, 1000}, {0, 500}, {1, 1000}}},
|
||||
{LEDStates_e::_Improv_Start,
|
||||
{{1, 500}, {0, 300}, {0, 300}, {0, 300}, {1, 500}}},
|
||||
{LEDStates_e::_Improv_Stop,
|
||||
{{1, 300}, {0, 500}, {0, 500}, {0, 500}, {1, 300}}},
|
||||
{LEDStates_e::_Improv_Processing,
|
||||
{{1, 200}, {0, 100}, {0, 500}, {0, 100}, {1, 200}}},
|
||||
{LEDStates_e::_WebServerState_Error,
|
||||
{{1, 200}, {0, 100}, {0, 500}, {0, 100}, {1, 200}}},
|
||||
{LEDStates_e::_WiFiState_Error,
|
||||
{{1, 200}, {0, 100}, {0, 500}, {0, 100}, {1, 200}}},
|
||||
{LEDStates_e::_MDNSState_Error,
|
||||
{{1, 200},
|
||||
{0, 100},
|
||||
{1, 200},
|
||||
{0, 100},
|
||||
{0, 500},
|
||||
{0, 100},
|
||||
{1, 200},
|
||||
{0, 100},
|
||||
{1, 200}}},
|
||||
{LEDStates_e::_Camera_Error,
|
||||
{{1, 5000}}}, // this also works as a more general error - something went
|
||||
// critically wrong? We go here
|
||||
{LEDStates_e::_WiFiState_Connecting, {{1, 100}, {0, 100}}},
|
||||
{LEDStates_e::_WiFiState_Connected,
|
||||
{{1, 100},
|
||||
{0, 100},
|
||||
{1, 100},
|
||||
{0, 100},
|
||||
{1, 100},
|
||||
{0, 100},
|
||||
{1, 100},
|
||||
{0, 100},
|
||||
{1, 100},
|
||||
{0, 100}}}};
|
||||
|
||||
std::vector<LEDStates_e> LEDManager::keepAliveStates = {
|
||||
LEDStates_e::_WebServerState_Error, LEDStates_e::_Camera_Error};
|
||||
|
||||
LEDManager::LEDManager(gpio_num_t pin) : blink_led_pin(pin), state(false) {}
|
||||
|
||||
#ifdef USE_ILLUMNATIOR_PIN
|
||||
LEDManager::LEDManager(gpio_num_t pin, gpio_num_t illumninator_led_pin) : blink_led_pin(pin), illumninator_led_pin(illumninator_led_pin) state(false) {}
|
||||
#endif
|
||||
|
||||
void LEDManager::setup()
|
||||
{
|
||||
ESP_LOGD(LED_MANAGER_TAG, "Setting up status led.");
|
||||
gpio_reset_pin(blink_led_pin);
|
||||
/* Set the GPIO as a push/pull output */
|
||||
gpio_set_direction(blink_led_pin, GPIO_MODE_OUTPUT);
|
||||
// the defualt state is _LedStateNone so we're fine
|
||||
this->currentState = ledStateManager.getCurrentState();
|
||||
this->currentPatternIndex = 0;
|
||||
BlinkPatterns_t pattern =
|
||||
this->ledStateMap[this->currentState][this->currentPatternIndex];
|
||||
this->toggleLED(pattern.state);
|
||||
this->nextStateChangeMillis = pattern.delayTime;
|
||||
|
||||
#ifdef USE_ILLUMNATIOR_PIN
|
||||
ESP_LOGD(LED_MANAGER_TAG, "Setting up illuminator led.");
|
||||
const int ledPin = 1; // Replace this with a command endpoint eventually.
|
||||
const int freq = 5000;
|
||||
const auto resolution = LEDC_TIMER_8_BIT;
|
||||
const int dutyCycle = 255;
|
||||
|
||||
ledc_timer_config_t ledc_timer = {
|
||||
.speed_mode = LEDC_LOW_SPEED_MODE,
|
||||
.duty_resolution = resolution,
|
||||
.timer_num = LEDC_TIMER_0,
|
||||
.freq_hz = freq,
|
||||
.clk_cfg = LEDC_AUTO_CLK};
|
||||
|
||||
ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
|
||||
|
||||
ledc_channel_config_t ledc_channel = {
|
||||
.gpio_num = this->illumninator_led_pin,
|
||||
.speed_mode = LEDC_LOW_SPEED_MODE,
|
||||
.channel = LEDC_CHANNEL_0,
|
||||
.intr_type = LEDC_INTR_DISABLE,
|
||||
.timer_sel = LEDC_TIMER_0,
|
||||
.duty = dutyCycle,
|
||||
.hpoint = 0};
|
||||
|
||||
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
|
||||
#endif
|
||||
ESP_LOGD(LED_MANAGER_TAG, "Done.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Display the current state of the LED manager as a pattern of blinking
|
||||
* LED
|
||||
* @details This function must be called in the main loop
|
||||
*/
|
||||
void LEDManager::handleLED()
|
||||
{
|
||||
if (Helpers::getTimeInMillis() <= this->nextStateChangeMillis)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// !TODO what if we want a looping state? Or a state that needs to stay
|
||||
// bright? Am overthinking this, aren't I?
|
||||
|
||||
// we've reached the timeout on that state, check if we can grab next one and
|
||||
// start displaying it, or if we need to keep displaying the current one
|
||||
if (this->currentPatternIndex >
|
||||
this->ledStateMap[this->currentState].size() - 1)
|
||||
{
|
||||
auto nextState = ledStateManager.getCurrentState();
|
||||
// we want to keep displaying the same state only if its an keepAlive one,
|
||||
// but we should change if the incoming one is also an errours state, maybe
|
||||
// more serious one this time <- this may be a bad idea
|
||||
if ((std::find(this->keepAliveStates.begin(), this->keepAliveStates.end(),
|
||||
this->currentState) != this->keepAliveStates.end() ||
|
||||
std::find(this->keepAliveStates.begin(), this->keepAliveStates.end(),
|
||||
nextState) != this->keepAliveStates.end()) ||
|
||||
(this->currentState != nextState &&
|
||||
this->ledStateMap.find(nextState) != this->ledStateMap.end()))
|
||||
{
|
||||
ESP_LOGD(LED_MANAGER_TAG, "Updating the state and reseting");
|
||||
this->toggleLED(false);
|
||||
this->currentState = nextState;
|
||||
this->currentPatternIndex = 0;
|
||||
BlinkPatterns_t pattern =
|
||||
this->ledStateMap[this->currentState][this->currentPatternIndex];
|
||||
this->nextStateChangeMillis = Helpers::getTimeInMillis() + pattern.delayTime;
|
||||
return;
|
||||
}
|
||||
// it wasn't a keepAlive state, nor did we have another one ready,
|
||||
// we're done for now
|
||||
this->toggleLED(false);
|
||||
return;
|
||||
}
|
||||
// we can safely advance it and display the next stage
|
||||
BlinkPatterns_t pattern =
|
||||
this->ledStateMap[this->currentState][this->currentPatternIndex];
|
||||
this->toggleLED(pattern.state);
|
||||
this->nextStateChangeMillis = Helpers::getTimeInMillis() + pattern.delayTime;
|
||||
ESP_LOGD(LED_MANAGER_TAG, "before updating stage %d", this->currentPatternIndex);
|
||||
this->currentPatternIndex++;
|
||||
ESP_LOGD(LED_MANAGER_TAG, "updated stage %d", this->currentPatternIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turn the LED on or off
|
||||
*
|
||||
* @param state
|
||||
*/
|
||||
void LEDManager::toggleLED(bool state) const
|
||||
{
|
||||
gpio_set_level(blink_led_pin, state);
|
||||
}
|
||||
52
components/LEDManager/LEDManager/LEDManager.hpp
Normal file
52
components/LEDManager/LEDManager/LEDManager.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
#ifndef _LEDMANAGER_HPP_
|
||||
#define _LEDMANAGER_HPP_
|
||||
|
||||
#include "driver/gpio.h"
|
||||
|
||||
#ifdef USE_ILLUMNATIOR_PIN
|
||||
#include "driver/ledc.h"
|
||||
#endif
|
||||
|
||||
#include <esp_log.h>
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <StateManager.hpp>
|
||||
#include <Helpers.hpp>
|
||||
|
||||
class LEDManager
|
||||
{
|
||||
public:
|
||||
LEDManager(gpio_num_t blink_led_pin);
|
||||
|
||||
#ifdef USE_ILLUMNATIOR_PIN
|
||||
gpio_num_t illumninator_led_pin;
|
||||
LEDManager(gpio_num_t blink_led_pin, gpio_num_t illumninator_led_pin);
|
||||
#endif
|
||||
|
||||
void setup();
|
||||
void handleLED();
|
||||
|
||||
private:
|
||||
gpio_num_t blink_led_pin;
|
||||
unsigned long nextStateChangeMillis = 0;
|
||||
bool state = false;
|
||||
|
||||
struct BlinkPatterns_t
|
||||
{
|
||||
int state;
|
||||
int delayTime;
|
||||
};
|
||||
|
||||
typedef std::unordered_map<LEDStates_e, std::vector<BlinkPatterns_t>> ledStateMap_t;
|
||||
static ledStateMap_t ledStateMap;
|
||||
static std::vector<LEDStates_e> keepAliveStates;
|
||||
LEDStates_e currentState;
|
||||
unsigned int currentPatternIndex = 0;
|
||||
|
||||
void toggleLED(bool state) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "freertos/task.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
#include "led_strip.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "usb_device_uvc.h"
|
||||
#include "esp_camera.h"
|
||||
@@ -22,29 +21,11 @@
|
||||
#include <openiris_logo.hpp>
|
||||
#include <wifiManager.hpp>
|
||||
#include <ProjectConfig.hpp>
|
||||
#include <LEDManager.hpp>
|
||||
|
||||
static const char *TAG = "[MAIN]";
|
||||
|
||||
/* Use project configuration menu (idf.py menuconfig) to choose the GPIO to blink,
|
||||
or you can edit the following line and set a number here.
|
||||
*/
|
||||
#define BLINK_GPIO (gpio_num_t) CONFIG_BLINK_GPIO
|
||||
|
||||
static uint8_t s_led_state = 0;
|
||||
|
||||
static void blink_led(void)
|
||||
{
|
||||
/* Set the GPIO level according to the state (LOW or HIGH)*/
|
||||
gpio_set_level(BLINK_GPIO, s_led_state);
|
||||
}
|
||||
|
||||
static void configure_led(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "Example configured to blink GPIO LED!");
|
||||
gpio_reset_pin(BLINK_GPIO);
|
||||
/* Set the GPIO as a push/pull output */
|
||||
gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
|
||||
}
|
||||
static const char *TAG = "[MAIN]";
|
||||
|
||||
static void initNVSStorage()
|
||||
{
|
||||
@@ -80,21 +61,23 @@ extern "C" void app_main(void)
|
||||
ProjectConfig deviceConfig("openiris", "openiristracker");
|
||||
WiFiManager wifiManager;
|
||||
|
||||
#ifdef USE_ILLUMNATIOR_PIN
|
||||
// LEDManager ledManager(BLINK_GPIO, ILLUMINATOR_PIN);
|
||||
LEDManager ledManager(BLINK_GPIO, 1);
|
||||
#else
|
||||
LEDManager ledManager(BLINK_GPIO);
|
||||
#endif
|
||||
|
||||
Logo::printASCII();
|
||||
initNVSStorage();
|
||||
|
||||
ledManager.setup();
|
||||
deviceConfig.load();
|
||||
wifiManager.Begin();
|
||||
|
||||
/* Configure the peripheral according to the LED type */
|
||||
configure_led();
|
||||
|
||||
while (1)
|
||||
{
|
||||
ESP_LOGI(TAG, "Turning the LED on pin %d %s!", BLINK_GPIO, s_led_state == true ? "ON" : "OFF");
|
||||
blink_led();
|
||||
/* Toggle the LED state */
|
||||
s_led_state = !s_led_state;
|
||||
ledManager.handleLED();
|
||||
vTaskDelay(CONFIG_BLINK_PERIOD / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user