Fix hot camera start and restart

Simplify Camera module begin by separate streamserver from hardware initialization
This commit is contained in:
Luc 2020-10-15 18:50:22 +02:00
parent a700546b8c
commit eccad4248a
5 changed files with 93 additions and 74 deletions

View File

@ -42,7 +42,7 @@ bool Commands::ESP170(const char* cmd_params, level_authenticate_type auth_type,
parameter = get_param (cmd_params, ""); parameter = get_param (cmd_params, "");
//get //get
if (parameter.length() == 0) { if (parameter.length() == 0) {
output->printMSG(!esp3d_camera.started()?"Camera OFF":"Camera ON"); output->printMSG(!esp3d_camera.serverstarted()?"Camera OFF":"Camera ON");
} else { //set } else { //set
#ifdef AUTHENTICATION_FEATURE #ifdef AUTHENTICATION_FEATURE
if (auth_type != LEVEL_ADMIN) { if (auth_type != LEVEL_ADMIN) {
@ -56,11 +56,14 @@ bool Commands::ESP170(const char* cmd_params, level_authenticate_type auth_type,
return false; return false;
} else { } else {
if (parameter == "ON") { if (parameter == "ON") {
esp3d_camera.begin(); if(esp3d_camera.startStreamServer()) {
output->printMSG ("ok");
}
} else { } else {
esp3d_camera.stopHardware(); if(esp3d_camera.stopStreamServer()) {
output->printMSG ("ok");
}
} }
output->printMSG ("ok");
} }
} }
return response; return response;

View File

@ -151,7 +151,7 @@ bool Commands::ESP420(const char* cmd_params, level_authenticate_type auth_type,
} }
output->print(ESP_FileSystem::formatBytes (ESP.getFreeHeap()).c_str()); output->print(ESP_FileSystem::formatBytes (ESP.getFreeHeap()).c_str());
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
#ifdef BOARD_HAS_PSRAM #ifdef BOARD_HAS_PSRAM
output->print(" - PSRAM:"); output->print(" - PSRAM:");
output->print(ESP_FileSystem::formatBytes (ESP.getFreePsram()).c_str()); output->print(ESP_FileSystem::formatBytes (ESP.getFreePsram()).c_str());

View File

@ -42,6 +42,7 @@ static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary="
static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n"; 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\n\r\n"; static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n";
bool Camera::_initialised = false;
httpd_handle_t stream_httpd = NULL; httpd_handle_t stream_httpd = NULL;
Camera esp3d_camera; Camera esp3d_camera;
@ -55,7 +56,7 @@ static void disconnected_uri(httpd_handle_t hd, int sockfd)
static esp_err_t stream_handler(httpd_req_t *req) static esp_err_t stream_handler(httpd_req_t *req)
{ {
log_esp3d("Camera stream reached"); log_esp3d("Camera stream reached");
if (!esp3d_camera.started()) { if (!esp3d_camera.serverstarted()) {
const char* resp = "Camera not started"; const char* resp = "Camera not started";
log_esp3d("Camera not started"); log_esp3d("Camera not started");
httpd_resp_send(req, resp, strlen(resp)); httpd_resp_send(req, resp, strlen(resp));
@ -168,8 +169,8 @@ static esp_err_t stream_handler(httpd_req_t *req)
Camera::Camera() Camera::Camera()
{ {
_server_started = false;
_started = false; _started = false;
_initialised = false;
_connected = false; _connected = false;
} }
@ -248,16 +249,12 @@ int Camera::command(const char * param, const char * value)
return res; return res;
} }
bool Camera::initHardware(bool forceinit) bool Camera::initHardware()
{ {
if (forceinit) { _initialised = false;
_initialised = false;
}
if (_initialised) {
return _initialised;
}
log_esp3d("Disable brown out"); log_esp3d("Disable brown out");
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
stopHardware();
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;
@ -287,9 +284,6 @@ bool Camera::initHardware(bool forceinit)
log_esp3d("psram is not enabled"); log_esp3d("psram is not enabled");
return false; return false;
} }
if (!stopHardware()) {
log_esp3d("Stop camera failed");
}
log_esp3d("Init camera"); log_esp3d("Init camera");
#if CAM_PULLUP1 != -1 #if CAM_PULLUP1 != -1
pinMode(CAM_PULLUP1, INPUT_PULLUP); pinMode(CAM_PULLUP1, INPUT_PULLUP);
@ -319,7 +313,6 @@ bool Camera::initHardware(bool forceinit)
esp_err_t err = esp_camera_init(&config); esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) { if (err != ESP_OK) {
log_esp3d("Camera init failed with error 0x%x", err); log_esp3d("Camera init failed with error 0x%x", err);
_initialised = false;
} else { } else {
_initialised = true; _initialised = true;
} }
@ -328,52 +321,30 @@ bool Camera::initHardware(bool forceinit)
bool Camera::stopHardware() bool Camera::stopHardware()
{ {
end(); return true;
_initialised = false; //no need to stop as it is done once at boot
log_esp3d("deinit camera"); /* _initialised = false;
esp_err_t err = esp_camera_deinit(); log_esp3d("deinit camera");
if(err == ESP_OK) { esp_err_t err = esp_camera_deinit();
//seems sometimes i2c install failed when doing camera init so let's remove if already installed if(err == ESP_OK) {
if(i2c_driver_delete(I2C_NUM_1)!= ESP_OK) { //seems sometimes i2c install failed when doing camera init so let's remove if already installed
log_esp3d("I2C 1 delete failed"); if(i2c_driver_delete(I2C_NUM_1)!= ESP_OK) {
} log_esp3d("I2C 1 delete failed");
return true; }
} else { return true;
log_esp3d("Camera deinit failed with error 0x%x", err); } else {
return false; log_esp3d("Camera deinit failed with error 0x%x", err);
} return false;
}*/
} }
//need to be call by device and by network bool Camera::startStreamServer()
bool Camera::begin(bool forceinit)
{ {
end(); stopStreamServer();
log_esp3d("Begin camera"); if (!_initialised) {
if (!initHardware(forceinit) ) { log_esp3d("Camera not initialised");
log_esp3d("Init hardware failed");
return false; return false;
} }
delay(1000);
log_esp3d("Init camera sensor settings");
sensor_t * s = esp_camera_sensor_get();
if (s != nullptr) {
//initial sensors are flipped vertically and colors are a bit saturated
if (s->id.PID == OV3660_PID) {
s->set_brightness(s, 1);//up the blightness just a bit
s->set_saturation(s, -2);//lower the saturation
}
s->set_framesize(s, DEFAULT_FRAME_SIZE);
#if defined(CAMERA_DEVICE_FLIP_HORIZONTALY)
s->set_hmirror(s, 1);
#endif //CAMERA_DEVICE_FLIP_HORIZONTALY
#if defined(CAMERA_DEVICE_FLIP_VERTICALY)
s->set_vflip(s, 1);
#endif //CAMERA_DEVICE_FLIP_VERTICALY
} else {
log_esp3d("Cannot access camera sensor");
}
if (NetConfig::started() && (NetConfig::getMode()!= ESP_BT)) { if (NetConfig::started() && (NetConfig::getMode()!= ESP_BT)) {
ESP3DOutput output(ESP_ALL_CLIENTS); ESP3DOutput output(ESP_ALL_CLIENTS);
httpd_config_t httpdconfig = HTTPD_DEFAULT_CONFIG(); httpd_config_t httpdconfig = HTTPD_DEFAULT_CONFIG();
@ -401,7 +372,7 @@ bool Camera::begin(bool forceinit)
output.printERROR("Starting camera server failed"); output.printERROR("Starting camera server failed");
return false; return false;
} }
_started = true; _server_started = true;
} }
for (int j = 0; j < 5; j++) { for (int j = 0; j < 5; j++) {
camera_fb_t * fb = esp_camera_fb_get(); // start the camera ... warm it up camera_fb_t * fb = esp_camera_fb_get(); // start the camera ... warm it up
@ -411,14 +382,13 @@ bool Camera::begin(bool forceinit)
esp_camera_fb_return(fb); esp_camera_fb_return(fb);
delay(20); delay(20);
} }
return _started; return _server_started;
} }
void Camera::end() bool Camera::stopStreamServer()
{ {
if (_started) { _connected = false;
_started = false; if (_server_started) {
_connected = false;
log_esp3d("unregister /stream"); log_esp3d("unregister /stream");
if (ESP_OK != httpd_unregister_uri(stream_httpd, "/stream")) { if (ESP_OK != httpd_unregister_uri(stream_httpd, "/stream")) {
log_esp3d("Error unregistering /stream"); log_esp3d("Error unregistering /stream");
@ -427,6 +397,49 @@ void Camera::end()
if (ESP_OK != httpd_stop(stream_httpd)) { if (ESP_OK != httpd_stop(stream_httpd)) {
log_esp3d("Error stopping stream server"); log_esp3d("Error stopping stream server");
} }
_server_started = false;
}
return true;
}
//need to be call by device and by network
bool Camera::begin()
{
end();
log_esp3d("Begin camera");
if (!_initialised) {
log_esp3d("Init hardware not done");
return false;
}
log_esp3d("Init camera sensor settings");
sensor_t * s = esp_camera_sensor_get();
if (s != nullptr) {
//initial sensors are flipped vertically and colors are a bit saturated
if (s->id.PID == OV3660_PID) {
s->set_brightness(s, 1);//up the blightness just a bit
s->set_saturation(s, -2);//lower the saturation
}
s->set_framesize(s, DEFAULT_FRAME_SIZE);
#if defined(CAMERA_DEVICE_FLIP_HORIZONTALY)
s->set_hmirror(s, 1);
#endif //CAMERA_DEVICE_FLIP_HORIZONTALY
#if defined(CAMERA_DEVICE_FLIP_VERTICALY)
s->set_vflip(s, 1);
#endif //CAMERA_DEVICE_FLIP_VERTICALY
} else {
log_esp3d("Cannot access camera sensor");
}
_started = startStreamServer();
return _started;
}
void Camera::end()
{
if (_started) {
_started = false;
stopStreamServer();
} }
} }

View File

@ -28,9 +28,12 @@ class Camera
public: public:
Camera(); Camera();
~Camera(); ~Camera();
bool initHardware(bool forceinit = false); bool begin();
bool begin(bool forceinit = false);
void end(); void end();
bool initHardware();
bool stopHardware();
bool startStreamServer();
bool stopStreamServer();
void handle(); void handle();
int command(const char * param, const char * value); int command(const char * param, const char * value);
uint8_t GetModel(); uint8_t GetModel();
@ -39,11 +42,10 @@ public:
{ {
return _started; return _started;
} }
bool initialised() bool serverstarted()
{ {
return _initialised; return _server_started;
} }
bool stopHardware();
void connect(bool status) void connect(bool status)
{ {
_connected = status; _connected = status;
@ -57,7 +59,8 @@ public:
return _port; return _port;
} }
private: private:
bool _initialised; static bool _initialised;
bool _server_started;
bool _started; bool _started;
bool _connected; bool _connected;
uint16_t _port; uint16_t _port;

View File

@ -268,7 +268,7 @@ bool NetServices::begin()
#ifdef CAMERA_DEVICE #ifdef CAMERA_DEVICE
if (!esp3d_camera.begin()) { if (!esp3d_camera.begin()) {
output.printMSG("Failed start camera streaming server"); output.printMSG("Failed start camera streaming server");
} else esp3d_camera.connect(false); }
#endif //CAMERA_DEVICE #endif //CAMERA_DEVICE
if (!res) { if (!res) {
end(); end();