mirror of
https://git.mirrors.martin98.com/https://github.com/luc-github/ESP3D.git
synced 2025-08-04 12:51:39 +08:00
Add ESP171 which save camera frame to SD
This commit is contained in:
parent
fa20ebcec7
commit
ab9f3c1236
@ -82,7 +82,10 @@ The json format is {
|
||||
|
||||
* Get/Set Camera command value / list all values in JSON/plain
|
||||
label can be: light/framesize/quality/contrast/brightness/saturation/gainceiling/colorbar/awb/agc/aec/hmirror/vflip/awb_gain/agc_gain/aec_value/aec2/cw/bpc/wpc/raw_gma/lenc/special_effect/wb_mode/ae_level
|
||||
[ESP170]<plain><label=value> json=<no> pwd=<admin password>
|
||||
[ESP170]<label=value> json=<no> pwd=<admin password>
|
||||
|
||||
* Save frame to target path and filename (default target = today date, default name=timestamp.jpg)
|
||||
[ESP171] <path=target path> <filename=target filename>
|
||||
|
||||
* Get/Set Ftp state which can be ON, OFF, CLOSE
|
||||
[ESP180]<state> json=<no> pwd=<admin password>
|
||||
|
@ -492,11 +492,16 @@ bool Commands::execute_internal_command (int cmd, const char* cmd_params, level_
|
||||
#endif //WS_DATA_FEATURE
|
||||
#ifdef CAMERA_DEVICE
|
||||
//Get/Set Camera command value / list all values in JSON/plain
|
||||
//[ESP170]label=<value>pwd=<admin password>
|
||||
//[ESP170]label=<value> pwd=<admin/user password>
|
||||
//label can be: light/framesize/quality/contrast/brightness/saturation/gainceiling/colorbar/awb/agc/aec/hmirror/vflip/awb_gain/agc_gain/aec_value/aec2/cw/bpc/wpc/raw_gma/lenc/special_effect/wb_mode/ae_level
|
||||
case 170:
|
||||
response = ESP170(cmd_params, auth_type, output);
|
||||
break;
|
||||
//Save frame to target path and filename (default target = today date, default name=timestamp.jpg)
|
||||
//[ESP171]path=<target path> filename=<target filename> pwd=<admin/user password>
|
||||
case 171:
|
||||
response = ESP171(cmd_params, auth_type, output);
|
||||
break;
|
||||
#endif //CAMERA_DEVICE
|
||||
#ifdef FTP_FEATURE
|
||||
//Set Ftp state which can be ON, OFF
|
||||
|
@ -85,6 +85,7 @@ public:
|
||||
#endif //WS_DATA_FEATURE
|
||||
#if defined(CAMERA_DEVICE)
|
||||
bool ESP170(const char* cmd_params, level_authenticate_type auth_level, ESP3DOutput * output);
|
||||
bool ESP171(const char* cmd_params, level_authenticate_type auth_level, ESP3DOutput * output);
|
||||
#endif //CAMERA_DEVICE
|
||||
#if defined(FTP_FEATURE)
|
||||
bool ESP180(const char* cmd_params, level_authenticate_type auth_level, ESP3DOutput * output);
|
||||
|
@ -67,7 +67,8 @@ const char * help[]= {"[ESP] (id) - display this help",
|
||||
"[ESP161](Port) - display/set WebSocket port",
|
||||
#endif //WS_DATA_FEATURE
|
||||
#if defined(CAMERA_DEVICE)
|
||||
"[ESP170](plain) (label=value) - display(JSON/plain)/set Camera commands",
|
||||
"[ESP170](json) (label=value) - display/set Camera commands",
|
||||
"[ESP171] (path=<target path>) (filename=<target filename>) Save frame to target path and filename",
|
||||
#endif //CAMERA_DEVICE
|
||||
#if defined(FTP_FEATURE)
|
||||
"[ESP180](State) - display/set FTP state which can be ON, OFF",
|
||||
@ -203,6 +204,7 @@ const uint cmdlist[]= {0,
|
||||
#endif //WS_DATA_FEATURE
|
||||
#if defined(CAMERA_DEVICE)
|
||||
170,
|
||||
171,
|
||||
#endif //CAMERA_DEVICE
|
||||
#if defined(FTP_FEATURE)
|
||||
180,
|
||||
|
114
esp3d/src/core/espcmd/ESP171.cpp
Normal file
114
esp3d/src/core/espcmd/ESP171.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
ESP122.cpp - ESP3D command class
|
||||
|
||||
Copyright (c) 2014 Luc Lebosse. All rights reserved.
|
||||
|
||||
This code is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with This code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "../../include/esp3d_config.h"
|
||||
#if defined (CAMERA_DEVICE)
|
||||
#include "../commands.h"
|
||||
#include "../esp3doutput.h"
|
||||
#include "esp_camera.h"
|
||||
#include "../settings_esp3d.h"
|
||||
#include "../../modules/authentication/authentication_service.h"
|
||||
#include "../../modules/camera/camera.h"
|
||||
#include <time.h>
|
||||
#define COMMANDID 171
|
||||
//Save frame to target path and filename (default target = today date, default name=timestamp.jpg)
|
||||
//[ESP171]path=<target path> filename=<target filename> pwd=<admin/user password>
|
||||
bool Commands::ESP171(const char* cmd_params, level_authenticate_type auth_type, ESP3DOutput * output)
|
||||
{
|
||||
bool noError = true;
|
||||
bool json = has_tag (cmd_params, "json");
|
||||
String response;
|
||||
String parameter;
|
||||
int errorCode = 200; //unless it is a server error use 200 as default and set error in json instead
|
||||
String path;
|
||||
String filename;
|
||||
#ifdef AUTHENTICATION_FEATURE
|
||||
if (auth_type == LEVEL_GUEST) {
|
||||
response = format_response(COMMANDID, json, false, "Guest user can't use this command");
|
||||
noError = false;
|
||||
errorCode = 401;
|
||||
}
|
||||
#else
|
||||
(void)auth_type;
|
||||
#endif //AUTHENTICATION_FEATURE
|
||||
if(noError) {
|
||||
if (!esp3d_camera.started()) {
|
||||
response = format_response(COMMANDID, json, false, "No camera initialized");
|
||||
noError = false;
|
||||
} else {
|
||||
parameter = clean_param(get_param (cmd_params, "path="));
|
||||
//get path
|
||||
if (parameter.length() != 0) {
|
||||
|
||||
path = parameter;
|
||||
}
|
||||
parameter = clean_param(get_param (cmd_params, "filename="));
|
||||
//get filename
|
||||
if (parameter.length() != 0) {
|
||||
filename = parameter;
|
||||
}
|
||||
//if nothing provided, use default filename / path
|
||||
if (path.length()==0) {
|
||||
struct tm tmstruct;
|
||||
time_t now;
|
||||
path = "";
|
||||
time(&now);
|
||||
localtime_r(&now, &tmstruct);
|
||||
path = String((tmstruct.tm_year)+1900) + "-";
|
||||
if (((tmstruct.tm_mon)+1) < 10) {
|
||||
path +="0";
|
||||
}
|
||||
path += String(( tmstruct.tm_mon)+1) + "-";
|
||||
if (tmstruct.tm_mday < 10) {
|
||||
path +="0";
|
||||
}
|
||||
path += String(tmstruct.tm_mday);
|
||||
}
|
||||
if(filename.length()==0) {
|
||||
struct tm tmstruct;
|
||||
time_t now;
|
||||
time(&now);
|
||||
localtime_r(&now, &tmstruct);
|
||||
filename = String(now) + ".jpg";
|
||||
}
|
||||
|
||||
//now send command
|
||||
if(noError) {
|
||||
noError = esp3d_camera.handle_snap(nullptr,path.c_str(), filename.c_str());
|
||||
if(noError) {
|
||||
response = format_response(COMMANDID, json, true, "Snapshot taken");
|
||||
} else {
|
||||
response = format_response(COMMANDID, json, false, "Error taking snapshot");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (noError) {
|
||||
if (json) {
|
||||
output->printLN (response.c_str() );
|
||||
} else {
|
||||
output->printMSG (response.c_str() );
|
||||
}
|
||||
} else {
|
||||
output->printERROR(response.c_str(), errorCode);
|
||||
}
|
||||
return noError;
|
||||
}
|
||||
|
||||
#endif //CAMERA_DEVICE
|
@ -22,7 +22,7 @@
|
||||
#define _VERSION_ESP3D_H
|
||||
|
||||
//version and sources location
|
||||
#define FW_VERSION "3.0.0.a200"
|
||||
#define FW_VERSION "3.0.0.a201"
|
||||
#define REPOSITORY "https://github.com/luc-github/ESP3D/tree/3.0"
|
||||
|
||||
#endif //_VERSION_ESP3D_H
|
||||
|
@ -26,8 +26,10 @@
|
||||
#include <esp_camera.h>
|
||||
#include <soc/soc.h> //not sure this one is needed
|
||||
#include <soc/rtc_cntl_reg.h>
|
||||
|
||||
#include <WebServer.h>
|
||||
#if defined (SD_DEVICE)
|
||||
#include "../filesystem/esp_sd.h"
|
||||
#endif //SD_DEVICE
|
||||
|
||||
|
||||
#define DEFAULT_FRAME_SIZE FRAMESIZE_SVGA
|
||||
@ -35,45 +37,54 @@
|
||||
|
||||
Camera esp3d_camera;
|
||||
|
||||
void Camera::handle_snap(WebServer * webserver)
|
||||
bool Camera::handle_snap(WebServer * webserver, const char *path, const char* filename)
|
||||
{
|
||||
log_esp3d("Camera stream reached");
|
||||
if (!_initialised) {
|
||||
log_esp3d("Camera not started");
|
||||
webserver->send (500, "text/plain", "Camera not started");
|
||||
return;
|
||||
if (webserver) {
|
||||
webserver->send (500, "text/plain", "Camera not started");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
if (webserver->hasArg ("framesize") ) {
|
||||
if(s->status.framesize != webserver->arg ("framesize").toInt()) {
|
||||
command("framesize", webserver->arg ("framesize").c_str());
|
||||
if (webserver) {
|
||||
if (webserver->hasArg ("framesize") ) {
|
||||
if(s->status.framesize != webserver->arg ("framesize").toInt()) {
|
||||
command("framesize", webserver->arg ("framesize").c_str());
|
||||
}
|
||||
}
|
||||
if (webserver->hasArg ("hmirror") ) {
|
||||
command("hmirror", webserver->arg ("hmirror").c_str());
|
||||
}
|
||||
if (webserver->hasArg ("vflip") ) {
|
||||
command("vflip", webserver->arg ("vflip").c_str());
|
||||
}
|
||||
if (webserver->hasArg ("wb_mode") ) {
|
||||
command("wb_mode", webserver->arg ("wb_mode").c_str());
|
||||
}
|
||||
}
|
||||
if (webserver->hasArg ("hmirror") ) {
|
||||
command("hmirror", webserver->arg ("hmirror").c_str());
|
||||
}
|
||||
if (webserver->hasArg ("vflip") ) {
|
||||
command("vflip", webserver->arg ("vflip").c_str());
|
||||
}
|
||||
if (webserver->hasArg ("wb_mode") ) {
|
||||
command("wb_mode", webserver->arg ("wb_mode").c_str());
|
||||
}
|
||||
#ifdef ESP_ACCESS_CONTROL_ALLOW_ORIGIN
|
||||
webserver->enableCrossOrigin(true);
|
||||
webserver->enableCrossOrigin(true);
|
||||
#endif //ESP_ACCESS_CONTROL_ALLOw_ORIGIN
|
||||
}
|
||||
camera_fb_t * fb = NULL;
|
||||
bool res_error = false;
|
||||
size_t _jpg_buf_len = 0;
|
||||
uint8_t * _jpg_buf = NULL;
|
||||
webserver->sendHeader(String(F("Content-Type")), String(F("image/jpeg")),true);
|
||||
webserver->sendHeader(String(F("Content-Disposition")), String(F("inline; filename=capture.jpg")),true);
|
||||
webserver->setContentLength(CONTENT_LENGTH_UNKNOWN);
|
||||
webserver->send(200);
|
||||
if (webserver) {
|
||||
webserver->sendHeader(String(F("Content-Type")), String(F("image/jpeg")),true);
|
||||
webserver->sendHeader(String(F("Content-Disposition")), String(F("inline; filename=capture.jpg")),true);
|
||||
webserver->setContentLength(CONTENT_LENGTH_UNKNOWN);
|
||||
webserver->send(200);
|
||||
}
|
||||
log_esp3d("Camera capture ongoing");
|
||||
fb = esp_camera_fb_get();
|
||||
if (!fb) {
|
||||
log_esp3d("Camera capture failed");
|
||||
webserver->send (500, "text/plain", "Capture failed");
|
||||
if (webserver) {
|
||||
webserver->send (500, "text/plain", "Capture failed");
|
||||
}
|
||||
res_error=true;
|
||||
} else {
|
||||
if(fb->format != PIXFORMAT_JPEG) {
|
||||
bool jpeg_converted = frame2jpg(fb, JPEG_COMPRESSION, &_jpg_buf, &_jpg_buf_len);
|
||||
@ -89,7 +100,49 @@ void Camera::handle_snap(WebServer * webserver)
|
||||
}
|
||||
}
|
||||
if (!res_error) {
|
||||
webserver->sendContent_P ((const char *)_jpg_buf, _jpg_buf_len);
|
||||
if(webserver) {
|
||||
webserver->sendContent_P ((const char *)_jpg_buf, _jpg_buf_len);
|
||||
}
|
||||
#if defined (SD_DEVICE)
|
||||
if (filename!=nullptr && path!=nullptr) {
|
||||
if (!ESP_SD::accessFS()) {
|
||||
res_error = true;
|
||||
log_esp3d("SD not available");
|
||||
} else {
|
||||
if (ESP_SD::getState(true) == ESP_SDCARD_NOT_PRESENT) {
|
||||
res_error = true;
|
||||
log_esp3d("No SD");
|
||||
} else {
|
||||
ESP_SD::setState(ESP_SDCARD_BUSY );
|
||||
String wpath = path[0]=='/' ? path : String("/")+path;
|
||||
if (!ESP_SD::exists(wpath.c_str())) {
|
||||
res_error = !ESP_SD::mkdir(wpath.c_str());
|
||||
}
|
||||
if (!res_error) {
|
||||
if (wpath[wpath.length()-1]!='/') {
|
||||
wpath += "/";
|
||||
}
|
||||
wpath +=filename ;
|
||||
ESP_SDFile f = ESP_SD::open(wpath.c_str(), ESP_FILE_WRITE);
|
||||
if (f) {
|
||||
f.write((const uint8_t *)_jpg_buf, _jpg_buf_len);
|
||||
f.close();
|
||||
log_esp3d("Camera capture done");
|
||||
} else {
|
||||
res_error = true;
|
||||
log_esp3d("Failed to open file for writing");
|
||||
}
|
||||
}
|
||||
}
|
||||
ESP_SD::releaseFS();
|
||||
}
|
||||
|
||||
}
|
||||
#endif //SD_DEVICE
|
||||
if (!webserver && filename==nullptr && path==nullptr) {
|
||||
log_esp3d("No output defined");
|
||||
res_error = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(fb) {
|
||||
@ -100,7 +153,10 @@ void Camera::handle_snap(WebServer * webserver)
|
||||
free(_jpg_buf);
|
||||
_jpg_buf = NULL;
|
||||
}
|
||||
webserver->sendContent("");
|
||||
if(webserver) {
|
||||
webserver->sendContent("");
|
||||
}
|
||||
return !res_error;
|
||||
}
|
||||
|
||||
Camera::Camera()
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
void end();
|
||||
bool initHardware();
|
||||
bool stopHardware();
|
||||
void handle_snap(WebServer * webserver);
|
||||
bool handle_snap(WebServer * webserver, const char *path=NULL, const char* filename=NULL);
|
||||
void handle();
|
||||
int command(const char * param, const char * value);
|
||||
uint8_t GetModel();
|
||||
|
Loading…
x
Reference in New Issue
Block a user