Feature: AI Thinker LED flash
Reduce LEDC Timer Resolution. Add LEDC error msgs Update app_httpd.c Increase delay for still image flash from 100ms to 150 ms.pull/99/head
parent
fec860da0e
commit
65b14fd5be
|
|
@ -20,6 +20,7 @@
|
||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
#include "driver/ledc.h"
|
||||||
#include "esp_camera.h"
|
#include "esp_camera.h"
|
||||||
#include "app_camera.h"
|
#include "app_camera.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
@ -44,6 +45,32 @@ void app_camera_main ()
|
||||||
gpio_config(&conf);
|
gpio_config(&conf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_CAMERA_MODEL_AI_THINKER
|
||||||
|
gpio_set_direction(LED_GPIO_NUM,GPIO_MODE_OUTPUT);
|
||||||
|
ledc_timer_config_t ledc_timer = {
|
||||||
|
.duty_resolution = LEDC_TIMER_8_BIT, // resolution of PWM duty
|
||||||
|
.freq_hz = 1000, // frequency of PWM signal
|
||||||
|
.speed_mode = LEDC_LOW_SPEED_MODE, // timer mode
|
||||||
|
.timer_num = LEDC_TIMER_1 // timer index
|
||||||
|
};
|
||||||
|
switch (ledc_timer_config(&ledc_timer)) {
|
||||||
|
case ESP_ERR_INVALID_ARG: ESP_LOGE(TAG, "ledc_timer_config() parameter error"); break;
|
||||||
|
case ESP_FAIL: ESP_LOGE(TAG, "ledc_timer_config() Can not find a proper pre-divider number base on the given frequency and the current duty_resolution"); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
ledc_channel_config_t ledc_channel = {
|
||||||
|
.channel = LEDC_CHANNEL_1,
|
||||||
|
.duty = 0,
|
||||||
|
.gpio_num = LED_GPIO_NUM,
|
||||||
|
.speed_mode = LEDC_LOW_SPEED_MODE,
|
||||||
|
.hpoint = 0,
|
||||||
|
.timer_sel = LEDC_TIMER_1
|
||||||
|
};
|
||||||
|
if (ledc_channel_config(&ledc_channel) == ESP_ERR_INVALID_ARG) {
|
||||||
|
ESP_LOGE(TAG, "ledc_channel_config() parameter error");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
camera_config_t config;
|
camera_config_t config;
|
||||||
config.ledc_channel = LEDC_CHANNEL_0;
|
config.ledc_channel = LEDC_CHANNEL_0;
|
||||||
config.ledc_timer = LEDC_TIMER_0;
|
config.ledc_timer = LEDC_TIMER_0;
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
#include "esp_camera.h"
|
#include "esp_camera.h"
|
||||||
#include "img_converters.h"
|
#include "img_converters.h"
|
||||||
#include "fb_gfx.h"
|
#include "fb_gfx.h"
|
||||||
|
#include "driver/ledc.h"
|
||||||
//#include "camera_index.h"
|
//#include "camera_index.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
|
@ -47,6 +48,12 @@ static const char* TAG = "camera_httpd";
|
||||||
#define FACE_COLOR_PURPLE (FACE_COLOR_BLUE | FACE_COLOR_RED)
|
#define FACE_COLOR_PURPLE (FACE_COLOR_BLUE | FACE_COLOR_RED)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_CAMERA_MODEL_AI_THINKER
|
||||||
|
#define FLASH_LEDC_SPEED_MODE LEDC_LOW_SPEED_MODE
|
||||||
|
#define FLASH_LEDC_CHANNEL LEDC_CHANNEL_1
|
||||||
|
int flash_ledc_duty = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t size; //number of values used for filtering
|
size_t size; //number of values used for filtering
|
||||||
size_t index; //current value index
|
size_t index; //current value index
|
||||||
|
|
@ -243,7 +250,21 @@ static esp_err_t capture_handler(httpd_req_t *req){
|
||||||
esp_err_t res = ESP_OK;
|
esp_err_t res = ESP_OK;
|
||||||
int64_t fr_start = esp_timer_get_time();
|
int64_t fr_start = esp_timer_get_time();
|
||||||
|
|
||||||
|
#ifdef CONFIG_CAMERA_MODEL_AI_THINKER
|
||||||
|
ledc_set_duty(FLASH_LEDC_SPEED_MODE, FLASH_LEDC_CHANNEL, flash_ledc_duty);
|
||||||
|
ledc_update_duty(FLASH_LEDC_SPEED_MODE, FLASH_LEDC_CHANNEL);
|
||||||
|
ESP_LOGI(TAG, "Activating LED duty cycle=%d", flash_ledc_duty);
|
||||||
|
vTaskDelay(150 / portTICK_PERIOD_MS);
|
||||||
|
#endif
|
||||||
|
|
||||||
fb = esp_camera_fb_get();
|
fb = esp_camera_fb_get();
|
||||||
|
|
||||||
|
#ifdef CONFIG_CAMERA_MODEL_AI_THINKER
|
||||||
|
ledc_set_duty(FLASH_LEDC_SPEED_MODE, FLASH_LEDC_CHANNEL, 0);
|
||||||
|
ledc_update_duty(FLASH_LEDC_SPEED_MODE, FLASH_LEDC_CHANNEL);
|
||||||
|
ESP_LOGI(TAG, "LED Off");
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!fb) {
|
if (!fb) {
|
||||||
ESP_LOGE(TAG, "Camera capture failed");
|
ESP_LOGE(TAG, "Camera capture failed");
|
||||||
httpd_resp_send_500(req);
|
httpd_resp_send_500(req);
|
||||||
|
|
@ -360,11 +381,18 @@ static esp_err_t stream_handler(httpd_req_t *req){
|
||||||
|
|
||||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||||
|
|
||||||
|
#ifdef CONFIG_CAMERA_MODEL_AI_THINKER
|
||||||
|
ledc_set_duty(FLASH_LEDC_SPEED_MODE, FLASH_LEDC_CHANNEL, flash_ledc_duty);
|
||||||
|
ledc_update_duty(FLASH_LEDC_SPEED_MODE, FLASH_LEDC_CHANNEL);
|
||||||
|
ESP_LOGI(TAG, "Activating LED duty cycle=%d", flash_ledc_duty);
|
||||||
|
#endif
|
||||||
|
|
||||||
while(true){
|
while(true){
|
||||||
#if CONFIG_ESP_FACE_DETECT_ENABLED
|
#if CONFIG_ESP_FACE_DETECT_ENABLED
|
||||||
detected = false;
|
detected = false;
|
||||||
face_id = 0;
|
face_id = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fb = esp_camera_fb_get();
|
fb = esp_camera_fb_get();
|
||||||
if (!fb) {
|
if (!fb) {
|
||||||
ESP_LOGE(TAG, "Camera capture failed");
|
ESP_LOGE(TAG, "Camera capture failed");
|
||||||
|
|
@ -490,6 +518,12 @@ static esp_err_t stream_handler(httpd_req_t *req){
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_CAMERA_MODEL_AI_THINKER
|
||||||
|
ledc_set_duty(FLASH_LEDC_SPEED_MODE, FLASH_LEDC_CHANNEL, 0);
|
||||||
|
ledc_update_duty(FLASH_LEDC_SPEED_MODE, FLASH_LEDC_CHANNEL);
|
||||||
|
ESP_LOGI(TAG, "LED Off");
|
||||||
|
#endif
|
||||||
|
|
||||||
last_frame = 0;
|
last_frame = 0;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
@ -557,6 +591,9 @@ static esp_err_t cmd_handler(httpd_req_t *req){
|
||||||
else if(!strcmp(variable, "special_effect")) res = s->set_special_effect(s, val);
|
else if(!strcmp(variable, "special_effect")) res = s->set_special_effect(s, val);
|
||||||
else if(!strcmp(variable, "wb_mode")) res = s->set_wb_mode(s, val);
|
else if(!strcmp(variable, "wb_mode")) res = s->set_wb_mode(s, val);
|
||||||
else if(!strcmp(variable, "ae_level")) res = s->set_ae_level(s, val);
|
else if(!strcmp(variable, "ae_level")) res = s->set_ae_level(s, val);
|
||||||
|
#if CONFIG_CAMERA_MODEL_AI_THINKER
|
||||||
|
else if(!strcmp(variable, "flash_level")) flash_ledc_duty = val;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_ESP_FACE_DETECT_ENABLED
|
#if CONFIG_ESP_FACE_DETECT_ENABLED
|
||||||
else if(!strcmp(variable, "face_detect")) {
|
else if(!strcmp(variable, "face_detect")) {
|
||||||
|
|
@ -620,7 +657,9 @@ static esp_err_t status_handler(httpd_req_t *req){
|
||||||
p+=sprintf(p, "\"hmirror\":%u,", s->status.hmirror);
|
p+=sprintf(p, "\"hmirror\":%u,", s->status.hmirror);
|
||||||
p+=sprintf(p, "\"dcw\":%u,", s->status.dcw);
|
p+=sprintf(p, "\"dcw\":%u,", s->status.dcw);
|
||||||
p+=sprintf(p, "\"colorbar\":%u", s->status.colorbar);
|
p+=sprintf(p, "\"colorbar\":%u", s->status.colorbar);
|
||||||
|
#ifdef CONFIG_CAMERA_MODEL_AI_THINKER
|
||||||
|
p+= sprintf(p, "\"flash_level\":%u", flash_ledc_duty);
|
||||||
|
#endif
|
||||||
#if CONFIG_ESP_FACE_DETECT_ENABLED
|
#if CONFIG_ESP_FACE_DETECT_ENABLED
|
||||||
p+=sprintf(p, ",\"face_detect\":%u", detection_enabled);
|
p+=sprintf(p, ",\"face_detect\":%u", detection_enabled);
|
||||||
#if CONFIG_ESP_FACE_RECOGNITION_ENABLED
|
#if CONFIG_ESP_FACE_RECOGNITION_ENABLED
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
#define HREF_GPIO_NUM 23
|
#define HREF_GPIO_NUM 23
|
||||||
#define PCLK_GPIO_NUM 22
|
#define PCLK_GPIO_NUM 22
|
||||||
|
|
||||||
|
#define LED_GPIO_NUM 4
|
||||||
|
|
||||||
#elif CONFIG_CAMERA_MODEL_CUSTOM
|
#elif CONFIG_CAMERA_MODEL_CUSTOM
|
||||||
#define PWDN_GPIO_NUM CONFIG_CAMERA_PIN_PWDN
|
#define PWDN_GPIO_NUM CONFIG_CAMERA_PIN_PWDN
|
||||||
|
|
|
||||||
|
|
@ -531,6 +531,12 @@
|
||||||
<label class="slider" for="colorbar"></label>
|
<label class="slider" for="colorbar"></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="input-group" id="flash-group">
|
||||||
|
<label for="flash_level">Flash Level</label>
|
||||||
|
<div class="range-min">0</div>
|
||||||
|
<input type="range" id="flash_level" min="0" max="255" value="0" class="default-action">
|
||||||
|
<div class="range-max">255</div>
|
||||||
|
</div>
|
||||||
<div class="input-group" id="face_detect-group">
|
<div class="input-group" id="face_detect-group">
|
||||||
<label for="face_detect">Face Detection</label>
|
<label for="face_detect">Face Detection</label>
|
||||||
<div class="switch">
|
<div class="switch">
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -560,6 +560,12 @@
|
||||||
<label class="slider" for="colorbar"></label>
|
<label class="slider" for="colorbar"></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="input-group" id="flash-group">
|
||||||
|
<label for="flash_level">Flash Level</label>
|
||||||
|
<div class="range-min">0</div>
|
||||||
|
<input type="range" id="flash_level" min="0" max="255" value="0" class="default-action">
|
||||||
|
<div class="range-max">255</div>
|
||||||
|
</div>
|
||||||
<div class="input-group" id="face_detect-group">
|
<div class="input-group" id="face_detect-group">
|
||||||
<label for="face_detect">Face Detection</label>
|
<label for="face_detect">Face Detection</label>
|
||||||
<div class="switch">
|
<div class="switch">
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Reference in New Issue