♻️ common -> modules
parent
dd58787fab
commit
66b00a1449
|
@ -1,3 +0,0 @@
|
|||
idf_component_register(SRC_DIRS . INCLUDE_DIRS include wallpaper REQUIRES esp32-camera esp-dl bus screen)
|
||||
|
||||
component_compile_options(-ffast-math -O3)
|
|
@ -1,53 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "esp_camera.h"
|
||||
#include "app_define.h"
|
||||
|
||||
/**
|
||||
* @brief Initialize camera
|
||||
*
|
||||
* @param pixformat One of
|
||||
* - PIXFORMAT_RGB565
|
||||
* - PIXFORMAT_YUV422
|
||||
* - PIXFORMAT_GRAYSC
|
||||
* - PIXFORMAT_JPEG
|
||||
* - PIXFORMAT_RGB888
|
||||
* - PIXFORMAT_RAW
|
||||
* - PIXFORMAT_RGB444
|
||||
* - PIXFORMAT_RGB555
|
||||
* @param frame_size One of
|
||||
* - FRAMESIZE_96X96, // 96x96
|
||||
* - FRAMESIZE_QQVGA, // 160x120
|
||||
* - FRAMESIZE_QCIF, // 176x144
|
||||
* - FRAMESIZE_HQVGA, // 240x176
|
||||
* - FRAMESIZE_240X240, // 240x240
|
||||
* - FRAMESIZE_QVGA, // 320x240
|
||||
* - FRAMESIZE_CIF, // 400x296
|
||||
* - FRAMESIZE_HVGA, // 480x320
|
||||
* - FRAMESIZE_VGA, // 640x480
|
||||
* - FRAMESIZE_SVGA, // 800x600
|
||||
* - FRAMESIZE_XGA, // 1024x768
|
||||
* - FRAMESIZE_HD, // 1280x720
|
||||
* - FRAMESIZE_SXGA, // 1280x1024
|
||||
* - FRAMESIZE_UXGA, // 1600x1200
|
||||
* - FRAMESIZE_FHD, // 1920x1080
|
||||
* - FRAMESIZE_P_HD, // 720x1280
|
||||
* - FRAMESIZE_P_3MP, // 864x1536
|
||||
* - FRAMESIZE_QXGA, // 2048x1536
|
||||
* - FRAMESIZE_QHD, // 2560x1440
|
||||
* - FRAMESIZE_WQXGA, // 2560x1600
|
||||
* - FRAMESIZE_P_FHD, // 1080x1920
|
||||
* - FRAMESIZE_QSXGA, // 2560x1920
|
||||
* @param fb_count Number of frame buffers to be allocated. If more than one, then each frame will be acquired (double speed)
|
||||
* @param jpeg_quality Quality of JPEG output. 0-63 lower means higher quality
|
||||
*/
|
||||
void app_camera_init(const pixformat_t pixel_fromat, const framesize_t frame_size, const uint8_t fb_count, const uint8_t jpeg_quality = 12);
|
||||
|
||||
/**
|
||||
* @brief Decode fb ,
|
||||
* - if fb->format == PIXFORMAT_RGB565, then return fb->buf
|
||||
* - else, then return a new memory with RGB888, don't forget to free it
|
||||
*
|
||||
* @param fb
|
||||
*/
|
||||
void *app_camera_decode(camera_fb_t *fb);
|
|
@ -1,18 +0,0 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include "esp_log.h"
|
||||
#include "screen_driver.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
esp_err_t app_lcd_init();
|
||||
void app_lcd_draw_wallpaper();
|
||||
void app_lcd_set_color(int color);
|
||||
void app_lcd_draw_bitmap(uint16_t *image_ptr, const uint16_t image_height, const uint16_t image_width);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,31 @@
|
|||
set(embed_files "web/www/index_ov2640.html.gz"
|
||||
"web/www/index_ov3660.html.gz"
|
||||
"web/www/index_ov5640.html.gz"
|
||||
"web/www/monitor.html.gz")
|
||||
|
||||
set(src_dirs
|
||||
ai
|
||||
camera
|
||||
lcd
|
||||
led
|
||||
web)
|
||||
|
||||
set(include_dirs
|
||||
ai
|
||||
camera
|
||||
lcd
|
||||
led
|
||||
web)
|
||||
|
||||
set(requires esp32-camera
|
||||
esp-dl
|
||||
bus
|
||||
screen
|
||||
esp_http_server
|
||||
nvs_flash
|
||||
mdns
|
||||
fb_gfx)
|
||||
|
||||
idf_component_register(SRC_DIRS ${src_dirs} INCLUDE_DIRS ${include_dirs} REQUIRES ${requires} EMBED_FILES ${embed_files})
|
||||
|
||||
component_compile_options(-ffast-math -O3)
|
|
@ -1,30 +1,64 @@
|
|||
menu "ESP-WHO General Configuration"
|
||||
menu "Camera Configuration"
|
||||
|
||||
choice PIXEL_FORMAT
|
||||
bool "Select Camera Pixel Format"
|
||||
default CAMERA_PIXEL_FORMAT_RGB565
|
||||
help
|
||||
Select Camera Pixel Format.
|
||||
|
||||
config CAMERA_PIXEL_FORMAT_RGB565
|
||||
bool "RGB565"
|
||||
config CAMERA_PIXEL_FORMAT_YUV422
|
||||
bool "YUV422"
|
||||
config CAMERA_PIXEL_FORMAT_GRAYSCALE
|
||||
bool "GRAYSCALE"
|
||||
config CAMERA_PIXEL_FORMAT_JPEG
|
||||
bool "JPEG"
|
||||
config CAMERA_PIXEL_FORMAT_RGB888
|
||||
bool "RGB888"
|
||||
config CAMERA_PIXEL_FORMAT_RAW
|
||||
bool "RAW"
|
||||
config CAMERA_PIXEL_FORMAT_RGB444
|
||||
bool "RGB444"
|
||||
config CAMERA_PIXEL_FORMAT_RGB555
|
||||
bool "RGB555"
|
||||
|
||||
menu "WiFi Configuration"
|
||||
|
||||
endchoice
|
||||
config ESP_HOST_NAME
|
||||
string "Camera Host Name"
|
||||
default ""
|
||||
help
|
||||
Hostname that the camera will advertise over mDNS.
|
||||
|
||||
config ESP_WIFI_SSID
|
||||
string "WiFi STA SSID"
|
||||
default ""
|
||||
help
|
||||
WiFi SSID (network name) to connect to or empty for Off.
|
||||
|
||||
config ESP_WIFI_PASSWORD
|
||||
string "WiFi STA Password"
|
||||
default ""
|
||||
help
|
||||
WiFi Password if WEP/WPA/WPA2 or empty if Open.
|
||||
|
||||
config ESP_WIFI_AP_SSID
|
||||
string "WiFi AP SSID"
|
||||
default "ESP32-Camera"
|
||||
help
|
||||
AP SSID (network name) to create or empty for Off.
|
||||
|
||||
config ESP_WIFI_AP_PASSWORD
|
||||
string "WiFi AP Password"
|
||||
default ""
|
||||
help
|
||||
AP password for WPA2 or empty for Open.
|
||||
|
||||
config MAX_STA_CONN
|
||||
int "Maximal STA connections"
|
||||
default 1
|
||||
help
|
||||
Max number of the STA connects to AP.
|
||||
|
||||
config ESP_WIFI_AP_CHANNEL
|
||||
string "WiFi AP Channel"
|
||||
default ""
|
||||
help
|
||||
AP channel for better connection performance.
|
||||
|
||||
config SERVER_IP
|
||||
string "WiFi AP IP Address"
|
||||
default "192.168.4.1"
|
||||
help
|
||||
IP address that the ESP will assign to it's AP interface. You can use this IP to connect to the camera after flashing.
|
||||
|
||||
config ESP_MAXIMUM_RETRY
|
||||
int "Maximum retry"
|
||||
default 5
|
||||
help
|
||||
Set the Maximum retry to avoid station reconnecting to the AP unlimited when the AP is really inexistent.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Camera Configuration"
|
||||
|
||||
choice CAMERA_MODULE
|
||||
bool "Select Camera Pinout"
|
||||
|
@ -36,6 +70,8 @@ menu "ESP-WHO General Configuration"
|
|||
bool "WROVER-KIT With OV2640 Module"
|
||||
config CAMERA_MODULE_ESP_EYE
|
||||
bool "ESP-EYE DevKit"
|
||||
config CAMERA_MODULE_ESP_S2_KALUGA
|
||||
bool "ESP32-S2-Kaluga-1 V1.3"
|
||||
config CAMERA_MODULE_ESP_S3_EYE
|
||||
bool "ESP-S3-EYE DevKit"
|
||||
config CAMERA_MODEL_ESP32_CAM_BOARD
|
||||
|
@ -232,84 +268,4 @@ menu "ESP-WHO General Configuration"
|
|||
help
|
||||
Select the LEDC Channel (0-7)
|
||||
endmenu
|
||||
|
||||
|
||||
|
||||
menu "DL Configuration"
|
||||
|
||||
config DL_ENABLED
|
||||
bool "Enable Deep-Learning Application"
|
||||
default y
|
||||
|
||||
choice DL_SELECT_APP
|
||||
bool "Select Application"
|
||||
depends on DL_ENABLED
|
||||
default DL_HUMAN_FACE
|
||||
|
||||
config DL_HUMAN_FACE
|
||||
bool "Human Face"
|
||||
config DL_CAT_FACE
|
||||
bool "Cat Face"
|
||||
config DL_HUMAN_HAND
|
||||
bool "Human Hand"
|
||||
endchoice
|
||||
|
||||
# Human Face Series
|
||||
choice DL_HUMAN_FACE_DETECTION_S1_MODEL
|
||||
bool "Select Human Face Detection Stage-1 Model"
|
||||
depends on DL_HUMAN_FACE
|
||||
default DL_HUMAN_FACE_DETECTION_S1_MSR01
|
||||
|
||||
config DL_HUMAN_FACE_DETECTION_S1_MSR01
|
||||
bool "HumanFaceDetectMSR01"
|
||||
endchoice
|
||||
|
||||
config DL_HUMAN_FACE_DETECTION_S2_ENABLED
|
||||
bool "Enable Human Face Detection Stage-2"
|
||||
depends on DL_HUMAN_FACE
|
||||
default y
|
||||
|
||||
choice DL_HUMAN_FACE_DETECTION_S2_MODEL
|
||||
bool "Select Human Face Detection Stage-2 Model"
|
||||
depends on DL_HUMAN_FACE_DETECTION_S2_ENABLED
|
||||
default DL_HUMAN_FACE_DETECTION_S2_MNP01
|
||||
|
||||
config DL_HUMAN_FACE_DETECTION_S2_MNP01
|
||||
bool "HumanFaceDetectMNP01"
|
||||
endchoice
|
||||
|
||||
|
||||
config DL_HUMAN_FACE_RECOGNITION_ENABLED
|
||||
bool "Enable Human Face Recognition"
|
||||
depends on DL_HUMAN_FACE_DETECTION_S2_ENABLED
|
||||
default y
|
||||
|
||||
choice DL_HUMAN_FACE_RECOGNITION_MODEL
|
||||
bool "Select Human Face Recognition Model"
|
||||
depends on DL_HUMAN_FACE_RECOGNITION_ENABLED
|
||||
default DL_HUMAN_FACE_RECOGNITION_XXX
|
||||
|
||||
config DL_HUMAN_FACE_RECOGNITION_XXX
|
||||
bool "HumanFaceRecognizeXXX"
|
||||
endchoice
|
||||
|
||||
# Cat Face Series
|
||||
choice DL_CAT_FACE_DETECTION_MODEL
|
||||
bool "Select Cat Face Detection Model"
|
||||
depends on DL_CAT_FACE
|
||||
default DL_CAT_FACE_DETECTION_MN03
|
||||
|
||||
config DL_CAT_FACE_DETECTION_MN03
|
||||
bool "CatFaceDetectMN03"
|
||||
endchoice
|
||||
|
||||
|
||||
# Human Hand Series
|
||||
|
||||
|
||||
config DL_MOVING_TARGET_DETECTION_ENABLED
|
||||
bool "Enable Moving Target Detection"
|
||||
default y
|
||||
|
||||
endmenu
|
||||
endmenu
|
|
@ -1,7 +1,10 @@
|
|||
#include "app_common.hpp"
|
||||
|
||||
#include "dl_image.hpp"
|
||||
#include "esp_log.h"
|
||||
#include "esp_camera.h"
|
||||
|
||||
#include "dl_image.hpp"
|
||||
|
||||
|
||||
void draw_detection_result(uint16_t *image_ptr, int image_height, int image_width, std::list<dl::detect::result_t> &results)
|
||||
{
|
||||
|
@ -52,7 +55,7 @@ void print_detection_result(std::list<dl::detect::result_t> &results)
|
|||
{
|
||||
ESP_LOGI("detection_result", "[%d]: (%3d, %3d, %3d, %3d)"
|
||||
#if CONFIG_DL_HUMAN_FACE_DETECTION_S2_ENABLED
|
||||
" | left eye: (%3d, %3d), right eye: (%3d, %3d), nose: (%3d, %3d), mouth left: (%3d, %3d), mouth right: (%3d, %3d)"
|
||||
" | left eye: (%3d, %3d), right eye: (%3d, %3d), nose: (%3d, %3d), mouth left: (%3d, %3d), mouth right: (%3d, %3d)"
|
||||
#endif
|
||||
,
|
||||
i,
|
||||
|
@ -67,4 +70,33 @@ void print_detection_result(std::list<dl::detect::result_t> &results)
|
|||
#endif
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void *app_camera_decode(camera_fb_t *fb)
|
||||
{
|
||||
if (fb->format == PIXFORMAT_RGB565)
|
||||
{
|
||||
return (void *)fb->buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t *image_ptr = (uint8_t *)malloc(fb->height * fb->width * 3 * sizeof(uint8_t));
|
||||
if (image_ptr)
|
||||
{
|
||||
if (fmt2rgb888(fb->buf, fb->len, fb->format, image_ptr))
|
||||
{
|
||||
return (void *)image_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "fmt2rgb888 failed");
|
||||
dl::tool::free_aligned(image_ptr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "malloc memory for image rgb888 failed");
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
|
@ -2,7 +2,25 @@
|
|||
|
||||
#include <list>
|
||||
#include "dl_detect_define.hpp"
|
||||
#include "app_define.h"
|
||||
#include "esp_camera.h"
|
||||
// #include "who_define.h"
|
||||
|
||||
#if CONFIG_CAMERA_PIXEL_FORMAT_RGB565
|
||||
#define IMAGE_T uint16_t
|
||||
#define COLOR_RED 0b0000000011111000
|
||||
#define COLOR_GREEN 0b1110000000000111
|
||||
#define COLOR_BLUE 0b0001111100000000
|
||||
#define COLOR_BLACK 0b0000000000000000
|
||||
#else
|
||||
#define IMAGE_T uint8_t
|
||||
#define COLOR_RED 0x0000FF
|
||||
#define COLOR_GREEN 0x00FF00
|
||||
#define COLOR_BLUE 0xFF0000
|
||||
#define COLOR_BLACK 0x000000
|
||||
#endif
|
||||
|
||||
static const char *TAG = "app_common";
|
||||
|
||||
|
||||
/**
|
||||
* @brief Draw detection result on RGB565 image.
|
||||
|
@ -31,3 +49,12 @@ void draw_detection_result(uint8_t *image_ptr, int image_height, int image_width
|
|||
* @param results detection results
|
||||
*/
|
||||
void print_detection_result(std::list<dl::detect::result_t> &results);
|
||||
|
||||
/**
|
||||
* @brief Decode fb ,
|
||||
* - if fb->format == PIXFORMAT_RGB565, then return fb->buf
|
||||
* - else, then return a new memory with RGB888, don't forget to free it
|
||||
*
|
||||
* @param fb
|
||||
*/
|
||||
void *app_camera_decode(camera_fb_t *fb);
|
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
void register_cat_face_detection(QueueHandle_t frame_i, QueueHandle_t event,
|
||||
QueueHandle_t result, QueueHandle_t frame_o = NULL);
|
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
void register_motion_detection(QueueHandle_t frame_i, QueueHandle_t event,
|
||||
QueueHandle_t result, QueueHandle_t frame_o = NULL);
|
|
@ -1,14 +1,25 @@
|
|||
#include "app_camera.hpp"
|
||||
#include "who_camera.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
|
||||
#include "app_define.h"
|
||||
#include "dl_tool.hpp"
|
||||
static const char *TAG = "who_camera";
|
||||
static QueueHandle_t xQueueFrameO = NULL;
|
||||
|
||||
static const char *TAG = "app_camera";
|
||||
static void task_process_handler(void *arg)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
camera_fb_t *frame = esp_camera_fb_get();
|
||||
if (frame)
|
||||
xQueueSend(xQueueFrameO, &frame, portMAX_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
void app_camera_init(const pixformat_t pixel_fromat, const framesize_t frame_size, const uint8_t fb_count, const uint8_t jpeg_quality)
|
||||
void register_camera(const pixformat_t pixel_fromat,
|
||||
const framesize_t frame_size,
|
||||
const uint8_t fb_count,
|
||||
const QueueHandle_t frame_o)
|
||||
{
|
||||
ESP_LOGI(TAG, "Camera module is %s", CAMERA_MODULE_NAME);
|
||||
|
||||
|
@ -49,8 +60,9 @@ void app_camera_init(const pixformat_t pixel_fromat, const framesize_t frame_siz
|
|||
config.xclk_freq_hz = XCLK_FREQ_HZ;
|
||||
config.pixel_format = pixel_fromat;
|
||||
config.frame_size = frame_size;
|
||||
config.jpeg_quality = jpeg_quality;
|
||||
config.jpeg_quality = 12;
|
||||
config.fb_count = fb_count;
|
||||
config.fb_location = CAMERA_FB_IN_PSRAM;
|
||||
config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
|
||||
|
||||
// camera init
|
||||
|
@ -69,33 +81,7 @@ void app_camera_init(const pixformat_t pixel_fromat, const framesize_t frame_siz
|
|||
s->set_brightness(s, 1); //up the blightness just a bit
|
||||
s->set_saturation(s, -2); //lower the saturation
|
||||
}
|
||||
}
|
||||
|
||||
void *app_camera_decode(camera_fb_t *fb)
|
||||
{
|
||||
if (fb->format == PIXFORMAT_RGB565)
|
||||
{
|
||||
return (void *)fb->buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t *image_ptr = (uint8_t *)malloc(fb->height * fb->width * 3 * sizeof(uint8_t));
|
||||
if (image_ptr)
|
||||
{
|
||||
if (fmt2rgb888(fb->buf, fb->len, fb->format, image_ptr))
|
||||
{
|
||||
return (void *)image_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "fmt2rgb888 failed");
|
||||
dl::tool::free_aligned(image_ptr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "malloc memory for image rgb888 failed");
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
xQueueFrameO = frame_o;
|
||||
xTaskCreatePinnedToCore(task_process_handler, TAG, 2 * 1024, NULL, 5, NULL, 1);
|
||||
}
|
|
@ -1,22 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_camera.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
#if CONFIG_CAMERA_PIXEL_FORMAT_RGB565
|
||||
#define IMAGE_T uint16_t
|
||||
#define COLOR_RED 0b0000000011111000
|
||||
#define COLOR_GREEN 0b1110000000000111
|
||||
#define COLOR_BLUE 0b0001111100000000
|
||||
#define COLOR_BLACK 0b0000000000000000
|
||||
#else
|
||||
#define IMAGE_T uint8_t
|
||||
#define COLOR_RED 0x0000FF
|
||||
#define COLOR_GREEN 0x00FF00
|
||||
#define COLOR_BLUE 0xFF0000
|
||||
#define COLOR_BLACK 0x000000
|
||||
#endif
|
||||
#include "esp_camera.h"
|
||||
|
||||
#if CONFIG_CAMERA_MODULE_WROVER_KIT
|
||||
#define CAMERA_MODULE_NAME "Wrover Kit"
|
||||
|
@ -58,10 +47,30 @@
|
|||
#define CAMERA_PIN_HREF 27
|
||||
#define CAMERA_PIN_PCLK 25
|
||||
|
||||
#elif CONFIG_CAMERA_MODULE_ESP_S2_KALUGA
|
||||
#define CAMERA_MODULE_NAME "ESP-S2-KALUGA"
|
||||
#define CAMERA_PIN_PWDN -1
|
||||
#define CAMERA_PIN_RESET -1
|
||||
#define CAMERA_PIN_XCLK 1
|
||||
#define CAMERA_PIN_SIOD 8
|
||||
#define CAMERA_PIN_SIOC 7
|
||||
|
||||
#define CAMERA_PIN_D7 38
|
||||
#define CAMERA_PIN_D6 21
|
||||
#define CAMERA_PIN_D5 40
|
||||
#define CAMERA_PIN_D4 39
|
||||
#define CAMERA_PIN_D3 42
|
||||
#define CAMERA_PIN_D2 41
|
||||
#define CAMERA_PIN_D1 37
|
||||
#define CAMERA_PIN_D0 36
|
||||
#define CAMERA_PIN_VSYNC 2
|
||||
#define CAMERA_PIN_HREF 3
|
||||
#define CAMERA_PIN_PCLK 33
|
||||
|
||||
#elif CONFIG_CAMERA_MODULE_ESP_S3_EYE
|
||||
#define CAMERA_MODULE_NAME "ESP-S3-EYE"
|
||||
#define CAMERA_PIN_PWDN 43
|
||||
#define CAMERA_PIN_RESET 44
|
||||
#define CAMERA_PIN_PWDN -1
|
||||
#define CAMERA_PIN_RESET -1
|
||||
|
||||
#define CAMERA_PIN_VSYNC 6
|
||||
#define CAMERA_PIN_HREF 7
|
||||
|
@ -185,27 +194,52 @@
|
|||
|
||||
#define XCLK_FREQ_HZ 20000000
|
||||
|
||||
#if CONFIG_CAMERA_PIXEL_FORMAT_RGB565
|
||||
#define CAMERA_PIXEL_FORMAT PIXFORMAT_RGB565
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#if CONFIG_CAMERA_PIXEL_FORMAT_YUV422
|
||||
#define CAMERA_PIXEL_FORMAT PIXFORMAT_YUV422
|
||||
#endif
|
||||
#if CONFIG_CAMERA_PIXEL_FORMAT_GRAYSCALE
|
||||
#define CAMERA_PIXEL_FORMAT PIXFORMAT_GRAYSCALE
|
||||
#endif
|
||||
#if CONFIG_CAMERA_PIXEL_FORMAT_JPEG
|
||||
#define CAMERA_PIXEL_FORMAT PIXFORMAT_JPEG
|
||||
#endif
|
||||
#if CONFIG_CAMERA_PIXEL_FORMAT_RGB888
|
||||
#define CAMERA_PIXEL_FORMAT PIXFORMAT_RGB888
|
||||
#endif
|
||||
#if CONFIG_CAMERA_PIXEL_FORMAT_RAW
|
||||
#define CAMERA_PIXEL_FORMAT PIXFORMAT_RAW
|
||||
#endif
|
||||
#if CONFIG_CAMERA_PIXEL_FORMAT_RGB444
|
||||
#define CAMERA_PIXEL_FORMAT PIXFORMAT_RGB444
|
||||
#endif
|
||||
#if CONFIG_CAMERA_PIXEL_FORMAT_RGB555
|
||||
#define CAMERA_PIXEL_FORMAT PIXFORMAT_RGB555
|
||||
/**
|
||||
* @brief Initialize camera
|
||||
*
|
||||
* @param pixformat One of
|
||||
* - PIXFORMAT_RGB565
|
||||
* - PIXFORMAT_YUV422
|
||||
* - PIXFORMAT_GRAYSC
|
||||
* - PIXFORMAT_JPEG
|
||||
* - PIXFORMAT_RGB888
|
||||
* - PIXFORMAT_RAW
|
||||
* - PIXFORMAT_RGB444
|
||||
* - PIXFORMAT_RGB555
|
||||
* @param frame_size One of
|
||||
* - FRAMESIZE_96X96, // 96x96
|
||||
* - FRAMESIZE_QQVGA, // 160x120
|
||||
* - FRAMESIZE_QCIF, // 176x144
|
||||
* - FRAMESIZE_HQVGA, // 240x176
|
||||
* - FRAMESIZE_240X240, // 240x240
|
||||
* - FRAMESIZE_QVGA, // 320x240
|
||||
* - FRAMESIZE_CIF, // 400x296
|
||||
* - FRAMESIZE_HVGA, // 480x320
|
||||
* - FRAMESIZE_VGA, // 640x480
|
||||
* - FRAMESIZE_SVGA, // 800x600
|
||||
* - FRAMESIZE_XGA, // 1024x768
|
||||
* - FRAMESIZE_HD, // 1280x720
|
||||
* - FRAMESIZE_SXGA, // 1280x1024
|
||||
* - FRAMESIZE_UXGA, // 1600x1200
|
||||
* - FRAMESIZE_FHD, // 1920x1080
|
||||
* - FRAMESIZE_P_HD, // 720x1280
|
||||
* - FRAMESIZE_P_3MP, // 864x1536
|
||||
* - FRAMESIZE_QXGA, // 2048x1536
|
||||
* - FRAMESIZE_QHD, // 2560x1440
|
||||
* - FRAMESIZE_WQXGA, // 2560x1600
|
||||
* - FRAMESIZE_P_FHD, // 1080x1920
|
||||
* - FRAMESIZE_QSXGA, // 2560x1920
|
||||
* @param fb_count Number of frame buffers to be allocated. If more than one, then each frame will be acquired (double speed)
|
||||
*/
|
||||
void register_camera(const pixformat_t pixel_fromat,
|
||||
const framesize_t frame_size,
|
||||
const uint8_t fb_count,
|
||||
const QueueHandle_t frame_o);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -1,26 +1,57 @@
|
|||
#include "app_lcd.h"
|
||||
#include "who_lcd.h"
|
||||
#include "esp_camera.h"
|
||||
#include <string.h>
|
||||
#include "wallpaper_128x240_rgb565.h"
|
||||
|
||||
static const char *TAG = "app_lcd";
|
||||
static const char *TAG = "who_lcd";
|
||||
|
||||
static scr_driver_t g_lcd;
|
||||
static scr_info_t g_lcd_info;
|
||||
|
||||
esp_err_t app_lcd_init()
|
||||
static QueueHandle_t xQueueFrameI = NULL;
|
||||
static QueueHandle_t xQueueFrameO = NULL;
|
||||
static bool gReturnFB = true;
|
||||
|
||||
static void task_process_handler(void *arg)
|
||||
{
|
||||
camera_fb_t *frame = NULL;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (xQueueReceive(xQueueFrameI, &frame, portMAX_DELAY))
|
||||
{
|
||||
g_lcd.draw_bitmap(0, 0, frame->width, frame->height, (uint16_t *)frame->buf);
|
||||
|
||||
if (xQueueFrameO)
|
||||
{
|
||||
xQueueSend(xQueueFrameO, &frame, portMAX_DELAY);
|
||||
}
|
||||
else if (gReturnFB)
|
||||
{
|
||||
esp_camera_fb_return(frame);
|
||||
}
|
||||
else
|
||||
{
|
||||
free(frame);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t register_lcd(const QueueHandle_t frame_i, const QueueHandle_t frame_o, const bool return_fb)
|
||||
{
|
||||
spi_config_t bus_conf = {
|
||||
.miso_io_num = -1,
|
||||
.mosi_io_num = 48,
|
||||
.sclk_io_num = 21,
|
||||
.miso_io_num = BOARD_LCD_MISO,
|
||||
.mosi_io_num = BOARD_LCD_MOSI,
|
||||
.sclk_io_num = BOARD_LCD_SCK,
|
||||
.max_transfer_sz = 2 * 240 * 240 + 10,
|
||||
};
|
||||
spi_bus_handle_t spi_bus = spi_bus_create(SPI2_HOST, &bus_conf);
|
||||
|
||||
scr_interface_spi_config_t spi_lcd_cfg = {
|
||||
.spi_bus = spi_bus,
|
||||
.pin_num_cs = 43,
|
||||
.pin_num_dc = 47,
|
||||
.pin_num_cs = BOARD_LCD_CS,
|
||||
.pin_num_dc = BOARD_LCD_DC,
|
||||
.clk_freq = 40 * 1000000,
|
||||
.swap_data = 0,
|
||||
};
|
||||
|
@ -36,10 +67,10 @@ esp_err_t app_lcd_init()
|
|||
|
||||
scr_controller_config_t lcd_cfg = {
|
||||
.interface_drv = iface_drv,
|
||||
.pin_num_rst = -1,
|
||||
.pin_num_bckl = -1,
|
||||
.pin_num_rst = BOARD_LCD_RST,
|
||||
.pin_num_bckl = BOARD_LCD_BL,
|
||||
.rst_active_level = 0,
|
||||
.bckl_active_level = 1,
|
||||
.bckl_active_level = 0,
|
||||
.offset_hor = 0,
|
||||
.offset_ver = 0,
|
||||
.width = 240,
|
||||
|
@ -55,6 +86,17 @@ esp_err_t app_lcd_init()
|
|||
|
||||
g_lcd.get_info(&g_lcd_info);
|
||||
ESP_LOGI(TAG, "Screen name:%s | width:%d | height:%d", g_lcd_info.name, g_lcd_info.width, g_lcd_info.height);
|
||||
|
||||
app_lcd_set_color(0x000000);
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
app_lcd_draw_wallpaper();
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
|
||||
xQueueFrameI = frame_i;
|
||||
xQueueFrameO = frame_o;
|
||||
gReturnFB = return_fb;
|
||||
xTaskCreatePinnedToCore(task_process_handler, TAG, 4 * 1024, NULL, 5, NULL, 1);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
@ -104,8 +146,3 @@ void app_lcd_set_color(int color)
|
|||
free(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void app_lcd_draw_bitmap(uint16_t *image_ptr, const uint16_t image_height, const uint16_t image_width)
|
||||
{
|
||||
g_lcd.draw_bitmap(0, 0, image_width, image_height, image_ptr);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_log.h"
|
||||
#include "screen_driver.h"
|
||||
|
||||
#define BOARD_LCD_MOSI 46
|
||||
#define BOARD_LCD_MISO -1
|
||||
#define BOARD_LCD_SCK 21
|
||||
#define BOARD_LCD_CS 44
|
||||
#define BOARD_LCD_DC 47
|
||||
#define BOARD_LCD_RST -1
|
||||
#define BOARD_LCD_BL 48
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
esp_err_t register_lcd(const QueueHandle_t frame_i, const QueueHandle_t frame_o, const bool return_fb);
|
||||
|
||||
void app_lcd_draw_wallpaper();
|
||||
void app_lcd_set_color(int color);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -1,4 +1,4 @@
|
|||
#include "app_led.h"
|
||||
#include "who_led.h"
|
||||
|
||||
#if CONFIG_LED_ILLUMINATOR_ENABLED
|
||||
#include "esp_log.h"
|
|
@ -0,0 +1,778 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "app_httpd.hpp"
|
||||
|
||||
#include <list>
|
||||
#include "esp_http_server.h"
|
||||
#include "esp_timer.h"
|
||||
#include "img_converters.h"
|
||||
#include "fb_gfx.h"
|
||||
#include "app_mdns.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "who_camera.h"
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
|
||||
#include "esp32-hal-log.h"
|
||||
#define TAG ""
|
||||
#else
|
||||
#include "esp_log.h"
|
||||
static const char *TAG = "camera_httpd";
|
||||
#endif
|
||||
|
||||
static QueueHandle_t xQueueFrameI = NULL;
|
||||
static QueueHandle_t xQueueFrameO = NULL;
|
||||
static bool gReturnFB = true;
|
||||
|
||||
static int8_t detection_enabled = 0;
|
||||
static int8_t recognition_enabled = 0;
|
||||
static int8_t is_enrolling = 0;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
httpd_req_t *req;
|
||||
size_t len;
|
||||
} jpg_chunking_t;
|
||||
|
||||
#define PART_BOUNDARY "123456789000000000000987654321"
|
||||
static const char *_STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
|
||||
static const char *_STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
|
||||
static const char *_STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\nX-Timestamp: %d.%06d\r\n\r\n";
|
||||
|
||||
httpd_handle_t stream_httpd = NULL;
|
||||
httpd_handle_t camera_httpd = NULL;
|
||||
|
||||
static size_t jpg_encode_stream(void *arg, size_t index, const void *data, size_t len)
|
||||
{
|
||||
jpg_chunking_t *j = (jpg_chunking_t *)arg;
|
||||
if (!index)
|
||||
{
|
||||
j->len = 0;
|
||||
}
|
||||
if (httpd_resp_send_chunk(j->req, (const char *)data, len) != ESP_OK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
j->len += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
static esp_err_t capture_handler(httpd_req_t *req)
|
||||
{
|
||||
camera_fb_t *frame = NULL;
|
||||
esp_err_t res = ESP_OK;
|
||||
|
||||
if (xQueueReceive(xQueueFrameI, &frame, portMAX_DELAY))
|
||||
{
|
||||
httpd_resp_set_type(req, "image/jpeg");
|
||||
httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=capture.jpg");
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
|
||||
char ts[32];
|
||||
snprintf(ts, 32, "%ld.%06ld", frame->timestamp.tv_sec, frame->timestamp.tv_usec);
|
||||
httpd_resp_set_hdr(req, "X-Timestamp", (const char *)ts);
|
||||
|
||||
// size_t fb_len = 0;
|
||||
if (frame->format == PIXFORMAT_JPEG)
|
||||
{
|
||||
// fb_len = frame->len;
|
||||
res = httpd_resp_send(req, (const char *)frame->buf, frame->len);
|
||||
}
|
||||
else
|
||||
{
|
||||
jpg_chunking_t jchunk = {req, 0};
|
||||
res = frame2jpg_cb(frame, 80, jpg_encode_stream, &jchunk) ? ESP_OK : ESP_FAIL;
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
// fb_len = jchunk.len;
|
||||
}
|
||||
|
||||
if (xQueueFrameO)
|
||||
{
|
||||
xQueueSend(xQueueFrameO, &frame, portMAX_DELAY);
|
||||
}
|
||||
else if (gReturnFB)
|
||||
{
|
||||
esp_camera_fb_return(frame);
|
||||
}
|
||||
else
|
||||
{
|
||||
free(frame);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "Camera capture failed");
|
||||
httpd_resp_send_500(req);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static esp_err_t stream_handler(httpd_req_t *req)
|
||||
{
|
||||
camera_fb_t *frame = NULL;
|
||||
struct timeval _timestamp;
|
||||
esp_err_t res = ESP_OK;
|
||||
size_t _jpg_buf_len = 0;
|
||||
uint8_t *_jpg_buf = NULL;
|
||||
char *part_buf[128];
|
||||
|
||||
res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
|
||||
if (res != ESP_OK)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
httpd_resp_set_hdr(req, "X-Framerate", "60");
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (xQueueReceive(xQueueFrameI, &frame, portMAX_DELAY))
|
||||
{
|
||||
_timestamp.tv_sec = frame->timestamp.tv_sec;
|
||||
_timestamp.tv_usec = frame->timestamp.tv_usec;
|
||||
|
||||
if (frame->format == PIXFORMAT_JPEG)
|
||||
{
|
||||
_jpg_buf = frame->buf;
|
||||
_jpg_buf_len = frame->len;
|
||||
}
|
||||
else if (!frame2jpg(frame, 80, &_jpg_buf, &_jpg_buf_len))
|
||||
{
|
||||
ESP_LOGE(TAG, "JPEG compression failed");
|
||||
res = ESP_FAIL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
res = ESP_FAIL;
|
||||
}
|
||||
|
||||
if (res == ESP_OK)
|
||||
{
|
||||
res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
|
||||
}
|
||||
|
||||
if (res == ESP_OK)
|
||||
{
|
||||
size_t hlen = snprintf((char *)part_buf, 128, _STREAM_PART, _jpg_buf_len, _timestamp.tv_sec, _timestamp.tv_usec);
|
||||
res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);
|
||||
}
|
||||
|
||||
if (res == ESP_OK)
|
||||
{
|
||||
res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);
|
||||
}
|
||||
|
||||
if (frame->format != PIXFORMAT_JPEG)
|
||||
{
|
||||
free(_jpg_buf);
|
||||
_jpg_buf = NULL;
|
||||
}
|
||||
|
||||
if (xQueueFrameO)
|
||||
{
|
||||
xQueueSend(xQueueFrameO, &frame, portMAX_DELAY);
|
||||
}
|
||||
else if (gReturnFB)
|
||||
{
|
||||
esp_camera_fb_return(frame);
|
||||
}
|
||||
else
|
||||
{
|
||||
free(frame);
|
||||
}
|
||||
|
||||
if (res != ESP_OK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static esp_err_t parse_get(httpd_req_t *req, char **obuf)
|
||||
{
|
||||
char *buf = NULL;
|
||||
size_t buf_len = 0;
|
||||
|
||||
buf_len = httpd_req_get_url_query_len(req) + 1;
|
||||
if (buf_len > 1)
|
||||
{
|
||||
buf = (char *)malloc(buf_len);
|
||||
if (!buf)
|
||||
{
|
||||
httpd_resp_send_500(req);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK)
|
||||
{
|
||||
*obuf = buf;
|
||||
return ESP_OK;
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
httpd_resp_send_404(req);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
static esp_err_t cmd_handler(httpd_req_t *req)
|
||||
{
|
||||
char *buf = NULL;
|
||||
char variable[32];
|
||||
char value[32];
|
||||
|
||||
if (parse_get(req, &buf) != ESP_OK ||
|
||||
httpd_query_key_value(buf, "var", variable, sizeof(variable)) != ESP_OK ||
|
||||
httpd_query_key_value(buf, "val", value, sizeof(value)) != ESP_OK)
|
||||
{
|
||||
free(buf);
|
||||
httpd_resp_send_404(req);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
free(buf);
|
||||
|
||||
int val = atoi(value);
|
||||
ESP_LOGI(TAG, "%s = %d", variable, val);
|
||||
sensor_t *s = esp_camera_sensor_get();
|
||||
int res = 0;
|
||||
|
||||
if (!strcmp(variable, "framesize"))
|
||||
{
|
||||
if (s->pixformat == PIXFORMAT_JPEG)
|
||||
{
|
||||
res = s->set_framesize(s, (framesize_t)val);
|
||||
if (res == 0)
|
||||
{
|
||||
app_mdns_update_framesize(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(variable, "quality"))
|
||||
res = s->set_quality(s, val);
|
||||
else if (!strcmp(variable, "contrast"))
|
||||
res = s->set_contrast(s, val);
|
||||
else if (!strcmp(variable, "brightness"))
|
||||
res = s->set_brightness(s, val);
|
||||
else if (!strcmp(variable, "saturation"))
|
||||
res = s->set_saturation(s, val);
|
||||
else if (!strcmp(variable, "gainceiling"))
|
||||
res = s->set_gainceiling(s, (gainceiling_t)val);
|
||||
else if (!strcmp(variable, "colorbar"))
|
||||
res = s->set_colorbar(s, val);
|
||||
else if (!strcmp(variable, "awb"))
|
||||
res = s->set_whitebal(s, val);
|
||||
else if (!strcmp(variable, "agc"))
|
||||
res = s->set_gain_ctrl(s, val);
|
||||
else if (!strcmp(variable, "aec"))
|
||||
res = s->set_exposure_ctrl(s, val);
|
||||
else if (!strcmp(variable, "hmirror"))
|
||||
res = s->set_hmirror(s, val);
|
||||
else if (!strcmp(variable, "vflip"))
|
||||
res = s->set_vflip(s, val);
|
||||
else if (!strcmp(variable, "awb_gain"))
|
||||
res = s->set_awb_gain(s, val);
|
||||
else if (!strcmp(variable, "agc_gain"))
|
||||
res = s->set_agc_gain(s, val);
|
||||
else if (!strcmp(variable, "aec_value"))
|
||||
res = s->set_aec_value(s, val);
|
||||
else if (!strcmp(variable, "aec2"))
|
||||
res = s->set_aec2(s, val);
|
||||
else if (!strcmp(variable, "dcw"))
|
||||
res = s->set_dcw(s, val);
|
||||
else if (!strcmp(variable, "bpc"))
|
||||
res = s->set_bpc(s, val);
|
||||
else if (!strcmp(variable, "wpc"))
|
||||
res = s->set_wpc(s, val);
|
||||
else if (!strcmp(variable, "raw_gma"))
|
||||
res = s->set_raw_gma(s, val);
|
||||
else if (!strcmp(variable, "lenc"))
|
||||
res = s->set_lenc(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, "ae_level"))
|
||||
res = s->set_ae_level(s, val);
|
||||
#ifdef CONFIG_LED_ILLUMINATOR_ENABLED
|
||||
else if (!strcmp(variable, "led_intensity"))
|
||||
led_duty = val;
|
||||
#endif
|
||||
|
||||
else if (!strcmp(variable, "face_detect"))
|
||||
{
|
||||
detection_enabled = val;
|
||||
if (!detection_enabled)
|
||||
{
|
||||
recognition_enabled = 0;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(variable, "face_enroll"))
|
||||
is_enrolling = val;
|
||||
else if (!strcmp(variable, "face_recognize"))
|
||||
{
|
||||
recognition_enabled = val;
|
||||
if (recognition_enabled)
|
||||
{
|
||||
detection_enabled = val;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
res = -1;
|
||||
}
|
||||
|
||||
if (res)
|
||||
{
|
||||
return httpd_resp_send_500(req);
|
||||
}
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
return httpd_resp_send(req, NULL, 0);
|
||||
}
|
||||
|
||||
static int print_reg(char *p, sensor_t *s, uint16_t reg, uint32_t mask)
|
||||
{
|
||||
return sprintf(p, "\"0x%x\":%u,", reg, s->get_reg(s, reg, mask));
|
||||
}
|
||||
|
||||
static esp_err_t status_handler(httpd_req_t *req)
|
||||
{
|
||||
static char json_response[1024];
|
||||
|
||||
sensor_t *s = esp_camera_sensor_get();
|
||||
char *p = json_response;
|
||||
*p++ = '{';
|
||||
|
||||
if (s->id.PID == OV5640_PID || s->id.PID == OV3660_PID)
|
||||
{
|
||||
for (int reg = 0x3400; reg < 0x3406; reg += 2)
|
||||
{
|
||||
p += print_reg(p, s, reg, 0xFFF); //12 bit
|
||||
}
|
||||
p += print_reg(p, s, 0x3406, 0xFF);
|
||||
|
||||
p += print_reg(p, s, 0x3500, 0xFFFF0); //16 bit
|
||||
p += print_reg(p, s, 0x3503, 0xFF);
|
||||
p += print_reg(p, s, 0x350a, 0x3FF); //10 bit
|
||||
p += print_reg(p, s, 0x350c, 0xFFFF); //16 bit
|
||||
|
||||
for (int reg = 0x5480; reg <= 0x5490; reg++)
|
||||
{
|
||||
p += print_reg(p, s, reg, 0xFF);
|
||||
}
|
||||
|
||||
for (int reg = 0x5380; reg <= 0x538b; reg++)
|
||||
{
|
||||
p += print_reg(p, s, reg, 0xFF);
|
||||
}
|
||||
|
||||
for (int reg = 0x5580; reg < 0x558a; reg++)
|
||||
{
|
||||
p += print_reg(p, s, reg, 0xFF);
|
||||
}
|
||||
p += print_reg(p, s, 0x558a, 0x1FF); //9 bit
|
||||
}
|
||||
else
|
||||
{
|
||||
p += print_reg(p, s, 0xd3, 0xFF);
|
||||
p += print_reg(p, s, 0x111, 0xFF);
|
||||
p += print_reg(p, s, 0x132, 0xFF);
|
||||
}
|
||||
|
||||
p += sprintf(p, "\"board\":\"%s\",", CAMERA_MODULE_NAME);
|
||||
p += sprintf(p, "\"xclk\":%u,", s->xclk_freq_hz / 1000000);
|
||||
p += sprintf(p, "\"pixformat\":%u,", s->pixformat);
|
||||
p += sprintf(p, "\"framesize\":%u,", s->status.framesize);
|
||||
p += sprintf(p, "\"quality\":%u,", s->status.quality);
|
||||
p += sprintf(p, "\"brightness\":%d,", s->status.brightness);
|
||||
p += sprintf(p, "\"contrast\":%d,", s->status.contrast);
|
||||
p += sprintf(p, "\"saturation\":%d,", s->status.saturation);
|
||||
p += sprintf(p, "\"sharpness\":%d,", s->status.sharpness);
|
||||
p += sprintf(p, "\"special_effect\":%u,", s->status.special_effect);
|
||||
p += sprintf(p, "\"wb_mode\":%u,", s->status.wb_mode);
|
||||
p += sprintf(p, "\"awb\":%u,", s->status.awb);
|
||||
p += sprintf(p, "\"awb_gain\":%u,", s->status.awb_gain);
|
||||
p += sprintf(p, "\"aec\":%u,", s->status.aec);
|
||||
p += sprintf(p, "\"aec2\":%u,", s->status.aec2);
|
||||
p += sprintf(p, "\"ae_level\":%d,", s->status.ae_level);
|
||||
p += sprintf(p, "\"aec_value\":%u,", s->status.aec_value);
|
||||
p += sprintf(p, "\"agc\":%u,", s->status.agc);
|
||||
p += sprintf(p, "\"agc_gain\":%u,", s->status.agc_gain);
|
||||
p += sprintf(p, "\"gainceiling\":%u,", s->status.gainceiling);
|
||||
p += sprintf(p, "\"bpc\":%u,", s->status.bpc);
|
||||
p += sprintf(p, "\"wpc\":%u,", s->status.wpc);
|
||||
p += sprintf(p, "\"raw_gma\":%u,", s->status.raw_gma);
|
||||
p += sprintf(p, "\"lenc\":%u,", s->status.lenc);
|
||||
p += sprintf(p, "\"hmirror\":%u,", s->status.hmirror);
|
||||
p += sprintf(p, "\"dcw\":%u,", s->status.dcw);
|
||||
p += sprintf(p, "\"colorbar\":%u", s->status.colorbar);
|
||||
#ifdef CONFIG_LED_ILLUMINATOR_ENABLED
|
||||
p += sprintf(p, ",\"led_intensity\":%u", led_duty);
|
||||
#else
|
||||
p += sprintf(p, ",\"led_intensity\":%d", -1);
|
||||
#endif
|
||||
p += sprintf(p, ",\"face_detect\":%u", detection_enabled);
|
||||
p += sprintf(p, ",\"face_enroll\":%u,", is_enrolling);
|
||||
p += sprintf(p, "\"face_recognize\":%u", recognition_enabled);
|
||||
*p++ = '}';
|
||||
*p++ = 0;
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
return httpd_resp_send(req, json_response, strlen(json_response));
|
||||
}
|
||||
|
||||
static esp_err_t mdns_handler(httpd_req_t *req)
|
||||
{
|
||||
size_t json_len = 0;
|
||||
const char *json_response = app_mdns_query(&json_len);
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
return httpd_resp_send(req, json_response, json_len);
|
||||
}
|
||||
|
||||
static esp_err_t xclk_handler(httpd_req_t *req)
|
||||
{
|
||||
char *buf = NULL;
|
||||
char _xclk[32];
|
||||
|
||||
if (parse_get(req, &buf) != ESP_OK ||
|
||||
httpd_query_key_value(buf, "xclk", _xclk, sizeof(_xclk)) != ESP_OK)
|
||||
{
|
||||
free(buf);
|
||||
httpd_resp_send_404(req);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
free(buf);
|
||||
|
||||
int xclk = atoi(_xclk);
|
||||
ESP_LOGI(TAG, "Set XCLK: %d MHz", xclk);
|
||||
|
||||
sensor_t *s = esp_camera_sensor_get();
|
||||
int res = s->set_xclk(s, LEDC_TIMER_0, xclk);
|
||||
if (res)
|
||||
{
|
||||
return httpd_resp_send_500(req);
|
||||
}
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
return httpd_resp_send(req, NULL, 0);
|
||||
}
|
||||
|
||||
static esp_err_t reg_handler(httpd_req_t *req)
|
||||
{
|
||||
char *buf = NULL;
|
||||
char _reg[32];
|
||||
char _mask[32];
|
||||
char _val[32];
|
||||
|
||||
if (parse_get(req, &buf) != ESP_OK ||
|
||||
httpd_query_key_value(buf, "reg", _reg, sizeof(_reg)) != ESP_OK ||
|
||||
httpd_query_key_value(buf, "mask", _mask, sizeof(_mask)) != ESP_OK ||
|
||||
httpd_query_key_value(buf, "val", _val, sizeof(_val)) != ESP_OK)
|
||||
{
|
||||
free(buf);
|
||||
httpd_resp_send_404(req);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
free(buf);
|
||||
|
||||
int reg = atoi(_reg);
|
||||
int mask = atoi(_mask);
|
||||
int val = atoi(_val);
|
||||
ESP_LOGI(TAG, "Set Register: reg: 0x%02x, mask: 0x%02x, value: 0x%02x", reg, mask, val);
|
||||
|
||||
sensor_t *s = esp_camera_sensor_get();
|
||||
int res = s->set_reg(s, reg, mask, val);
|
||||
if (res)
|
||||
{
|
||||
return httpd_resp_send_500(req);
|
||||
}
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
return httpd_resp_send(req, NULL, 0);
|
||||
}
|
||||
|
||||
static esp_err_t greg_handler(httpd_req_t *req)
|
||||
{
|
||||
char *buf = NULL;
|
||||
char _reg[32];
|
||||
char _mask[32];
|
||||
|
||||
if (parse_get(req, &buf) != ESP_OK ||
|
||||
httpd_query_key_value(buf, "reg", _reg, sizeof(_reg)) != ESP_OK ||
|
||||
httpd_query_key_value(buf, "mask", _mask, sizeof(_mask)) != ESP_OK)
|
||||
{
|
||||
free(buf);
|
||||
httpd_resp_send_404(req);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
free(buf);
|
||||
|
||||
int reg = atoi(_reg);
|
||||
int mask = atoi(_mask);
|
||||
sensor_t *s = esp_camera_sensor_get();
|
||||
int res = s->get_reg(s, reg, mask);
|
||||
if (res < 0)
|
||||
{
|
||||
return httpd_resp_send_500(req);
|
||||
}
|
||||
ESP_LOGI(TAG, "Get Register: reg: 0x%02x, mask: 0x%02x, value: 0x%02x", reg, mask, res);
|
||||
|
||||
char buffer[20];
|
||||
const char *val = itoa(res, buffer, 10);
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
return httpd_resp_send(req, val, strlen(val));
|
||||
}
|
||||
|
||||
static int parse_get_var(char *buf, const char *key, int def)
|
||||
{
|
||||
char _int[16];
|
||||
if (httpd_query_key_value(buf, key, _int, sizeof(_int)) != ESP_OK)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
return atoi(_int);
|
||||
}
|
||||
|
||||
static esp_err_t pll_handler(httpd_req_t *req)
|
||||
{
|
||||
char *buf = NULL;
|
||||
|
||||
if (parse_get(req, &buf) != ESP_OK)
|
||||
{
|
||||
free(buf);
|
||||
httpd_resp_send_404(req);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
int bypass = parse_get_var(buf, "bypass", 0);
|
||||
int mul = parse_get_var(buf, "mul", 0);
|
||||
int sys = parse_get_var(buf, "sys", 0);
|
||||
int root = parse_get_var(buf, "root", 0);
|
||||
int pre = parse_get_var(buf, "pre", 0);
|
||||
int seld5 = parse_get_var(buf, "seld5", 0);
|
||||
int pclken = parse_get_var(buf, "pclken", 0);
|
||||
int pclk = parse_get_var(buf, "pclk", 0);
|
||||
free(buf);
|
||||
|
||||
ESP_LOGI(TAG, "Set Pll: bypass: %d, mul: %d, sys: %d, root: %d, pre: %d, seld5: %d, pclken: %d, pclk: %d", bypass, mul, sys, root, pre, seld5, pclken, pclk);
|
||||
sensor_t *s = esp_camera_sensor_get();
|
||||
int res = s->set_pll(s, bypass, mul, sys, root, pre, seld5, pclken, pclk);
|
||||
if (res)
|
||||
{
|
||||
return httpd_resp_send_500(req);
|
||||
}
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
return httpd_resp_send(req, NULL, 0);
|
||||
}
|
||||
|
||||
static esp_err_t win_handler(httpd_req_t *req)
|
||||
{
|
||||
char *buf = NULL;
|
||||
|
||||
if (parse_get(req, &buf) != ESP_OK)
|
||||
{
|
||||
free(buf);
|
||||
httpd_resp_send_404(req);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
int startX = parse_get_var(buf, "sx", 0);
|
||||
int startY = parse_get_var(buf, "sy", 0);
|
||||
int endX = parse_get_var(buf, "ex", 0);
|
||||
int endY = parse_get_var(buf, "ey", 0);
|
||||
int offsetX = parse_get_var(buf, "offx", 0);
|
||||
int offsetY = parse_get_var(buf, "offy", 0);
|
||||
int totalX = parse_get_var(buf, "tx", 0);
|
||||
int totalY = parse_get_var(buf, "ty", 0);
|
||||
int outputX = parse_get_var(buf, "ox", 0);
|
||||
int outputY = parse_get_var(buf, "oy", 0);
|
||||
bool scale = parse_get_var(buf, "scale", 0) == 1;
|
||||
bool binning = parse_get_var(buf, "binning", 0) == 1;
|
||||
free(buf);
|
||||
|
||||
ESP_LOGI(TAG, "Set Window: Start: %d %d, End: %d %d, Offset: %d %d, Total: %d %d, Output: %d %d, Scale: %u, Binning: %u", startX, startY, endX, endY, offsetX, offsetY, totalX, totalY, outputX, outputY, scale, binning);
|
||||
sensor_t *s = esp_camera_sensor_get();
|
||||
int res = s->set_res_raw(s, startX, startY, endX, endY, offsetX, offsetY, totalX, totalY, outputX, outputY, scale, binning);
|
||||
if (res)
|
||||
{
|
||||
return httpd_resp_send_500(req);
|
||||
}
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
return httpd_resp_send(req, NULL, 0);
|
||||
}
|
||||
|
||||
static esp_err_t index_handler(httpd_req_t *req)
|
||||
{
|
||||
extern const unsigned char index_ov2640_html_gz_start[] asm("_binary_index_ov2640_html_gz_start");
|
||||
extern const unsigned char index_ov2640_html_gz_end[] asm("_binary_index_ov2640_html_gz_end");
|
||||
size_t index_ov2640_html_gz_len = index_ov2640_html_gz_end - index_ov2640_html_gz_start;
|
||||
|
||||
extern const unsigned char index_ov3660_html_gz_start[] asm("_binary_index_ov3660_html_gz_start");
|
||||
extern const unsigned char index_ov3660_html_gz_end[] asm("_binary_index_ov3660_html_gz_end");
|
||||
size_t index_ov3660_html_gz_len = index_ov3660_html_gz_end - index_ov3660_html_gz_start;
|
||||
|
||||
extern const unsigned char index_ov5640_html_gz_start[] asm("_binary_index_ov5640_html_gz_start");
|
||||
extern const unsigned char index_ov5640_html_gz_end[] asm("_binary_index_ov5640_html_gz_end");
|
||||
size_t index_ov5640_html_gz_len = index_ov5640_html_gz_end - index_ov5640_html_gz_start;
|
||||
|
||||
httpd_resp_set_type(req, "text/html");
|
||||
httpd_resp_set_hdr(req, "Content-Encoding", "gzip");
|
||||
sensor_t *s = esp_camera_sensor_get();
|
||||
if (s != NULL)
|
||||
{
|
||||
if (s->id.PID == OV3660_PID)
|
||||
{
|
||||
return httpd_resp_send(req, (const char *)index_ov3660_html_gz_start, index_ov3660_html_gz_len);
|
||||
}
|
||||
else if (s->id.PID == OV5640_PID)
|
||||
{
|
||||
return httpd_resp_send(req, (const char *)index_ov5640_html_gz_start, index_ov5640_html_gz_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
return httpd_resp_send(req, (const char *)index_ov2640_html_gz_start, index_ov2640_html_gz_len);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "Camera sensor not found");
|
||||
return httpd_resp_send_500(req);
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t monitor_handler(httpd_req_t *req)
|
||||
{
|
||||
extern const unsigned char monitor_html_gz_start[] asm("_binary_monitor_html_gz_start");
|
||||
extern const unsigned char monitor_html_gz_end[] asm("_binary_monitor_html_gz_end");
|
||||
size_t monitor_html_gz_len = monitor_html_gz_end - monitor_html_gz_start;
|
||||
httpd_resp_set_type(req, "text/html");
|
||||
httpd_resp_set_hdr(req, "Content-Encoding", "gzip");
|
||||
return httpd_resp_send(req, (const char *)monitor_html_gz_start, monitor_html_gz_len);
|
||||
}
|
||||
|
||||
void register_httpd(const QueueHandle_t frame_i, const QueueHandle_t frame_o, const bool return_fb)
|
||||
{
|
||||
xQueueFrameI = frame_i;
|
||||
xQueueFrameO = frame_o;
|
||||
gReturnFB = return_fb;
|
||||
|
||||
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
||||
config.max_uri_handlers = 12;
|
||||
|
||||
httpd_uri_t index_uri = {
|
||||
.uri = "/",
|
||||
.method = HTTP_GET,
|
||||
.handler = index_handler,
|
||||
.user_ctx = NULL};
|
||||
|
||||
httpd_uri_t status_uri = {
|
||||
.uri = "/status",
|
||||
.method = HTTP_GET,
|
||||
.handler = status_handler,
|
||||
.user_ctx = NULL};
|
||||
|
||||
httpd_uri_t cmd_uri = {
|
||||
.uri = "/control",
|
||||
.method = HTTP_GET,
|
||||
.handler = cmd_handler,
|
||||
.user_ctx = NULL};
|
||||
|
||||
httpd_uri_t capture_uri = {
|
||||
.uri = "/capture",
|
||||
.method = HTTP_GET,
|
||||
.handler = capture_handler,
|
||||
.user_ctx = NULL};
|
||||
|
||||
httpd_uri_t stream_uri = {
|
||||
.uri = "/stream",
|
||||
.method = HTTP_GET,
|
||||
.handler = stream_handler,
|
||||
.user_ctx = NULL};
|
||||
|
||||
httpd_uri_t xclk_uri = {
|
||||
.uri = "/xclk",
|
||||
.method = HTTP_GET,
|
||||
.handler = xclk_handler,
|
||||
.user_ctx = NULL};
|
||||
|
||||
httpd_uri_t reg_uri = {
|
||||
.uri = "/reg",
|
||||
.method = HTTP_GET,
|
||||
.handler = reg_handler,
|
||||
.user_ctx = NULL};
|
||||
|
||||
httpd_uri_t greg_uri = {
|
||||
.uri = "/greg",
|
||||
.method = HTTP_GET,
|
||||
.handler = greg_handler,
|
||||
.user_ctx = NULL};
|
||||
|
||||
httpd_uri_t pll_uri = {
|
||||
.uri = "/pll",
|
||||
.method = HTTP_GET,
|
||||
.handler = pll_handler,
|
||||
.user_ctx = NULL};
|
||||
|
||||
httpd_uri_t win_uri = {
|
||||
.uri = "/resolution",
|
||||
.method = HTTP_GET,
|
||||
.handler = win_handler,
|
||||
.user_ctx = NULL};
|
||||
|
||||
httpd_uri_t mdns_uri = {
|
||||
.uri = "/mdns",
|
||||
.method = HTTP_GET,
|
||||
.handler = mdns_handler,
|
||||
.user_ctx = NULL};
|
||||
|
||||
httpd_uri_t monitor_uri = {
|
||||
.uri = "/monitor",
|
||||
.method = HTTP_GET,
|
||||
.handler = monitor_handler,
|
||||
.user_ctx = NULL};
|
||||
|
||||
ESP_LOGI(TAG, "Starting web server on port: '%d'", config.server_port);
|
||||
if (httpd_start(&camera_httpd, &config) == ESP_OK)
|
||||
{
|
||||
httpd_register_uri_handler(camera_httpd, &index_uri);
|
||||
httpd_register_uri_handler(camera_httpd, &cmd_uri);
|
||||
httpd_register_uri_handler(camera_httpd, &status_uri);
|
||||
httpd_register_uri_handler(camera_httpd, &capture_uri);
|
||||
|
||||
httpd_register_uri_handler(camera_httpd, &xclk_uri);
|
||||
httpd_register_uri_handler(camera_httpd, ®_uri);
|
||||
httpd_register_uri_handler(camera_httpd, &greg_uri);
|
||||
httpd_register_uri_handler(camera_httpd, &pll_uri);
|
||||
httpd_register_uri_handler(camera_httpd, &win_uri);
|
||||
|
||||
httpd_register_uri_handler(camera_httpd, &mdns_uri);
|
||||
httpd_register_uri_handler(camera_httpd, &monitor_uri);
|
||||
}
|
||||
|
||||
config.server_port += 1;
|
||||
config.ctrl_port += 1;
|
||||
ESP_LOGI(TAG, "Starting stream server on port: '%d'", config.server_port);
|
||||
if (httpd_start(&stream_httpd, &config) == ESP_OK)
|
||||
{
|
||||
httpd_register_uri_handler(stream_httpd, &stream_uri);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
void register_httpd(const QueueHandle_t frame_i, const QueueHandle_t frame_o, const bool return_fb);
|
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* ESPRESSIF MIT License
|
||||
*
|
||||
* Copyright (c) 2020 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
|
||||
*
|
||||
* Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case,
|
||||
* it is free of charge, to any person obtaining a copy of this software and associated
|
||||
* documentation files (the "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished
|
||||
* to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_camera.h"
|
||||
#include "mdns.h"
|
||||
#include "who_camera.h"
|
||||
|
||||
static const char *TAG = "camera mdns";
|
||||
|
||||
static const char * service_name = "_esp-cam";
|
||||
static const char * proto = "_tcp";
|
||||
static mdns_result_t * found_cams = NULL;
|
||||
static SemaphoreHandle_t query_lock = NULL;
|
||||
static char iname[64];
|
||||
static char hname[64];
|
||||
static char framesize[4];
|
||||
static char pixformat[4];
|
||||
static const char * model = NULL;
|
||||
|
||||
static void mdns_query_for_cams()
|
||||
{
|
||||
mdns_result_t * new_cams = NULL;
|
||||
esp_err_t err = mdns_query_ptr(service_name, proto, 5000, 4, &new_cams);
|
||||
if(err){
|
||||
ESP_LOGE(TAG, "MDNS Query Failed: %s", esp_err_to_name(err));
|
||||
return;
|
||||
}
|
||||
xSemaphoreTake(query_lock, portMAX_DELAY);
|
||||
if (found_cams != NULL) {
|
||||
mdns_query_results_free(found_cams);
|
||||
}
|
||||
found_cams = new_cams;
|
||||
xSemaphoreGive(query_lock);
|
||||
}
|
||||
|
||||
static void mdns_task(void * arg)
|
||||
{
|
||||
for (;;) {
|
||||
mdns_query_for_cams();
|
||||
//delay 55 seconds
|
||||
vTaskDelay((55 * 1000) / portTICK_PERIOD_MS);
|
||||
}
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Public Functions
|
||||
*/
|
||||
|
||||
const char * app_mdns_query(size_t * out_len)
|
||||
{
|
||||
//build JSON
|
||||
static char json_response[2048];
|
||||
char *p = json_response;
|
||||
*p++ = '[';
|
||||
|
||||
//add own data first
|
||||
tcpip_adapter_ip_info_t ip;
|
||||
if (strlen(CONFIG_ESP_WIFI_SSID)) {
|
||||
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip);
|
||||
} else {
|
||||
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip);
|
||||
}
|
||||
*p++ = '{';
|
||||
p += sprintf(p, "\"instance\":\"%s\",", iname);
|
||||
p += sprintf(p, "\"host\":\"%s.local\",", hname);
|
||||
p += sprintf(p, "\"port\":80,");
|
||||
p += sprintf(p, "\"txt\":{");
|
||||
p += sprintf(p, "\"pixformat\":\"%s\",", pixformat);
|
||||
p += sprintf(p, "\"framesize\":\"%s\",", framesize);
|
||||
p += sprintf(p, "\"stream_port\":\"81\",");
|
||||
p += sprintf(p, "\"board\":\"%s\",", CAMERA_MODULE_NAME);
|
||||
p += sprintf(p, "\"model\":\"%s\"", model);
|
||||
*p++ = '}';
|
||||
*p++ = ',';
|
||||
p += sprintf(p, "\"ip\":\"" IPSTR "\",", IP2STR(&(ip.ip)));
|
||||
p += sprintf(p, "\"id\":\"" IPSTR ":80\",", IP2STR(&(ip.ip)));
|
||||
p += sprintf(p, "\"service\":\"%s\",", service_name);
|
||||
p += sprintf(p, "\"proto\":\"%s\"", proto);
|
||||
*p++ = '}';
|
||||
|
||||
xSemaphoreTake(query_lock, portMAX_DELAY);
|
||||
if (found_cams) {
|
||||
*p++ = ',';
|
||||
}
|
||||
mdns_result_t * r = found_cams;
|
||||
mdns_ip_addr_t * a = NULL;
|
||||
int t;
|
||||
while(r){
|
||||
*p++ = '{';
|
||||
if(r->instance_name){
|
||||
p += sprintf(p, "\"instance\":\"%s\",", r->instance_name);
|
||||
}
|
||||
if(r->hostname){
|
||||
p += sprintf(p, "\"host\":\"%s.local\",", r->hostname);
|
||||
p += sprintf(p, "\"port\":%u,", r->port);
|
||||
}
|
||||
if(r->txt_count){
|
||||
p += sprintf(p, "\"txt\":{");
|
||||
for(t=0; t<r->txt_count; t++){
|
||||
if (t > 0) {
|
||||
*p++ = ',';
|
||||
}
|
||||
p += sprintf(p, "\"%s\":\"%s\"", r->txt[t].key, r->txt[t].value?r->txt[t].value:"NULL");
|
||||
}
|
||||
*p++ = '}';
|
||||
*p++ = ',';
|
||||
}
|
||||
a = r->addr;
|
||||
while(a){
|
||||
if(a->addr.type != IPADDR_TYPE_V6){
|
||||
p += sprintf(p, "\"ip\":\"" IPSTR "\",", IP2STR(&(a->addr.u_addr.ip4)));
|
||||
p += sprintf(p, "\"id\":\"" IPSTR ":%u\",", IP2STR(&(a->addr.u_addr.ip4)), r->port);
|
||||
break;
|
||||
}
|
||||
a = a->next;
|
||||
}
|
||||
p += sprintf(p, "\"service\":\"%s\",", service_name);
|
||||
p += sprintf(p, "\"proto\":\"%s\"", proto);
|
||||
*p++ = '}';
|
||||
r = r->next;
|
||||
if (r) {
|
||||
*p++ = ',';
|
||||
}
|
||||
}
|
||||
xSemaphoreGive(query_lock);
|
||||
*p++ = ']';
|
||||
*out_len = (uint32_t)p - (uint32_t)json_response;
|
||||
*p++ = '\0';
|
||||
ESP_LOGI(TAG, "JSON: %uB", *out_len);
|
||||
return (const char *)json_response;
|
||||
}
|
||||
|
||||
void app_mdns_update_framesize(int size)
|
||||
{
|
||||
snprintf(framesize, 4, "%d", size);
|
||||
if(mdns_service_txt_item_set(service_name, proto, "framesize", (char*)framesize)){
|
||||
ESP_LOGE(TAG, "mdns_service_txt_item_set() framesize Failed");
|
||||
}
|
||||
}
|
||||
|
||||
void app_mdns_main()
|
||||
{
|
||||
uint8_t mac[6];
|
||||
|
||||
query_lock = xSemaphoreCreateBinary();
|
||||
if (query_lock == NULL) {
|
||||
ESP_LOGE(TAG, "xSemaphoreCreateMutex() Failed");
|
||||
return;
|
||||
}
|
||||
xSemaphoreGive(query_lock);
|
||||
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
if(s == NULL){
|
||||
return;
|
||||
}
|
||||
switch(s->id.PID){
|
||||
case OV2640_PID: model = "OV2640"; break;
|
||||
case OV3660_PID: model = "OV3660"; break;
|
||||
case OV5640_PID: model = "OV5640"; break;
|
||||
case OV7725_PID: model = "OV7725"; break;
|
||||
default: model = "UNKNOWN"; break;
|
||||
}
|
||||
|
||||
if (strlen(CONFIG_ESP_HOST_NAME) > 0) {
|
||||
snprintf(iname, 64, "%s", CONFIG_ESP_HOST_NAME);
|
||||
} else {
|
||||
if (esp_read_mac(mac, ESP_MAC_WIFI_STA) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "esp_read_mac() Failed");
|
||||
return;
|
||||
}
|
||||
snprintf(iname, 64, "%s-%s-%02X%02X%02X", CAMERA_MODULE_NAME, model, mac[3], mac[4], mac[5]);
|
||||
}
|
||||
|
||||
snprintf(framesize, 4, "%d", s->status.framesize);
|
||||
snprintf(pixformat, 4, "%d", s->pixformat);
|
||||
|
||||
char * src = iname, * dst = hname, c;
|
||||
while (*src) {
|
||||
c = *src++;
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
c -= 'A' - 'a';
|
||||
}
|
||||
*dst++ = c;
|
||||
}
|
||||
*dst++ = '\0';
|
||||
|
||||
if(mdns_init() != ESP_OK){
|
||||
ESP_LOGE(TAG, "mdns_init() Failed");
|
||||
return;
|
||||
}
|
||||
|
||||
if(mdns_hostname_set(hname) != ESP_OK){
|
||||
ESP_LOGE(TAG, "mdns_hostname_set(\"%s\") Failed", hname);
|
||||
return;
|
||||
}
|
||||
|
||||
if(mdns_instance_name_set(iname) != ESP_OK){
|
||||
ESP_LOGE(TAG, "mdns_instance_name_set(\"%s\") Failed", iname);
|
||||
return;
|
||||
}
|
||||
|
||||
if(mdns_service_add(NULL, "_http", "_tcp", 80, NULL, 0) != ESP_OK){
|
||||
ESP_LOGE(TAG, "mdns_service_add() HTTP Failed");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
mdns_txt_item_t camera_txt_data[] = {
|
||||
{(char*)"board" ,(char*)CAMERA_MODULE_NAME},
|
||||
{(char*)"model" ,(char*)model},
|
||||
{(char*)"stream_port" ,(char*)"81"},
|
||||
{(char*)"framesize" ,(char*)framesize},
|
||||
{(char*)"pixformat" ,(char*)pixformat}
|
||||
};
|
||||
|
||||
if(mdns_service_add(NULL, service_name, proto, 80, camera_txt_data, 5)) {
|
||||
ESP_LOGE(TAG, "mdns_service_add() ESP-CAM Failed");
|
||||
return;
|
||||
}
|
||||
|
||||
xTaskCreate(mdns_task, "mdns-cam", 2048, NULL, 2, NULL);
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
void app_mdns_main();
|
||||
void app_mdns_update_framesize(int size);
|
||||
const char *app_mdns_query(size_t *out_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,196 @@
|
|||
/* ESPRESSIF MIT License
|
||||
*
|
||||
* Copyright (c) 2018 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
|
||||
*
|
||||
* Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case,
|
||||
* it is free of charge, to any person obtaining a copy of this software and associated
|
||||
* documentation files (the "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished
|
||||
* to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_event_loop.h"
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/sys.h"
|
||||
|
||||
#include "mdns.h"
|
||||
|
||||
/* The examples use WiFi configuration that you can set via 'make menuconfig'.
|
||||
|
||||
If you'd rather not, just change the below entries to strings with
|
||||
the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
|
||||
*/
|
||||
#define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID
|
||||
#define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD
|
||||
#define EXAMPLE_ESP_MAXIMUM_RETRY CONFIG_ESP_MAXIMUM_RETRY
|
||||
#define EXAMPLE_ESP_WIFI_AP_SSID CONFIG_ESP_WIFI_AP_SSID
|
||||
#define EXAMPLE_ESP_WIFI_AP_PASS CONFIG_ESP_WIFI_AP_PASSWORD
|
||||
#define EXAMPLE_MAX_STA_CONN CONFIG_MAX_STA_CONN
|
||||
#define EXAMPLE_IP_ADDR CONFIG_SERVER_IP
|
||||
#define EXAMPLE_ESP_WIFI_AP_CHANNEL CONFIG_ESP_WIFI_AP_CHANNEL
|
||||
|
||||
static const char *TAG = "camera wifi";
|
||||
|
||||
static int s_retry_num = 0;
|
||||
|
||||
static esp_err_t event_handler(void *ctx, system_event_t *event)
|
||||
{
|
||||
switch (event->event_id)
|
||||
{
|
||||
case SYSTEM_EVENT_AP_STACONNECTED:
|
||||
ESP_LOGI(TAG, "station:" MACSTR " join, AID=%d",
|
||||
MAC2STR(event->event_info.sta_connected.mac),
|
||||
event->event_info.sta_connected.aid);
|
||||
break;
|
||||
case SYSTEM_EVENT_AP_STADISCONNECTED:
|
||||
ESP_LOGI(TAG, "station:" MACSTR "leave, AID=%d",
|
||||
MAC2STR(event->event_info.sta_disconnected.mac),
|
||||
event->event_info.sta_disconnected.aid);
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_START:
|
||||
esp_wifi_connect();
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_GOT_IP:
|
||||
ESP_LOGI(TAG, "got ip:%s",
|
||||
ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
|
||||
s_retry_num = 0;
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_DISCONNECTED:
|
||||
{
|
||||
if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY)
|
||||
{
|
||||
esp_wifi_connect();
|
||||
s_retry_num++;
|
||||
ESP_LOGI(TAG, "retry to connect to the AP");
|
||||
}
|
||||
ESP_LOGI(TAG, "connect to the AP fail");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mdns_handle_system_event(ctx, event);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void wifi_init_softap()
|
||||
{
|
||||
if (strcmp(EXAMPLE_IP_ADDR, "192.168.4.1"))
|
||||
{
|
||||
int a, b, c, d;
|
||||
sscanf(EXAMPLE_IP_ADDR, "%d.%d.%d.%d", &a, &b, &c, &d);
|
||||
tcpip_adapter_ip_info_t ip_info;
|
||||
IP4_ADDR(&ip_info.ip, a, b, c, d);
|
||||
IP4_ADDR(&ip_info.gw, a, b, c, d);
|
||||
IP4_ADDR(&ip_info.netmask, 255, 255, 255, 0);
|
||||
ESP_ERROR_CHECK(tcpip_adapter_dhcps_stop(WIFI_IF_AP));
|
||||
ESP_ERROR_CHECK(tcpip_adapter_set_ip_info(WIFI_IF_AP, &ip_info));
|
||||
ESP_ERROR_CHECK(tcpip_adapter_dhcps_start(WIFI_IF_AP));
|
||||
}
|
||||
wifi_config_t wifi_config;
|
||||
memset(&wifi_config, 0, sizeof(wifi_config_t));
|
||||
snprintf((char *)wifi_config.ap.ssid, 32, "%s", EXAMPLE_ESP_WIFI_AP_SSID);
|
||||
wifi_config.ap.ssid_len = strlen((char *)wifi_config.ap.ssid);
|
||||
snprintf((char *)wifi_config.ap.password, 64, "%s", EXAMPLE_ESP_WIFI_AP_PASS);
|
||||
wifi_config.ap.max_connection = EXAMPLE_MAX_STA_CONN;
|
||||
wifi_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK;
|
||||
if (strlen(EXAMPLE_ESP_WIFI_AP_PASS) == 0)
|
||||
{
|
||||
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
|
||||
}
|
||||
if (strlen(EXAMPLE_ESP_WIFI_AP_CHANNEL))
|
||||
{
|
||||
int channel;
|
||||
sscanf(EXAMPLE_ESP_WIFI_AP_CHANNEL, "%d", &channel);
|
||||
wifi_config.ap.channel = channel;
|
||||
}
|
||||
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config));
|
||||
|
||||
ESP_LOGI(TAG, "wifi_init_softap finished.SSID:%s password:%s",
|
||||
EXAMPLE_ESP_WIFI_AP_SSID, EXAMPLE_ESP_WIFI_AP_PASS);
|
||||
}
|
||||
|
||||
void wifi_init_sta()
|
||||
{
|
||||
wifi_config_t wifi_config;
|
||||
memset(&wifi_config, 0, sizeof(wifi_config_t));
|
||||
snprintf((char *)wifi_config.sta.ssid, 32, "%s", EXAMPLE_ESP_WIFI_SSID);
|
||||
snprintf((char *)wifi_config.sta.password, 64, "%s", EXAMPLE_ESP_WIFI_PASS);
|
||||
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
|
||||
|
||||
ESP_LOGI(TAG, "wifi_init_sta finished.");
|
||||
ESP_LOGI(TAG, "connect to ap SSID:%s password:%s",
|
||||
EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
|
||||
}
|
||||
|
||||
void app_wifi_main()
|
||||
{
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
wifi_mode_t mode = WIFI_MODE_NULL;
|
||||
|
||||
if (strlen(EXAMPLE_ESP_WIFI_AP_SSID) && strlen(EXAMPLE_ESP_WIFI_SSID))
|
||||
{
|
||||
mode = WIFI_MODE_APSTA;
|
||||
}
|
||||
else if (strlen(EXAMPLE_ESP_WIFI_AP_SSID))
|
||||
{
|
||||
mode = WIFI_MODE_AP;
|
||||
}
|
||||
else if (strlen(EXAMPLE_ESP_WIFI_SSID))
|
||||
{
|
||||
mode = WIFI_MODE_STA;
|
||||
}
|
||||
|
||||
esp_err_t ret = nvs_flash_init();
|
||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
|
||||
{
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
ret = nvs_flash_init();
|
||||
}
|
||||
ESP_ERROR_CHECK(ret);
|
||||
|
||||
if (mode == WIFI_MODE_NULL)
|
||||
{
|
||||
ESP_LOGW(TAG, "Neither AP or STA have been configured. WiFi will be off.");
|
||||
return;
|
||||
}
|
||||
|
||||
tcpip_adapter_init();
|
||||
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
|
||||
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(mode));
|
||||
|
||||
if (mode & WIFI_MODE_AP)
|
||||
{
|
||||
wifi_init_softap();
|
||||
}
|
||||
|
||||
if (mode & WIFI_MODE_STA)
|
||||
{
|
||||
wifi_init_sta();
|
||||
}
|
||||
ESP_ERROR_CHECK(esp_wifi_start());
|
||||
ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE));
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* ESPRESSIF MIT License
|
||||
*
|
||||
* Copyright (c) 2017 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
|
||||
*
|
||||
* Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case,
|
||||
* it is free of charge, to any person obtaining a copy of this software and associated
|
||||
* documentation files (the "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished
|
||||
* to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef _APP_WIFI_H_
|
||||
#define _APP_WIFI_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void app_wifi_main();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
for file in `ls *.html`; do
|
||||
echo "Compressing: $file"
|
||||
cp "$file" "copy_$file" && \
|
||||
gzip -f "$file" && \
|
||||
mv "copy_$file" "$file"
|
||||
done
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Loading…
Reference in New Issue