diff --git a/code/components/jomjol_controlcamera/ClassControllCamera.cpp b/code/components/jomjol_controlcamera/ClassControllCamera.cpp index 5095cb16a..bd830ed92 100644 --- a/code/components/jomjol_controlcamera/ClassControllCamera.cpp +++ b/code/components/jomjol_controlcamera/ClassControllCamera.cpp @@ -142,8 +142,10 @@ esp_err_t CCamera::InitCam(void) if (s != NULL) { + CCstatus.CamSensor_id = s->id.PID; + // Dump camera module, warn for unsupported modules. - switch (s->id.PID) + switch (CCstatus.CamSensor_id) { case OV2640_PID: ESP_LOGI(TAG, "OV2640 camera module detected"); @@ -151,6 +153,9 @@ esp_err_t CCamera::InitCam(void) case OV3660_PID: ESP_LOGI(TAG, "OV3660 camera module detected"); break; + case OV5640_PID: + ESP_LOGI(TAG, "OV5640 camera module detected"); + break; default: ESP_LOGE(TAG, "Camera module is unknown and not properly supported!"); CCstatus.CameraInitSuccessful = false; @@ -237,8 +242,6 @@ esp_err_t CCamera::setSensorDatenFromCCstatus(void) if (s != NULL) { s->set_framesize(s, CCstatus.ImageFrameSize); - s->set_gainceiling(s, CCstatus.ImageGainceiling); // Image gain (GAINCEILING_x2, x4, x8, x16, x32, x64 or x128) - s->set_quality(s, CCstatus.ImageQuality); // 0 - 63 s->set_brightness(s, CCstatus.ImageBrightness); // -2 to 2 @@ -247,34 +250,37 @@ esp_err_t CCamera::setSensorDatenFromCCstatus(void) // s->set_sharpness(s, CCstatus.ImageSharpness); // auto-sharpness is not officially supported, default to 0 SetCamSharpness(CCstatus.ImageAutoSharpness, CCstatus.ImageSharpness); - s->set_exposure_ctrl(s, CCstatus.ImageAec); // 0 = disable , 1 = enable + s->set_denoise(s, CCstatus.ImageDenoiseLevel); // The OV2640 does not support it, OV3660 and OV5640 (0 to 8) + + s->set_special_effect(s, CCstatus.ImageSpecialEffect); // 0 to 6 (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia) + s->set_wb_mode(s, CCstatus.ImageWbMode); // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home) + s->set_ae_level(s, CCstatus.ImageAeLevel); // -2 to 2 s->set_aec_value(s, CCstatus.ImageAecValue); // 0 to 1200 + s->set_agc_gain(s, CCstatus.ImageAgcGain); // 0 to 30 - s->set_aec2(s, CCstatus.ImageAec2); // 0 = disable , 1 = enable + // s->set_gainceiling(s, CCstatus.ImageGainceiling); // Image gain (GAINCEILING_x2, x4, x8, x16, x32, x64 or x128) + ov5640_set_gainceiling(s, CCstatus.ImageGainceiling); - s->set_gain_ctrl(s, CCstatus.ImageAgc); // 0 = disable , 1 = enable - s->set_agc_gain(s, CCstatus.ImageAgcGain); // 0 to 30 + s->set_lenc(s, CCstatus.ImageLenc); // 0 = disable , 1 = enable + s->set_gain_ctrl(s, CCstatus.ImageAgc); // 0 = disable , 1 = enable + s->set_exposure_ctrl(s, CCstatus.ImageAec); // 0 = disable , 1 = enable + + s->set_hmirror(s, CCstatus.ImageHmirror); // 0 = disable , 1 = enable + s->set_vflip(s, CCstatus.ImageVflip); // 0 = disable , 1 = enable + s->set_aec2(s, CCstatus.ImageAec2); // 0 = disable , 1 = enable s->set_bpc(s, CCstatus.ImageBpc); // 0 = disable , 1 = enable s->set_wpc(s, CCstatus.ImageWpc); // 0 = disable , 1 = enable s->set_raw_gma(s, CCstatus.ImageRawGma); // 0 = disable , 1 = enable - s->set_lenc(s, CCstatus.ImageLenc); // 0 = disable , 1 = enable - - s->set_hmirror(s, CCstatus.ImageHmirror); // 0 = disable , 1 = enable - s->set_vflip(s, CCstatus.ImageVflip); // 0 = disable , 1 = enable - s->set_dcw(s, CCstatus.ImageDcw); // 0 = disable , 1 = enable - - s->set_wb_mode(s, CCstatus.ImageWbMode); // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home) s->set_awb_gain(s, CCstatus.ImageAwbGain); // 0 = disable , 1 = enable s->set_whitebal(s, CCstatus.ImageAwb); // 0 = disable , 1 = enable - // special_effect muß als Letztes gesetzt werden, sonst geht es nicht - s->set_special_effect(s, CCstatus.ImageSpecialEffect); // 0 to 6 (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia) + s->set_dcw(s, CCstatus.ImageDcw); // 0 = disable , 1 = enable - TickType_t xDelay2 = 1000 / portTICK_PERIOD_MS; + TickType_t xDelay2 = 100 / portTICK_PERIOD_MS; vTaskDelay(xDelay2); return ESP_OK; @@ -291,6 +297,8 @@ esp_err_t CCamera::getSensorDatenToCCstatus(void) if (s != NULL) { + CCstatus.CamSensor_id = s->id.PID; + CCstatus.ImageFrameSize = (framesize_t)s->status.framesize; CCstatus.ImageGainceiling = (gainceiling_t)s->status.gainceiling; @@ -316,6 +324,7 @@ esp_err_t CCamera::getSensorDatenToCCstatus(void) CCstatus.ImageHmirror = s->status.hmirror; CCstatus.ImageVflip = s->status.vflip; CCstatus.ImageDcw = s->status.dcw; + CCstatus.ImageDenoiseLevel = s->status.denoise; return ESP_OK; } @@ -325,7 +334,93 @@ esp_err_t CCamera::getSensorDatenToCCstatus(void) } } -void CCamera::SetZoomSize(bool zoomEnabled, int zoomOffsetX, int zoomOffsetY, int imageSize) +// on the OV5640, gainceiling must be set with the real value (x2>>>level = 2, .... x128>>>level = 128) +int CCamera::ov5640_set_gainceiling(sensor_t *s, gainceiling_t level) +{ + int ret = 0; + + if (CCstatus.CamSensor_id == OV2640_PID) + { + ret = s->set_gainceiling(s, CCstatus.ImageGainceiling); // Image gain (GAINCEILING_x2, x4, x8, x16, x32, x64 or x128) + } + else + { + int _level = (1 << ((int)level + 1)); + + ret = s->set_reg(s, 0x3A18, 0xFF, (_level >> 8) & 3) || s->set_reg(s, 0x3A19, 0xFF, _level & 0xFF); + + if (ret == 0) + { + // ESP_LOGD(TAG, "Set gainceiling to: %d", level); + s->status.gainceiling = level; + } + } + + return ret; +} + +// - It always zooms to the image center when offsets are zero +// - if imageSize = 0 then the image is not zoomed +// - if imageSize = max value, then the image is fully zoomed in +// - a zoom step is >>> Width + 32 px / Height + 24 px +void CCamera::SanitizeZoomParams(int imageSize, int frameSizeX, int frameSizeY, int &imageWidth, int &imageHeight, int &zoomOffsetX, int &zoomOffsetY) +{ + // for OV2640, This works only if the aspect ratio of 4:3 is preserved in the window size. + // use only values divisible by 8 without remainder + imageWidth = CCstatus.ImageWidth + (imageSize * 4 * 8); + imageHeight = CCstatus.ImageHeight + (imageSize * 3 * 8); + + int _maxX = frameSizeX - imageWidth; + int _maxY = frameSizeY - imageHeight; + + if ((abs(zoomOffsetX) * 2) > _maxX) + { + if (zoomOffsetX > 0) + { + zoomOffsetX = _maxX; + } + else + { + zoomOffsetX = 0; + } + } + else + { + if (zoomOffsetX > 0) + { + zoomOffsetX = ((_maxX / 2) + zoomOffsetX); + } + else + { + zoomOffsetX = ((_maxX / 2) + zoomOffsetX); + } + } + + if ((abs(zoomOffsetY) * 2) > _maxY) + { + if (zoomOffsetY > 0) + { + zoomOffsetY = _maxY; + } + else + { + zoomOffsetY = 0; + } + } + else + { + if (zoomOffsetY > 0) + { + zoomOffsetY = ((_maxY / 2) + zoomOffsetY); + } + else + { + zoomOffsetY = ((_maxY / 2) + zoomOffsetY); + } + } +} + +void CCamera::SetZoomSize(bool zoomEnabled, int zoomOffsetX, int zoomOffsetY, int imageSize, int imageVflip) { sensor_t *s = esp_camera_sensor_get(); @@ -333,89 +428,59 @@ void CCamera::SetZoomSize(bool zoomEnabled, int zoomOffsetX, int zoomOffsetY, in { if (zoomEnabled) { - // ov2640_sensor_mode_t _mode = OV2640_MODE_UXGA; // 1600x1200 - // ov2640_sensor_mode_t _mode = OV2640_MODE_SVGA; // 800x600 - // ov2640_sensor_mode_t _mode = OV2640_MODE_CIF; // 400x296 - int _mode = 0; - + int _imageSize_temp = 0; + int _imageWidth = CCstatus.ImageWidth; + int _imageHeight = CCstatus.ImageHeight; int _offsetx = zoomOffsetX; int _offsety = zoomOffsetY; - int _imageSize_temp = 0; - int _maxX = 0; - int _maxY = 0; - - if (imageSize < 29) - { - _imageSize_temp = (29 - imageSize); - } - - // This works only if the aspect ratio of 4:3 is preserved in the window size. - // use values divisible by 8 without remainder - int _imageWidth = CCstatus.ImageWidth + (_imageSize_temp * 4 * 8); - int _imageHeight = CCstatus.ImageHeight + (_imageSize_temp * 3 * 8); - - _maxX = 1600 - _imageWidth; - _maxY = 1200 - _imageHeight; + int frameSizeX; + int frameSizeY; - if ((abs(_offsetx) * 2) > _maxX) + switch (CCstatus.CamSensor_id) { - if (_offsetx > 0) + case OV5640_PID: + frameSizeX = 2592; + frameSizeY = 1944; + // max imageSize = ((frameSizeX - CCstatus.ImageWidth) / 8 / 4) - 1 + // 59 = ((2560 - 640) / 8 / 4) - 1 + if (imageSize < 59) { - _offsetx = _maxX; + _imageSize_temp = (59 - imageSize); } - else + SanitizeZoomParams(_imageSize_temp, frameSizeX, frameSizeY, _imageWidth, _imageHeight, _offsetx, _offsety); + SetCamWindow(s, frameSizeX, frameSizeY, _offsetx, _offsety, _imageWidth, _imageHeight, CCstatus.ImageWidth, CCstatus.ImageHeight, imageVflip); + break; + + case OV3660_PID: + frameSizeX = 2048; + frameSizeY = 1536; + // max imageSize = ((frameSizeX - CCstatus.ImageWidth) / 8 / 4) -1 + // 43 = ((2048 - 640) / 8 / 4) - 1 + if (imageSize < 43) { - _offsetx = 0; + _imageSize_temp = (43 - imageSize); } - } - else - { - if (_offsetx > 0) - { - // wenn der Wert von _offsetx nicht durch 8 teilbar ist, - // werden die Farben sehr oft vertauscht(insbesondere Rot mit Blau) - _offsetx = ((_maxX / 2) + _offsetx); - } - else + SanitizeZoomParams(_imageSize_temp, frameSizeX, frameSizeY, _imageWidth, _imageHeight, _offsetx, _offsety); + SetCamWindow(s, frameSizeX, frameSizeY, _offsetx, _offsety, _imageWidth, _imageHeight, CCstatus.ImageWidth, CCstatus.ImageHeight, imageVflip); + break; + + case OV2640_PID: + frameSizeX = 1600; + frameSizeY = 1200; + // max imageSize = ((frameSizeX - CCstatus.ImageWidth) / 8 / 4) -1 + // 29 = ((1600 - 640) / 8 / 4) - 1 + if (imageSize < 29) { - // wenn der Wert von _offsetx nicht durch 8 teilbar ist, - // werden die Farben sehr oft vertauscht(insbesondere Rot mit Blau) - _offsetx = ((_maxX / 2) + _offsetx); + _imageSize_temp = (29 - imageSize); } - } + SanitizeZoomParams(_imageSize_temp, frameSizeX, frameSizeY, _imageWidth, _imageHeight, _offsetx, _offsety); + SetCamWindow(s, frameSizeX, frameSizeY, _offsetx, _offsety, _imageWidth, _imageHeight, CCstatus.ImageWidth, CCstatus.ImageHeight, imageVflip); + break; - if ((abs(_offsety) * 2) > _maxY) - { - if (_offsety > 0) - { - _offsety = _maxY; - } - else - { - _offsety = 0; - } - } - else - { - if (_offsety > 0) - { - // wenn der Wert von _offsety nicht durch 8 teilbar ist, - // werden die Farben sehr oft vertauscht(insbesondere Rot mit Blau) - _offsety = ((_maxY / 2) + _offsety); - } - else - { - // wenn der Wert von _offsety nicht durch 8 teilbar ist, - // werden die Farben sehr oft vertauscht(insbesondere Rot mit Blau) - _offsety = ((_maxY / 2) + _offsety); - } + default: + // do nothing + break; } - - // _mode sets the sensor resolution (3 options available), - // _offsetx and _offsety set the start of the ROI, - // _imageWidth and _imageHeight set the size of the ROI, - // CCstatus.ImageWidth and CCstatus.ImageHeight set the output window size. - SetCamWindow(s, _mode, _offsetx, _offsety, _imageWidth, _imageHeight, CCstatus.ImageWidth, CCstatus.ImageHeight); } else { @@ -424,18 +489,22 @@ void CCamera::SetZoomSize(bool zoomEnabled, int zoomOffsetX, int zoomOffsetY, in } } -void CCamera::SetQualityZoomSize(int qual, framesize_t resol, bool zoomEnabled, int zoomOffsetX, int zoomOffsetY, int imageSize) +void CCamera::SetQualityZoomSize(int qual, framesize_t resol, bool zoomEnabled, int zoomOffsetX, int zoomOffsetY, int imageSize, int imageVflip) { - qual = min(63, max(8, qual)); // Limit quality from 8..63 (values lower than 8 tent to be unstable) + sensor_t *s = esp_camera_sensor_get(); - SetImageWidthHeightFromResolution(resol); + // OV2640 has no lower limit on jpeg quality + if (CCstatus.CamSensor_id == OV5640_PID) + { + qual = min(63, max(8, qual)); + } - sensor_t *s = esp_camera_sensor_get(); + SetImageWidthHeightFromResolution(resol); if (s != NULL) { s->set_quality(s, qual); - SetZoomSize(zoomEnabled, zoomOffsetX, zoomOffsetY, imageSize); + SetZoomSize(zoomEnabled, zoomOffsetX, zoomOffsetY, imageSize, imageVflip); } else { @@ -445,21 +514,36 @@ void CCamera::SetQualityZoomSize(int qual, framesize_t resol, bool zoomEnabled, void CCamera::SetCamSharpness(bool _autoSharpnessEnabled, int _sharpnessLevel) { - _sharpnessLevel = min(2, max(-2, _sharpnessLevel)); - sensor_t *s = esp_camera_sensor_get(); if (s != NULL) { - // post processing - if (_autoSharpnessEnabled) + if (CCstatus.CamSensor_id == OV2640_PID) { - s->set_sharpness(s, 0); - ov2640_enable_auto_sharpness(s); + _sharpnessLevel = min(2, max(-2, _sharpnessLevel)); + // The OV2640 does not officially support sharpness, so the detour is made with the ov2640_sharpness.cpp. + if (_autoSharpnessEnabled) + { + ov2640_enable_auto_sharpness(s); + } + else + { + ov2640_set_sharpness(s, _sharpnessLevel); + } } else { - ov2640_set_sharpness(s, _sharpnessLevel); + _sharpnessLevel = min(3, max(-3, _sharpnessLevel)); + // for CAMERA_OV5640 and CAMERA_OV3660 + if (_autoSharpnessEnabled) + { + // autoSharpness is not supported, default to zero + s->set_sharpness(s, 0); + } + else + { + s->set_sharpness(s, _sharpnessLevel); + } } } else @@ -468,47 +552,27 @@ void CCamera::SetCamSharpness(bool _autoSharpnessEnabled, int _sharpnessLevel) } } -/* - * resolution = 0 \\ OV2640_MODE_UXGA -> 1600 x 1200 - * resolution = 1 \\ OV2640_MODE_SVGA -> 800 x 600 - * resolution = 2 \\ OV2640_MODE_CIF -> 400 x 296 - * resolution = 3 \\ OV2640_MODE_MAX - */ -void CCamera::SetCamWindow(sensor_t *s, int resolution, int xOffset, int yOffset, int xTotal, int yTotal, int xOutput, int yOutput) +void CCamera::SetCamWindow(sensor_t *s, int frameSizeX, int frameSizeY, int xOffset, int yOffset, int xTotal, int yTotal, int xOutput, int yOutput, int imageVflip) { - // - (xOffset,yOffset) is the origin of the window in pixels and (xLength,yLength) is the size of the window in pixels. - // - (xOffset,yOffset) ist der Ursprung des Fensters in Pixel und (xLength,yLength) ist die Größe des Fensters in Pixel. - - // - Be aware that changing the resolution will effectively overwrite these settings. - // - Beachten Sie, dass eine Änderung der Auflösung diese Einstellungen effektiv überschreibt. - - // - This works only if the aspect ratio of 4:3 is preserved in the window size. - // - Dies funktioniert nur, wenn das Seitenverhältnis von 4:3 in der Fenstergröße beibehalten wird. - - // - total_x and total_y defines the size on the sensor - // - total_x und total_y definieren die Größe des Sensors - - // - width and height defines the resulting image(may be smaller than the size on the sensor) - // - width und height definieren das resultierende Bild (kann kleiner sein als die Größe des Sensor) - - // - keep the aspect total_x : total_y == width : height - // - Behalten Sie den Aspekt total_x : total_y == width : height bei - - // - use values divisible by 8 without remainder - // - Verwenden Sie Werte, die ohne Rest durch 8 teilbar sind - - // - start with total_x = width and total_y = height, reduce both values by eg.32 pixels - // - Beginnen Sie mit total_x = width und total_y = height und reduzieren Sie beide Werte um z.B.32 Pixel - - // - next try moving with offset_x or offset_y by 8 pixels - // - Versuchen Sie als Nächstes, mit offset_x oder offset_y um 8 Pixel zu verschieben - - // set_res_raw(sensor_t *sensor, int startX, int startY, int endX, int endY, int offsetX, int offsetY, int totalX, int totalY, int outputX, int outputY, bool scale, bool binning) - // set_window(sensor, (ov2640_sensor_mode_t)startX, offsetX, offsetY, totalX, totalY, outputX, outputY); - // set_window(sensor, mode, offset_x, offset_y, max_x, max_y, w, h); + if (CCstatus.CamSensor_id == OV2640_PID) + { + s->set_res_raw(s, 0, 0, 0, 0, xOffset, yOffset, xTotal, yTotal, xOutput, yOutput, false, false); + } + else + { + // for CAMERA_OV5640 and CAMERA_OV3660 + bool scale = !(xOutput == xTotal && yOutput == yTotal); + bool binning = (xTotal >= (frameSizeX >> 1)); - int unused = 0; - s->set_res_raw(s, resolution, unused, unused, unused, xOffset, yOffset, xTotal, yTotal, xOutput, yOutput, unused, unused); + if (imageVflip == true) + { + s->set_res_raw(s, xOffset, yOffset, xOffset + xTotal - 1, yOffset + yTotal - 1, 0, 0, frameSizeX, frameSizeY, xOutput, yOutput, scale, binning); + } + else + { + s->set_res_raw(s, xOffset, yOffset, xOffset + xTotal, yOffset + yTotal, 0, 0, frameSizeX, frameSizeY, xOutput, yOutput, scale, binning); + } + } } static size_t jpg_encode_stream(void *arg, size_t index, const void *data, size_t len) @@ -839,7 +903,7 @@ esp_err_t CCamera::CaptureToStream(httpd_req_t *req, bool FlashlightOn) if (CFstatus.changedCameraSettings) { Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera - Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize); + Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize, CCstatus.ImageVflip); CFstatus.changedCameraSettings = false; } diff --git a/code/components/jomjol_controlcamera/ClassControllCamera.h b/code/components/jomjol_controlcamera/ClassControllCamera.h index b674ead3f..cea057260 100644 --- a/code/components/jomjol_controlcamera/ClassControllCamera.h +++ b/code/components/jomjol_controlcamera/ClassControllCamera.h @@ -15,15 +15,10 @@ #include "CImageBasis.h" #include "../../include/defines.h" -typedef enum -{ - OV2640_MODE_UXGA, - OV2640_MODE_SVGA, - OV2640_MODE_CIF -} ov2640_sensor_mode_t; - typedef struct { + uint16_t CamSensor_id; + framesize_t ImageFrameSize = FRAMESIZE_VGA; // 0 - 10 gainceiling_t ImageGainceiling; // Image gain (GAINCEILING_x2, x4, x8, x16, x32, x64 or x128) @@ -51,13 +46,14 @@ typedef struct int ImageVflip; // Invert image (0 or 1) int ImageDcw; // downsize enable (1 or 0) + int ImageDenoiseLevel; // The OV2640 does not support it, OV3660 and OV5640 (0 to 8) + int ImageWidth; int ImageHeight; int ImageLedIntensity; bool ImageZoomEnabled; - int ImageZoomMode; int ImageZoomOffsetX; int ImageZoomOffsetY; int ImageZoomSize; @@ -79,33 +75,36 @@ class CCamera void ledc_init(void); bool loadNextDemoImage(camera_fb_t *fb); long GetFileSize(std::string filename); - void SetCamWindow(sensor_t *s, int resolution, int xOffset, int yOffset, int xTotal, int yTotal, int xOutput, int yOutput); + void SetCamWindow(sensor_t *s, int frameSizeX, int frameSizeY, int xOffset, int yOffset, int xTotal, int yTotal, int xOutput, int yOutput, int imageVflip); void SetImageWidthHeightFromResolution(framesize_t resol); + void SanitizeZoomParams(int imageSize, int frameSizeX, int frameSizeY, int &imageWidth, int &imageHeight, int &zoomOffsetX, int &zoomOffsetY); public: CCamera(void); esp_err_t InitCam(void); - + void LightOnOff(bool status); void LEDOnOff(bool status); esp_err_t setSensorDatenFromCCstatus(void); esp_err_t getSensorDatenToCCstatus(void); + int ov5640_set_gainceiling(sensor_t *s, gainceiling_t level); + esp_err_t CaptureToHTTP(httpd_req_t *req, int delay = 0); esp_err_t CaptureToStream(httpd_req_t *req, bool FlashlightOn); - void SetQualityZoomSize(int qual, framesize_t resol, bool zoomEnabled, int zoomOffsetX, int zoomOffsetY, int imageSize); - void SetZoomSize(bool zoomEnabled, int zoomOffsetX, int zoomOffsetY, int imageSize); + void SetQualityZoomSize(int qual, framesize_t resol, bool zoomEnabled, int zoomOffsetX, int zoomOffsetY, int imageSize, int imageVflip); + void SetZoomSize(bool zoomEnabled, int zoomOffsetX, int zoomOffsetY, int imageSize, int imageVflip); void SetCamSharpness(bool _autoSharpnessEnabled, int _sharpnessLevel); - - void SetLEDIntensity(float _intrel); + + void SetLEDIntensity(float _intrel); bool testCamera(void); bool getCameraInitSuccessful(void); void useDemoMode(void); framesize_t TextToFramesize(const char *text); - + esp_err_t CaptureToFile(std::string nm, int delay = 0); esp_err_t CaptureToBasisImage(CImageBasis *_Image, int delay = 0); }; diff --git a/code/components/jomjol_controlcamera/server_camera.cpp b/code/components/jomjol_controlcamera/server_camera.cpp index ed6d0d126..08affb128 100644 --- a/code/components/jomjol_controlcamera/server_camera.cpp +++ b/code/components/jomjol_controlcamera/server_camera.cpp @@ -100,7 +100,7 @@ esp_err_t handler_capture(httpd_req_t *req) if (CFstatus.changedCameraSettings) { Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera - Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize); + Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize, CCstatus.ImageVflip); CFstatus.changedCameraSettings = false; } @@ -158,7 +158,7 @@ esp_err_t handler_capture_with_light(httpd_req_t *req) if (CFstatus.changedCameraSettings) { Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera - Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize); + Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize, CCstatus.ImageVflip); CFstatus.changedCameraSettings = false; } @@ -240,7 +240,7 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req) if (CFstatus.changedCameraSettings) { Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera - Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize); + Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize, CCstatus.ImageVflip); CFstatus.changedCameraSettings = false; } diff --git a/code/components/jomjol_flowcontroll/ClassFlowTakeImage.cpp b/code/components/jomjol_flowcontroll/ClassFlowTakeImage.cpp index 999296b13..caf5158b9 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowTakeImage.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowTakeImage.cpp @@ -101,14 +101,7 @@ bool ClassFlowTakeImage::ReadParameter(FILE *pfile, string &aktparamgraph) else if ((toUpper(splitted[0]) == "SAVEALLFILES") && (splitted.size() > 1)) { - if (toUpper(splitted[1]) == "TRUE") - { - CCstatus.SaveAllFiles = 1; - } - else - { - CCstatus.SaveAllFiles = 0; - } + CCstatus.SaveAllFiles = stringToBoolean(toUpper(splitted[1])); } else if ((toUpper(splitted[0]) == "WAITBEFORETAKINGPICTURE") && (splitted.size() > 1)) @@ -160,58 +153,43 @@ bool ClassFlowTakeImage::ReadParameter(FILE *pfile, string &aktparamgraph) else if ((toUpper(splitted[0]) == "CAMQUALITY") && (splitted.size() > 1)) { int _ImageQuality = std::stoi(splitted[1]); - if ((_ImageQuality >= 0) && (_ImageQuality <= 63)) - { - CCstatus.ImageQuality = _ImageQuality; - } + CCstatus.ImageQuality = clipInt(_ImageQuality, 63, 6); } else if ((toUpper(splitted[0]) == "CAMBRIGHTNESS") && (splitted.size() > 1)) { int _ImageBrightness = std::stoi(splitted[1]); - if ((_ImageBrightness >= -2) && (_ImageBrightness <= 2)) - { - CCstatus.ImageBrightness = _ImageBrightness; - } + CCstatus.ImageBrightness = clipInt(_ImageBrightness, 2, -2); } else if ((toUpper(splitted[0]) == "CAMCONTRAST") && (splitted.size() > 1)) { int _ImageContrast = std::stoi(splitted[1]); - if ((_ImageContrast >= -2) && (_ImageContrast <= 2)) - { - CCstatus.ImageContrast = _ImageContrast; - } + CCstatus.ImageContrast = clipInt(_ImageContrast, 2, -2); } else if ((toUpper(splitted[0]) == "CAMSATURATION") && (splitted.size() > 1)) { int _ImageSaturation = std::stoi(splitted[1]); - if ((_ImageSaturation >= -2) && (_ImageSaturation <= 2)) - { - CCstatus.ImageSaturation = _ImageSaturation; - } + CCstatus.ImageSaturation = clipInt(_ImageSaturation, 2, -2); } else if ((toUpper(splitted[0]) == "CAMSHARPNESS") && (splitted.size() > 1)) { int _ImageSharpness = std::stoi(splitted[1]); - if ((_ImageSharpness >= -2) && (_ImageSharpness <= 2)) + if (CCstatus.CamSensor_id == OV2640_PID) + { + CCstatus.ImageSharpness = clipInt(_ImageSharpness, 2, -2); + } + else { - CCstatus.ImageSharpness = _ImageSharpness; + CCstatus.ImageSharpness = clipInt(_ImageSharpness, 3, -3); } } else if ((toUpper(splitted[0]) == "CAMAUTOSHARPNESS") && (splitted.size() > 1)) { - if (toUpper(splitted[1]) == "TRUE") - { - CCstatus.ImageAutoSharpness = 1; - } - else - { - CCstatus.ImageAutoSharpness = 0; - } + CCstatus.ImageAutoSharpness = stringToBoolean(toUpper(splitted[1])); } else if ((toUpper(splitted[0]) == "CAMSPECIALEFFECT") && (splitted.size() > 1)) @@ -274,203 +252,155 @@ bool ClassFlowTakeImage::ReadParameter(FILE *pfile, string &aktparamgraph) else if ((toUpper(splitted[0]) == "CAMAWB") && (splitted.size() > 1)) { - if (toUpper(splitted[1]) == "TRUE") - { - CCstatus.ImageAwb = 1; - } - else - { - CCstatus.ImageAwb = 0; - } + CCstatus.ImageAwb = stringToBoolean(toUpper(splitted[1])); } else if ((toUpper(splitted[0]) == "CAMAWBGAIN") && (splitted.size() > 1)) { - if (toUpper(splitted[1]) == "TRUE") - { - CCstatus.ImageAwbGain = 1; - } - else - { - CCstatus.ImageAwbGain = 0; - } + CCstatus.ImageAwbGain = stringToBoolean(toUpper(splitted[1])); } else if ((toUpper(splitted[0]) == "CAMAEC") && (splitted.size() > 1)) { - if (toUpper(splitted[1]) == "TRUE") - { - CCstatus.ImageAec = 1; - } - else - { - CCstatus.ImageAec = 0; - } + CCstatus.ImageAec = stringToBoolean(toUpper(splitted[1])); } else if ((toUpper(splitted[0]) == "CAMAEC2") && (splitted.size() > 1)) { - if (toUpper(splitted[1]) == "TRUE") - { - CCstatus.ImageAec2 = 1; - } - else - { - CCstatus.ImageAec2 = 0; - } + CCstatus.ImageAec2 = stringToBoolean(toUpper(splitted[1])); } else if ((toUpper(splitted[0]) == "CAMAELEVEL") && (splitted.size() > 1)) { int _ImageAeLevel = std::stoi(splitted[1]); - if ((_ImageAeLevel >= -2) && (_ImageAeLevel <= 2)) + if (CCstatus.CamSensor_id == OV2640_PID) { - CCstatus.ImageAeLevel = _ImageAeLevel; + CCstatus.ImageAeLevel = clipInt(_ImageAeLevel, 2, -2); + } + else + { + CCstatus.ImageAeLevel = clipInt(_ImageAeLevel, 5, -5); } } else if ((toUpper(splitted[0]) == "CAMAECVALUE") && (splitted.size() > 1)) { int _ImageAecValue = std::stoi(splitted[1]); - if ((_ImageAecValue >= 0) && (_ImageAecValue <= 1200)) - { - CCstatus.ImageAecValue = _ImageAecValue; - } + CCstatus.ImageAecValue = clipInt(_ImageAecValue, 1200, 0); } else if ((toUpper(splitted[0]) == "CAMAGC") && (splitted.size() > 1)) { - if (toUpper(splitted[1]) == "TRUE") - { - CCstatus.ImageAgc = 1; - } - else - { - CCstatus.ImageAgc = 0; - } + CCstatus.ImageAgc = stringToBoolean(toUpper(splitted[1])); } else if ((toUpper(splitted[0]) == "CAMAGCGAIN") && (splitted.size() > 1)) { int _ImageAgcGain = std::stoi(splitted[1]); - if ((_ImageAgcGain >= 0) && (_ImageAgcGain <= 30)) - { - CCstatus.ImageAgcGain = _ImageAgcGain; - } + CCstatus.ImageAgcGain = clipInt(_ImageAgcGain, 30, 0); } else if ((toUpper(splitted[0]) == "CAMBPC") && (splitted.size() > 1)) { - if (toUpper(splitted[1]) == "TRUE") - { - CCstatus.ImageBpc = 1; - } - else - { - CCstatus.ImageBpc = 0; - } + CCstatus.ImageBpc = stringToBoolean(toUpper(splitted[1])); } else if ((toUpper(splitted[0]) == "CAMWPC") && (splitted.size() > 1)) { - if (toUpper(splitted[1]) == "TRUE") - { - CCstatus.ImageWpc = 1; - } - else - { - CCstatus.ImageWpc = 0; - } + CCstatus.ImageWpc = stringToBoolean(toUpper(splitted[1])); } else if ((toUpper(splitted[0]) == "CAMRAWGMA") && (splitted.size() > 1)) { - if (toUpper(splitted[1]) == "TRUE") - { - CCstatus.ImageRawGma = 1; - } - else - { - CCstatus.ImageRawGma = 0; - } + CCstatus.ImageRawGma = stringToBoolean(toUpper(splitted[1])); } else if ((toUpper(splitted[0]) == "CAMLENC") && (splitted.size() > 1)) { - if (toUpper(splitted[1]) == "TRUE") - { - CCstatus.ImageLenc = 1; - } - else - { - CCstatus.ImageLenc = 0; - } + CCstatus.ImageLenc = stringToBoolean(toUpper(splitted[1])); } else if ((toUpper(splitted[0]) == "CAMHMIRROR") && (splitted.size() > 1)) { - if (toUpper(splitted[1]) == "TRUE") - { - CCstatus.ImageHmirror = 1; - } - else - { - CCstatus.ImageHmirror = 0; - } + CCstatus.ImageHmirror = stringToBoolean(toUpper(splitted[1])); } else if ((toUpper(splitted[0]) == "CAMVFLIP") && (splitted.size() > 1)) { - if (toUpper(splitted[1]) == "TRUE") - { - CCstatus.ImageVflip = 1; - } - else - { - CCstatus.ImageVflip = 0; - } + CCstatus.ImageVflip = stringToBoolean(toUpper(splitted[1])); } else if ((toUpper(splitted[0]) == "CAMDCW") && (splitted.size() > 1)) { - if (toUpper(splitted[1]) == "TRUE") + CCstatus.ImageDcw = stringToBoolean(toUpper(splitted[1])); + } + + else if ((toUpper(splitted[0]) == "CAMSDENOISE") && (splitted.size() > 1)) + { + int _ImageDenoiseLevel = std::stoi(splitted[1]); + if (CCstatus.CamSensor_id == OV2640_PID) { - CCstatus.ImageDcw = 1; + CCstatus.ImageDenoiseLevel = 0; } else { - CCstatus.ImageDcw = 0; + CCstatus.ImageDenoiseLevel = clipInt(_ImageDenoiseLevel, 8, 0); } } else if ((toUpper(splitted[0]) == "CAMZOOM") && (splitted.size() > 1)) { - if (toUpper(splitted[1]) == "TRUE") - { - CCstatus.ImageZoomEnabled = 1; - } - else - { - CCstatus.ImageZoomEnabled = 0; - } + CCstatus.ImageZoomEnabled = stringToBoolean(toUpper(splitted[1])); } else if ((toUpper(splitted[0]) == "CAMZOOMOFFSETX") && (splitted.size() > 1)) { - CCstatus.ImageZoomOffsetX = std::stoi(splitted[1]); + int _ImageZoomOffsetX = std::stoi(splitted[1]); + if (CCstatus.CamSensor_id == OV2640_PID) + { + CCstatus.ImageZoomOffsetX = clipInt(_ImageZoomOffsetX, 480, -480); + } + else if (CCstatus.CamSensor_id == OV3660_PID) + { + CCstatus.ImageZoomOffsetX = clipInt(_ImageZoomOffsetX, 704, -704); + } + else if (CCstatus.CamSensor_id == OV5640_PID) + { + CCstatus.ImageZoomOffsetX = clipInt(_ImageZoomOffsetX, 960, -960); + } } else if ((toUpper(splitted[0]) == "CAMZOOMOFFSETY") && (splitted.size() > 1)) { - CCstatus.ImageZoomOffsetY = std::stoi(splitted[1]); + int _ImageZoomOffsetY = std::stoi(splitted[1]); + if (CCstatus.CamSensor_id == OV2640_PID) + { + CCstatus.ImageZoomOffsetY = clipInt(_ImageZoomOffsetY, 360, -360); + } + else if (CCstatus.CamSensor_id == OV3660_PID) + { + CCstatus.ImageZoomOffsetY = clipInt(_ImageZoomOffsetY, 528, -528); + } + else if (CCstatus.CamSensor_id == OV5640_PID) + { + CCstatus.ImageZoomOffsetY = clipInt(_ImageZoomOffsetY, 720, -720); + } } else if ((toUpper(splitted[0]) == "CAMZOOMSIZE") && (splitted.size() > 1)) { int _ImageZoomSize = std::stoi(splitted[1]); - if (_ImageZoomSize >= 0) + if (CCstatus.CamSensor_id == OV2640_PID) { - CCstatus.ImageZoomSize = _ImageZoomSize; + CCstatus.ImageZoomSize = clipInt(_ImageZoomSize, 29, 0); + } + else if (CCstatus.CamSensor_id == OV3660_PID) + { + CCstatus.ImageZoomSize = clipInt(_ImageZoomSize, 43, 0); + } + else if (CCstatus.CamSensor_id == OV5640_PID) + { + CCstatus.ImageZoomSize = clipInt(_ImageZoomSize, 59, 0); } } @@ -482,20 +412,16 @@ bool ClassFlowTakeImage::ReadParameter(FILE *pfile, string &aktparamgraph) else if ((toUpper(splitted[0]) == "DEMO") && (splitted.size() > 1)) { - if (toUpper(splitted[1]) == "TRUE") + CCstatus.DemoMode = stringToBoolean(toUpper(splitted[1])); + if (CCstatus.DemoMode) { - CCstatus.DemoMode = true; Camera.useDemoMode(); } - else - { - CCstatus.DemoMode = false; - } } } Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera - Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize); + Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize, CCstatus.ImageVflip); rawImage = new CImageBasis("rawImage"); rawImage->CreateEmptyImage(CCstatus.ImageWidth, CCstatus.ImageHeight, 3); @@ -538,7 +464,7 @@ bool ClassFlowTakeImage::doFlow(string zwtime) if (CFstatus.changedCameraSettings) { Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera - Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize); + Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize, CCstatus.ImageVflip); CFstatus.changedCameraSettings = false; } diff --git a/code/components/jomjol_flowcontroll/MainFlowControl.cpp b/code/components/jomjol_flowcontroll/MainFlowControl.cpp index b3c0a6a84..8e8303c5c 100644 --- a/code/components/jomjol_flowcontroll/MainFlowControl.cpp +++ b/code/components/jomjol_flowcontroll/MainFlowControl.cpp @@ -145,6 +145,8 @@ bool doflow(void) esp_err_t setCCstatusToCFstatus(void) { + CFstatus.CamSensor_id = CCstatus.CamSensor_id; + CFstatus.ImageFrameSize = CCstatus.ImageFrameSize; CFstatus.ImageGainceiling = CCstatus.ImageGainceiling; @@ -171,11 +173,11 @@ esp_err_t setCCstatusToCFstatus(void) CFstatus.ImageHmirror = CCstatus.ImageHmirror; CFstatus.ImageVflip = CCstatus.ImageVflip; CFstatus.ImageDcw = CCstatus.ImageDcw; + CFstatus.ImageDenoiseLevel = CCstatus.ImageDenoiseLevel; CFstatus.ImageLedIntensity = CCstatus.ImageLedIntensity; CFstatus.ImageZoomEnabled = CCstatus.ImageZoomEnabled; - CFstatus.ImageZoomMode = CCstatus.ImageZoomMode; CFstatus.ImageZoomOffsetX = CCstatus.ImageZoomOffsetX; CFstatus.ImageZoomOffsetY = CCstatus.ImageZoomOffsetY; CFstatus.ImageZoomSize = CCstatus.ImageZoomSize; @@ -187,6 +189,8 @@ esp_err_t setCCstatusToCFstatus(void) esp_err_t setCFstatusToCCstatus(void) { + // CCstatus.CamSensor_id = CFstatus.CamSensor_id; + CCstatus.ImageFrameSize = CFstatus.ImageFrameSize; CCstatus.ImageGainceiling = CFstatus.ImageGainceiling; @@ -213,11 +217,11 @@ esp_err_t setCFstatusToCCstatus(void) CCstatus.ImageHmirror = CFstatus.ImageHmirror; CCstatus.ImageVflip = CFstatus.ImageVflip; CCstatus.ImageDcw = CFstatus.ImageDcw; + CCstatus.ImageDenoiseLevel = CFstatus.ImageDenoiseLevel; CCstatus.ImageLedIntensity = CFstatus.ImageLedIntensity; CCstatus.ImageZoomEnabled = CFstatus.ImageZoomEnabled; - CCstatus.ImageZoomMode = CFstatus.ImageZoomMode; CCstatus.ImageZoomOffsetX = CFstatus.ImageZoomOffsetX; CCstatus.ImageZoomOffsetY = CFstatus.ImageZoomOffsetY; CCstatus.ImageZoomSize = CFstatus.ImageZoomSize; @@ -234,8 +238,6 @@ esp_err_t setCFstatusToCam(void) if (s != NULL) { s->set_framesize(s, CFstatus.ImageFrameSize); - s->set_gainceiling(s, CFstatus.ImageGainceiling); - s->set_quality(s, CFstatus.ImageQuality); // 0 - 63 s->set_brightness(s, CFstatus.ImageBrightness); // -2 to 2 @@ -244,33 +246,37 @@ esp_err_t setCFstatusToCam(void) // s->set_sharpness(s, CFstatus.ImageSharpness); // auto-sharpness is not officially supported, default to 0 Camera.SetCamSharpness(CFstatus.ImageAutoSharpness, CFstatus.ImageSharpness); - s->set_exposure_ctrl(s, CFstatus.ImageAec); // 0 = disable , 1 = enable + s->set_denoise(s, CFstatus.ImageDenoiseLevel); // The OV2640 does not support it, OV3660 and OV5640 (0 to 8) + + s->set_special_effect(s, CFstatus.ImageSpecialEffect); // 0 to 6 (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia) + s->set_wb_mode(s, CFstatus.ImageWbMode); // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home) + s->set_ae_level(s, CFstatus.ImageAeLevel); // -2 to 2 s->set_aec_value(s, CFstatus.ImageAecValue); // 0 to 1200 - s->set_aec2(s, CFstatus.ImageAec2); // 0 = disable , 1 = enable + s->set_agc_gain(s, CFstatus.ImageAgcGain); // 0 to 30 - s->set_gain_ctrl(s, CFstatus.ImageAgc); // 0 = disable , 1 = enable - s->set_agc_gain(s, CFstatus.ImageAgcGain); // 0 to 30 - - s->set_bpc(s, CFstatus.ImageBpc); // 0 = disable , 1 = enable - s->set_wpc(s, CFstatus.ImageWpc); // 0 = disable , 1 = enable + // s->set_gainceiling(s, CFstatus.ImageGainceiling); // Image gain (GAINCEILING_x2, x4, x8, x16, x32, x64 or x128) + Camera.ov5640_set_gainceiling(s, CFstatus.ImageGainceiling); - s->set_raw_gma(s, CFstatus.ImageRawGma); // 0 = disable , 1 = enable - s->set_lenc(s, CFstatus.ImageLenc); // 0 = disable , 1 = enable + s->set_lenc(s, CFstatus.ImageLenc); // 0 = disable , 1 = enable + s->set_gain_ctrl(s, CFstatus.ImageAgc); // 0 = disable , 1 = enable + s->set_exposure_ctrl(s, CFstatus.ImageAec); // 0 = disable , 1 = enable s->set_hmirror(s, CFstatus.ImageHmirror); // 0 = disable , 1 = enable s->set_vflip(s, CFstatus.ImageVflip); // 0 = disable , 1 = enable + s->set_aec2(s, CFstatus.ImageAec2); // 0 = disable , 1 = enable - s->set_dcw(s, CFstatus.ImageDcw); // 0 = disable , 1 = enable + s->set_bpc(s, CFstatus.ImageBpc); // 0 = disable , 1 = enable + s->set_wpc(s, CFstatus.ImageWpc); // 0 = disable , 1 = enable + + s->set_raw_gma(s, CFstatus.ImageRawGma); // 0 = disable , 1 = enable - s->set_wb_mode(s, CFstatus.ImageWbMode); // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home) s->set_awb_gain(s, CFstatus.ImageAwbGain); // 0 = disable , 1 = enable s->set_whitebal(s, CFstatus.ImageAwb); // 0 = disable , 1 = enable - // special_effect muß als Letztes gesetzt werden, sonst geht es nicht - s->set_special_effect(s, CFstatus.ImageSpecialEffect); // 0 to 6 (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia) + s->set_dcw(s, CFstatus.ImageDcw); // 0 = disable , 1 = enable - TickType_t xDelay2 = 1000 / portTICK_PERIOD_MS; + TickType_t xDelay2 = 100 / portTICK_PERIOD_MS; vTaskDelay(xDelay2); return ESP_OK; @@ -946,280 +952,226 @@ esp_err_t handler_editflow(httpd_req_t *req) } } - if (httpd_query_key_value(_query, "qual", _valuechar, 30) == ESP_OK) + if (httpd_query_key_value(_query, "aecgc", _valuechar, 30) == ESP_OK) { - int _qual = std::stoi(_valuechar); - if ((_qual >= 0) && (_qual <= 63)) + int _aecgc = std::stoi(_valuechar); + switch (_aecgc) { - CFstatus.ImageQuality = _qual; + case 1: CFstatus.ImageGainceiling = GAINCEILING_4X; break; + case 2: CFstatus.ImageGainceiling = GAINCEILING_8X; break; + case 3: CFstatus.ImageGainceiling = GAINCEILING_16X; break; + case 4: CFstatus.ImageGainceiling = GAINCEILING_32X; break; + case 5: CFstatus.ImageGainceiling = GAINCEILING_64X; break; + case 6: CFstatus.ImageGainceiling = GAINCEILING_128X; break; + default: CFstatus.ImageGainceiling = GAINCEILING_2X; } } + if (httpd_query_key_value(_query, "qual", _valuechar, 30) == ESP_OK) + { + int _qual = std::stoi(_valuechar); + CFstatus.ImageQuality = clipInt(_qual, 63, 6); + } + if (httpd_query_key_value(_query, "bri", _valuechar, 30) == ESP_OK) { int _bri = std::stoi(_valuechar); - if ((_bri >= -2) && (_bri <= 2)) - { - CFstatus.ImageBrightness = _bri; - } + CFstatus.ImageBrightness = clipInt(_bri, 2, -2); } if (httpd_query_key_value(_query, "con", _valuechar, 30) == ESP_OK) { int _con = std::stoi(_valuechar); - if ((_con >= -2) && (_con <= 2)) - { - CFstatus.ImageContrast = _con; - } + CFstatus.ImageContrast = clipInt(_con, 2, -2); } if (httpd_query_key_value(_query, "sat", _valuechar, 30) == ESP_OK) { int _sat = std::stoi(_valuechar); - if ((_sat >= -2) && (_sat <= 2)) - { - CFstatus.ImageSaturation = _sat; - } + CFstatus.ImageSaturation = clipInt(_sat, 2, -2); } if (httpd_query_key_value(_query, "shp", _valuechar, 30) == ESP_OK) { int _shp = std::stoi(_valuechar); - if ((_shp >= -2) && (_shp <= 2)) + if (CCstatus.CamSensor_id == OV2640_PID) + { + CFstatus.ImageSharpness = clipInt(_shp, 2, -2); + } + else { - CFstatus.ImageSharpness = _shp; + CFstatus.ImageSharpness = clipInt(_shp, 3, -3); } } if (httpd_query_key_value(_query, "ashp", _valuechar, 30) == ESP_OK) { - if (std::stoi(_valuechar) != 0) - { - CFstatus.ImageAutoSharpness = 1; - } - else - { - CFstatus.ImageAutoSharpness = 0; - } + CFstatus.ImageAutoSharpness = numericStrToBool(_valuechar); } if (httpd_query_key_value(_query, "spe", _valuechar, 30) == ESP_OK) { int _spe = std::stoi(_valuechar); - if ((_spe >= 0) && (_spe <= 6)) - { - CFstatus.ImageSpecialEffect = _spe; - } + CFstatus.ImageSpecialEffect = clipInt(_spe, 6, 0); } if (httpd_query_key_value(_query, "wbm", _valuechar, 30) == ESP_OK) { int _wbm = std::stoi(_valuechar); - if ((_wbm >= 0) && (_wbm <= 4)) - { - CFstatus.ImageWbMode = _wbm; - } + CFstatus.ImageWbMode = clipInt(_wbm, 4, 0); } if (httpd_query_key_value(_query, "awb", _valuechar, 30) == ESP_OK) { - if (std::stoi(_valuechar) != 0) - { - CFstatus.ImageAwb = 1; - } - else - { - CFstatus.ImageAwb = 0; - } + CFstatus.ImageAwb = numericStrToBool(_valuechar); } if (httpd_query_key_value(_query, "awbg", _valuechar, 30) == ESP_OK) { - if (std::stoi(_valuechar) != 0) - { - CFstatus.ImageAwbGain = 1; - } - else - { - CFstatus.ImageAwbGain = 0; - } + CFstatus.ImageAwbGain = numericStrToBool(_valuechar); } if (httpd_query_key_value(_query, "aec", _valuechar, 30) == ESP_OK) { - if (std::stoi(_valuechar) != 0) - { - CFstatus.ImageAec = 1; - } - else - { - CFstatus.ImageAec = 0; - } + CFstatus.ImageAec = numericStrToBool(_valuechar); } if (httpd_query_key_value(_query, "aec2", _valuechar, 30) == ESP_OK) { - if (std::stoi(_valuechar) != 0) - { - CFstatus.ImageAec2 = 1; - } - else - { - CFstatus.ImageAec2 = 0; - } + CFstatus.ImageAec2 = numericStrToBool(_valuechar); } if (httpd_query_key_value(_query, "ael", _valuechar, 30) == ESP_OK) { int _ael = std::stoi(_valuechar); - if ((_ael >= -2) && (_ael <= 2)) + if (CCstatus.CamSensor_id == OV2640_PID) + { + CFstatus.ImageAeLevel = clipInt(_ael, 2, -2); + } + else { - CFstatus.ImageAeLevel = _ael; + CFstatus.ImageAeLevel = clipInt(_ael, 5, -5); } } if (httpd_query_key_value(_query, "aecv", _valuechar, 30) == ESP_OK) { int _aecv = std::stoi(_valuechar); - if ((_aecv >= 0) && (_aecv <= 1200)) - { - CFstatus.ImageAecValue = _aecv; - } + CFstatus.ImageAecValue = clipInt(_aecv, 1200, 0); } if (httpd_query_key_value(_query, "agc", _valuechar, 30) == ESP_OK) { - if (std::stoi(_valuechar) != 0) - { - CFstatus.ImageAgc = 1; - } - else - { - CFstatus.ImageAgc = 0; - } + CFstatus.ImageAgc = numericStrToBool(_valuechar); } if (httpd_query_key_value(_query, "agcg", _valuechar, 30) == ESP_OK) { int _agcg = std::stoi(_valuechar); - if ((_agcg >= 0) && (_agcg <= 30)) - { - CFstatus.ImageAgcGain = _agcg; - } + CFstatus.ImageAgcGain = clipInt(_agcg, 30, 0); } if (httpd_query_key_value(_query, "bpc", _valuechar, 30) == ESP_OK) { - if (std::stoi(_valuechar) != 0) - { - CFstatus.ImageBpc = 1; - } - else - { - CFstatus.ImageBpc = 0; - } + CFstatus.ImageBpc = numericStrToBool(_valuechar); } if (httpd_query_key_value(_query, "wpc", _valuechar, 30) == ESP_OK) { - if (std::stoi(_valuechar) != 0) - { - CFstatus.ImageWpc = 1; - } - else - { - CFstatus.ImageWpc = 0; - } + CFstatus.ImageWpc = numericStrToBool(_valuechar); } if (httpd_query_key_value(_query, "rgma", _valuechar, 30) == ESP_OK) { - if (std::stoi(_valuechar) != 0) - { - CFstatus.ImageRawGma = 1; - } - else - { - CFstatus.ImageRawGma = 0; - } + CFstatus.ImageRawGma = numericStrToBool(_valuechar); } if (httpd_query_key_value(_query, "lenc", _valuechar, 30) == ESP_OK) { - if (std::stoi(_valuechar) != 0) - { - CFstatus.ImageLenc = 1; - } - else - { - CFstatus.ImageLenc = 0; - } + CFstatus.ImageLenc = numericStrToBool(_valuechar); } if (httpd_query_key_value(_query, "mirror", _valuechar, 30) == ESP_OK) { - if (std::stoi(_valuechar) != 0) - { - CFstatus.ImageHmirror = 1; - } - else - { - CFstatus.ImageHmirror = 0; - } + CFstatus.ImageHmirror = numericStrToBool(_valuechar); } if (httpd_query_key_value(_query, "flip", _valuechar, 30) == ESP_OK) { - if (std::stoi(_valuechar) != 0) - { - CFstatus.ImageVflip = 1; - } - else - { - CFstatus.ImageVflip = 0; - } + CFstatus.ImageVflip = numericStrToBool(_valuechar); } if (httpd_query_key_value(_query, "dcw", _valuechar, 30) == ESP_OK) { - if (std::stoi(_valuechar) != 0) + CFstatus.ImageDcw = numericStrToBool(_valuechar); + } + + if (httpd_query_key_value(_query, "den", _valuechar, 30) == ESP_OK) + { + int _ImageDenoiseLevel = std::stoi(_valuechar); + if (CCstatus.CamSensor_id == OV2640_PID) { - CFstatus.ImageDcw = 1; + CCstatus.ImageDenoiseLevel = 0; } else { - CFstatus.ImageDcw = 0; + CFstatus.ImageDenoiseLevel = clipInt(_ImageDenoiseLevel, 8, 0); } } if (httpd_query_key_value(_query, "zoom", _valuechar, 30) == ESP_OK) { - if (std::stoi(_valuechar) != 0) - { - CFstatus.ImageZoomEnabled = 1; - } - else - { - CFstatus.ImageZoomEnabled = 0; - } + CFstatus.ImageZoomEnabled = numericStrToBool(_valuechar); } if (httpd_query_key_value(_query, "zoomx", _valuechar, 30) == ESP_OK) { - CFstatus.ImageZoomOffsetX = std::stoi(_valuechar); + int _ImageZoomOffsetX = std::stoi(_valuechar); + if (CCstatus.CamSensor_id == OV2640_PID) + { + CFstatus.ImageZoomOffsetX = clipInt(_ImageZoomOffsetX, 480, -480); + } + else if (CCstatus.CamSensor_id == OV3660_PID) + { + CFstatus.ImageZoomOffsetX = clipInt(_ImageZoomOffsetX, 704, -704); + } + else if (CCstatus.CamSensor_id == OV5640_PID) + { + CFstatus.ImageZoomOffsetX = clipInt(_ImageZoomOffsetX, 960, -960); + } } if (httpd_query_key_value(_query, "zoomy", _valuechar, 30) == ESP_OK) { - CFstatus.ImageZoomOffsetY = std::stoi(_valuechar); + int _ImageZoomOffsetY = std::stoi(_valuechar); + if (CCstatus.CamSensor_id == OV2640_PID) + { + CFstatus.ImageZoomOffsetY = clipInt(_ImageZoomOffsetY, 360, -360); + } + else if (CCstatus.CamSensor_id == OV3660_PID) + { + CFstatus.ImageZoomOffsetY = clipInt(_ImageZoomOffsetY, 528, -528); + } + else if (CCstatus.CamSensor_id == OV5640_PID) + { + CFstatus.ImageZoomOffsetY = clipInt(_ImageZoomOffsetY, 720, -720); + } } if (httpd_query_key_value(_query, "zooms", _valuechar, 30) == ESP_OK) { int _ImageZoomSize = std::stoi(_valuechar); - if (_ImageZoomSize >= 0) + if (CCstatus.CamSensor_id == OV2640_PID) + { + CFstatus.ImageZoomSize = clipInt(_ImageZoomSize, 29, 0); + } + else if (CCstatus.CamSensor_id == OV3660_PID) + { + CFstatus.ImageZoomSize = clipInt(_ImageZoomSize, 43, 0); + } + else if (CCstatus.CamSensor_id == OV5640_PID) { - CFstatus.ImageZoomSize = _ImageZoomSize; + CFstatus.ImageZoomSize = clipInt(_ImageZoomSize, 59, 0); } } @@ -1249,8 +1201,8 @@ esp_err_t handler_editflow(httpd_req_t *req) // CFstatus >>> Kamera setCFstatusToCam(); - Camera.SetQualityZoomSize(CFstatus.ImageQuality, CFstatus.ImageFrameSize, CFstatus.ImageZoomEnabled, CFstatus.ImageZoomOffsetX, CFstatus.ImageZoomOffsetY, CFstatus.ImageZoomSize); - // Camera.SetZoomSize(CFstatus.ImageZoomEnabled, CFstatus.ImageZoomOffsetX, CFstatus.ImageZoomOffsetY, CFstatus.ImageZoomSize); + Camera.SetQualityZoomSize(CFstatus.ImageQuality, CFstatus.ImageFrameSize, CFstatus.ImageZoomEnabled, CFstatus.ImageZoomOffsetX, CFstatus.ImageZoomOffsetY, CFstatus.ImageZoomSize, CFstatus.ImageVflip); + // Camera.SetZoomSize(CFstatus.ImageZoomEnabled, CFstatus.ImageZoomOffsetX, CFstatus.ImageZoomOffsetY, CFstatus.ImageZoomSize, CFstatus.ImageVflip); // Kameraeinstellungen wurden verädert CFstatus.changedCameraSettings = true; diff --git a/code/components/jomjol_flowcontroll/MainFlowControl.h b/code/components/jomjol_flowcontroll/MainFlowControl.h index 2810837f3..a2c2047e3 100644 --- a/code/components/jomjol_flowcontroll/MainFlowControl.h +++ b/code/components/jomjol_flowcontroll/MainFlowControl.h @@ -13,8 +13,10 @@ typedef struct { + uint16_t CamSensor_id; + framesize_t ImageFrameSize = FRAMESIZE_VGA; // 0 - 10 - gainceiling_t ImageGainceiling; // Image gain (GAINCEILING_x2, x4, x8, x16, x32, x64 or x128) + gainceiling_t ImageGainceiling; // Image gain (GAINCEILING_x2, x4, x8, x16, x32, x64 or x128) int ImageQuality; // 0 - 63 int ImageBrightness; // (-2 to 2) - set brightness @@ -40,13 +42,14 @@ typedef struct int ImageVflip; // Invert image (0 or 1) int ImageDcw; // downsize enable (1 or 0) + int ImageDenoiseLevel; // The OV2640 does not support it, OV3660 and OV5640 (0 to 8) + int ImageWidth; int ImageHeight; int ImageLedIntensity; bool ImageZoomEnabled; - int ImageZoomMode; int ImageZoomOffsetX; int ImageZoomOffsetY; int ImageZoomSize; diff --git a/code/components/jomjol_helper/Helper.cpp b/code/components/jomjol_helper/Helper.cpp index d61631552..1e15f06bd 100644 --- a/code/components/jomjol_helper/Helper.cpp +++ b/code/components/jomjol_helper/Helper.cpp @@ -1207,6 +1207,29 @@ bool isInString(std::string &s, std::string const &toFind) return true; } +int clipInt(int input, int high, int low) +{ + if (input < low) + { + input = low; + } + else if (input > high) + { + input = high; + } + return input; +} + +bool numericStrToBool(char *input) +{ + return (std::stoi(input) != 0); +} + +bool stringToBoolean(std::string input) +{ + return (input == "TRUE"); +} + // from https://stackoverflow.com/a/14678800 void replaceAll(std::string& s, const std::string& toReplace, const std::string& replaceWith) { diff --git a/code/components/jomjol_helper/Helper.h b/code/components/jomjol_helper/Helper.h index e81d2fbd0..70e7f02b7 100644 --- a/code/components/jomjol_helper/Helper.h +++ b/code/components/jomjol_helper/Helper.h @@ -103,4 +103,8 @@ bool replaceString(std::string& s, std::string const& toReplace, std::string con bool replaceString(std::string& s, std::string const& toReplace, std::string const& replaceWith, bool logIt); bool isInString(std::string& s, std::string const& toFind); +int clipInt(int input, int high, int low); +bool numericStrToBool(char *input); +bool stringToBoolean(std::string input); + #endif //HELPER_H diff --git a/code/sdkconfig.defaults b/code/sdkconfig.defaults index e41514a16..0fe530363 100644 --- a/code/sdkconfig.defaults +++ b/code/sdkconfig.defaults @@ -135,7 +135,8 @@ CONFIG_OV7670_SUPPORT=n CONFIG_OV7725_SUPPORT=n CONFIG_NT99141_SUPPORT=n CONFIG_OV3660_SUPPORT=n -CONFIG_OV5640_SUPPORT=n +CONFIG_OV2640_SUPPORT=y +CONFIG_OV5640_SUPPORT=y CONFIG_GC2145_SUPPORT=n CONFIG_GC032A_SUPPORT=n CONFIG_GC0308_SUPPORT=n diff --git a/param-docs/expert-params.txt b/param-docs/expert-params.txt index db38cc929..056b71288 100644 --- a/param-docs/expert-params.txt +++ b/param-docs/expert-params.txt @@ -19,6 +19,7 @@ CamWpc CamRawGma CamLenc CamDcw +CamDenoise CamZoom CamZoomSize CamZoomOffsetX diff --git a/param-docs/parameter-pages/TakeImage/CamAeLevel.md b/param-docs/parameter-pages/TakeImage/CamAeLevel.md index 8f562828c..332f687cb 100644 --- a/param-docs/parameter-pages/TakeImage/CamAeLevel.md +++ b/param-docs/parameter-pages/TakeImage/CamAeLevel.md @@ -12,4 +12,5 @@ Default Value: `0` Auto-Exposure Compensation. Lower values produce darker image. -Range (`-2` .. `2`) +available range on OV2640 (`-2` .. `2`) +available range on OV3660 and OV5640 (`-5` .. `5`) diff --git a/param-docs/parameter-pages/TakeImage/CamDenoise.md b/param-docs/parameter-pages/TakeImage/CamDenoise.md index 36c0a573d..f51b8ec4a 100644 --- a/param-docs/parameter-pages/TakeImage/CamDenoise.md +++ b/param-docs/parameter-pages/TakeImage/CamDenoise.md @@ -1,5 +1,5 @@ # Parameter `CamDenoise` -Default Value: ` ` +Default Value: `0` !!! Warning This is an **Expert Parameter**! Only change it if you understand what it does! @@ -7,4 +7,6 @@ Default Value: ` ` !!! Note After changing this parameter you need to update your reference image and alignment markers! -Denoise Image (not supported) +Denoise Image, is only supported by OV3660 and OV5640 + +Range (`0` .. `8`) diff --git a/param-docs/parameter-pages/TakeImage/CamVflip.md b/param-docs/parameter-pages/TakeImage/CamVflip.md index fccb30227..9f4ae8bfe 100644 --- a/param-docs/parameter-pages/TakeImage/CamVflip.md +++ b/param-docs/parameter-pages/TakeImage/CamVflip.md @@ -7,4 +7,7 @@ Default Value: `false` !!! Note After changing this parameter you need to update your reference image and alignment markers! +!!! Note + On some OV5640 Cameras, the image becomes reddish when Vflip is used in conjunction with the zoom function! + Option for initially flip the image on the original y-axis. diff --git a/sd-card/config/config.ini b/sd-card/config/config.ini index 2b133857f..24b5c357b 100644 --- a/sd-card/config/config.ini +++ b/sd-card/config/config.ini @@ -26,6 +26,7 @@ CamLenc = true CamHmirror = false CamVflip = false CamDcw = true +CamDenoise = 0 CamZoom = false CamZoomOffsetX = 0 CamZoomOffsetY = 0 diff --git a/sd-card/html/edit_config_template.html b/sd-card/html/edit_config_template.html index 68b9cd134..207cc4ef3 100644 --- a/sd-card/html/edit_config_template.html +++ b/sd-card/html/edit_config_template.html @@ -375,8 +375,8 @@

Configuration

Sharpness - + $TOOLTIP_TakeImage_CamSharpness @@ -472,8 +472,8 @@

Configuration

Auto Exposure Level - + $TOOLTIP_TakeImage_CamAeLevel @@ -605,6 +605,17 @@

Configuration

$TOOLTIP_TakeImage_CamDcw + + + Denoise + + + + + $TOOLTIP_TakeImage_CamDenoise + + Zoom @@ -623,8 +634,8 @@

Configuration

Zoom Size - + $TOOLTIP_TakeImage_CamZoomSize @@ -634,8 +645,8 @@

Configuration

Zoom Offset X - Pixel + Pixel $TOOLTIP_TakeImage_CamZoomOffsetX @@ -645,11 +656,11 @@

Configuration

Zoom Offset Y - Pixel + Pixel $TOOLTIP_TakeImage_CamZoomOffsetY - + @@ -2197,6 +2208,7 @@

Zoom Offset X: - + $TOOLTIP_TakeImage_CamZoomOffsetX @@ -195,8 +195,8 @@

Reference Image and Camera Settings

- + $TOOLTIP_TakeImage_CamZoomSize @@ -204,8 +204,8 @@

Reference Image and Camera Settings

- + $TOOLTIP_TakeImage_CamZoomOffsetY diff --git a/sd-card/html/readconfigparam.js b/sd-card/html/readconfigparam.js index 593281ef0..0577642c7 100644 --- a/sd-card/html/readconfigparam.js +++ b/sd-card/html/readconfigparam.js @@ -129,7 +129,8 @@ function ParseConfig() { ParamAddValue(param, catname, "CamLenc"); // lens correction (1 or 0) ParamAddValue(param, catname, "CamHmirror"); // (0 or 1) flip horizontally ParamAddValue(param, catname, "CamVflip"); // Invert image (0 or 1) - ParamAddValue(param, catname, "CamDcw"); // downsize enable (1 or 0) + ParamAddValue(param, catname, "CamDcw"); // downsize enable (1 or 0) + ParamAddValue(param, catname, "CamDenoise"); // The OV2640 does not support it, OV3660 and OV5640 (0 to 8) ParamAddValue(param, catname, "CamZoom"); ParamAddValue(param, catname, "CamZoomOffsetX"); ParamAddValue(param, catname, "CamZoomOffsetY"); @@ -475,7 +476,7 @@ function getCamConfig() { param["TakeImage"]["CamContrast"]["enabled"] = true; //-2 - 2 param["TakeImage"]["CamSaturation"]["enabled"] = true; //-2 - 2 param["TakeImage"]["CamSharpness"]["enabled"] = true; //-2 - 2 - param["TakeImage"]["CamAutoSharpness"]["enabled"] = true; //(1 or 0) + param["TakeImage"]["CamAutoSharpness"]["enabled"] = true; //(1 or 0) param["TakeImage"]["CamSpecialEffect"]["enabled"] = true; // 0 - 6 param["TakeImage"]["CamWbMode"]["enabled"] = true; // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home) param["TakeImage"]["CamAwb"]["enabled"] = true; // white balance enable (0 or 1) @@ -492,12 +493,13 @@ function getCamConfig() { param["TakeImage"]["CamLenc"]["enabled"] = true; // lens correction (1 or 0) param["TakeImage"]["CamHmirror"]["enabled"] = true; // (0 or 1) flip horizontally param["TakeImage"]["CamVflip"]["enabled"] = true; // Invert image (0 or 1) - param["TakeImage"]["CamDcw"]["enabled"] = true; // downsize enable (1 or 0) + param["TakeImage"]["CamDcw"]["enabled"] = true; // downsize enable (1 or 0) + param["TakeImage"]["CamDenoise"]["enabled"] = true; // The OV2640 does not support it, OV3660 and OV5640 (0 to 8) param["TakeImage"]["CamZoom"]["enabled"] = true; param["TakeImage"]["CamZoomOffsetX"]["enabled"] = true; param["TakeImage"]["CamZoomOffsetY"]["enabled"] = true; - param["TakeImage"]["CamZoomSize"]["enabled"] = true; - param["TakeImage"]["LEDIntensity"]["enabled"] = true; + param["TakeImage"]["CamZoomSize"]["enabled"] = true; + param["TakeImage"]["LEDIntensity"]["enabled"] = true; if (!param["System"]["Tooltip"]["found"]) { param["System"]["Tooltip"]["found"] = true; @@ -609,6 +611,10 @@ function getCamConfig() { param["TakeImage"]["CamDcw"]["found"] = true; param["TakeImage"]["CamDcw"].value1 = 'true'; } + if (!param["TakeImage"]["CamDenoise"]["found"]) { + param["TakeImage"]["CamDenoise"]["found"] = true; + param["TakeImage"]["CamDenoise"].value1 = '0'; + } if (!param["TakeImage"]["CamZoom"]["found"]) { param["TakeImage"]["CamZoom"]["found"] = true; param["TakeImage"]["CamZoom"].value1 = 'false';