Merge pull request #81 from jomjol/rolling

Update to v6.0.0
This commit is contained in:
jomjol
2021-01-02 08:54:05 +01:00
committed by GitHub
88 changed files with 2704 additions and 1137 deletions

View File

@@ -23,30 +23,68 @@ If you would like to support the developer with a cup of coffee you can do that
</form>
## Donate
------
If you would like to support the developer with a cup of coffee you can do that via [Paypal](https://www.paypal.com/donate?hosted_button_id=8TRSVYNYKDSWL).
<form action="https://www.paypal.com/donate" method="post" target="_top">
<input type="hidden" name="hosted_button_id" value="8TRSVYNYKDSWL" />
<input type="image" src="https://www.paypalobjects.com/en_US/DK/i/btn/btn_donateCC_LG.gif" border="0" name="submit" title="PayPal - The safer, easier way to pay online!" alt="Donate with PayPal button" />
<img alt="" border="0" src="https://www.paypal.com/en_DE/i/scr/pixel.gif" width="1" height="1" />
</form>
## Change log
------
### Known Issues
* Reboot on extensive web access due to the limits of the internal web server
* slow response of web server during picture analysis
------
**General remark:** Beside the `firmware.bin`, typically also the content of `/html` needs to be updated!
##### 6.0.0 Image Processing in Memory - (2021-01-02)
* **Major change**: image processing fully in memory - no need of SD card buffer anymore
* Need to limit camera resolution to VGA (due to memory limits)
* MQTT: Last Will Testament (LWT) implemented: "connection lost" in case of connection lost to `TopicError`
* Disabled `CheckDigitIncreaseConsistency` in default configuration - must now be explicit enabled if needed
* Update digital CNN to v7.2.1 (additional digital images trained)
* Setting of arbitrary time server in `config.ini`
* Option for fixed IP-, DNS-Settings in `wlan.ini`
* Increased stability (internal image and camera handling)
* Bug fixing: edit digits, handling PreValue, html-bugs
##### 5.0.0 Setup Modus - (2020-12-06)
* Implementation of intial setup modus for fresh installation
* Code restructuring (full compatibility between pure ESP-IDF and Platformio w/ espressif)
##### 4.1.1 Configuration editor - (2020-12-02)
* Bug fixing: internal improvement of file handling (reduce not responding)
##### 4.1.0 Configuration editor - (2020-11-30)
@@ -62,7 +100,6 @@ If you would like to support the developer with a cup of coffee you can do that
* Bug fixing: truncation error, CheckDigitConsistency & PreValue implementation
##### 4.0.0 Tflite Core - (2020-11-15)

View File

@@ -232,7 +232,7 @@ void LoadWlanFromFile(std::string fn, std::string &_ssid, std::string &_passphra
FILE* pFile;
fn = FormatFileName(fn);
pFile = fopen(fn.c_str(), "r");
pFile = OpenFileAndWait(fn.c_str(), "r");
printf("file loaded\n");
@@ -270,7 +270,48 @@ void LoadWlanFromFile(std::string fn, std::string &_ssid, std::string &_passphra
}
}
/*
if (fgets(zw, 1024, pFile) == NULL)
{
line = "";
}
else
{
line = std::string(zw);
}
}
fclose(pFile);
// Check if Hostname was empty in .ini if yes set to std_hostname
if(_hostname.length() <= 0){
_hostname = std_hostname;
}
}
void LoadNetConfigFromFile(std::string fn, std::string &_ip, std::string &_gw, std::string &_netmask, std::string &_dns)
{
string line = "";
std::vector<string> zerlegt;
FILE* pFile;
fn = FormatFileName(fn);
pFile = OpenFileAndWait(fn.c_str(), "r");
printf("file loaded\n");
if (pFile == NULL)
return;
char zw[1024];
fgets(zw, 1024, pFile);
line = std::string(zw);
while ((line.size() > 0) || !(feof(pFile)))
{
printf("%s", line.c_str());
zerlegt = ZerlegeZeile(line, "=");
zerlegt[0] = trim(zerlegt[0], " ");
if ((zerlegt.size() > 1) && (toUpper(zerlegt[0]) == "IP")){
_ip = zerlegt[1];
if ((_ip[0] == '"') && (_ip[_ip.length()-1] == '"')){
@@ -298,8 +339,6 @@ void LoadWlanFromFile(std::string fn, std::string &_ssid, std::string &_passphra
_dns = _dns.substr(1, _dns.length()-2);
}
}
*/
if (fgets(zw, 1024, pFile) == NULL)
{
@@ -312,11 +351,6 @@ void LoadWlanFromFile(std::string fn, std::string &_ssid, std::string &_passphra
}
fclose(pFile);
// Check if Hostname was empty in .ini if yes set to std_hostname
if(_hostname.length() <= 0){
_hostname = std_hostname;
}
}

View File

@@ -11,7 +11,7 @@ void initialise_wifi_fixed_ip(std::string _ip, std::string _gw, std::string _net
void LoadWlanFromFile(std::string fn, std::string &_ssid, std::string &_passphrase, std::string &_hostname);
void LoadNetConfigFromFile(std::string &_ip, std::string &_gw, std::string &_netmask, std::string &_dns);
void LoadNetConfigFromFile(std::string fn, std::string &_ip, std::string &_gw, std::string &_netmask, std::string &_dns);
std::string getHostname();
std::string getIPAddress();

View File

@@ -0,0 +1,9 @@
FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
list(APPEND EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
idf_component_register(SRCS ${app_sources}
INCLUDE_DIRS "."
REQUIRES esp_http_server jomjol_logfile)

View File

@@ -0,0 +1,123 @@
#include <string>
#include "string.h"
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_log.h"
#include "driver/gpio.h"
//#include "errno.h"
#include <sys/stat.h>
#include "server_GPIO.h"
#include "ClassLogFile.h"
#include "Helper.h"
#define DEBUG_DETAIL_ON
esp_err_t handler_switch_GPIO(httpd_req_t *req)
{
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_switch_GPIO - Start");
#endif
LogFile.WriteToFile("handler_switch_GPIO");
char _query[200];
char _valueGPIO[30];
char _valueStatus[30];
std::string gpio, status, zw;
int gpionum = 0;
gpio_num_t gpio_num;
if (httpd_req_get_url_query_str(req, _query, 200) == ESP_OK)
{
printf("Query: "); printf(_query); printf("\n");
if (httpd_query_key_value(_query, "GPIO", _valueGPIO, 30) == ESP_OK)
{
printf("GPIO is found"); printf(_valueGPIO); printf("\n");
gpio = std::string(_valueGPIO);
}
if (httpd_query_key_value(_query, "Status", _valueStatus, 30) == ESP_OK)
{
printf("Status is found"); printf(_valueStatus); printf("\n");
status = std::string(_valueStatus);
}
};
status = toUpper(status);
if (!(status == "HIGH") && !(status == "LOW"))
{
zw = "Status not valid: " + status;;
httpd_resp_sendstr_chunk(req, zw.c_str());
httpd_resp_sendstr_chunk(req, NULL);
return ESP_OK;
}
gpionum = stoi(gpio);
// frei: 16; 12-15; 2; 4
switch (gpionum) {
case 2:
gpio_num = GPIO_NUM_2;
break;
case 4:
gpio_num = GPIO_NUM_4;
break;
case 12:
gpio_num = GPIO_NUM_12;
break;
case 13:
gpio_num = GPIO_NUM_13;
break;
case 14:
gpio_num = GPIO_NUM_14;
break;
case 15:
gpio_num = GPIO_NUM_15;
break;
case 16:
gpio_num = (gpio_num_t) 16;
break;
default:
zw = "GPIO" + std::to_string(gpionum) + " not support - only 2, 4, 12-16 free";
httpd_resp_sendstr_chunk(req, zw.c_str());
httpd_resp_sendstr_chunk(req, NULL);
return ESP_OK;
}
// Init the GPIO
gpio_pad_select_gpio(gpio_num);
/* Set the GPIO as a push/pull output */
gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT);
if (status == "HIGH")
gpio_set_level(gpio_num, 1);
else
gpio_set_level(gpio_num, 0);
zw = "GPIO" + std::to_string(gpionum) + " switched to " + status;
httpd_resp_sendstr_chunk(req, zw.c_str());
httpd_resp_sendstr_chunk(req, NULL);
return ESP_OK;
};
void register_server_GPIO_uri(httpd_handle_t server)
{
ESP_LOGI(TAGPARTGPIO, "server_GPIO - Registering URI handlers");
httpd_uri_t camuri = { };
camuri.method = HTTP_GET;
camuri.uri = "/GPIO";
camuri.handler = handler_switch_GPIO;
camuri.user_ctx = (void*) "switch GPIO";
httpd_register_uri_handler(server, &camuri);
}

View File

@@ -0,0 +1,10 @@
#include <esp_log.h>
#include <esp_http_server.h>
//#include "ClassControllCamera.h"
static const char *TAGPARTGPIO = "server_GPIO";
void register_server_GPIO_uri(httpd_handle_t server);

View File

@@ -1,4 +1,5 @@
#include "ClassControllCamera.h"
#include "ClassLogFile.h"
#include <stdio.h>
#include "driver/gpio.h"
@@ -6,34 +7,11 @@
#include "esp_log.h"
#include "Helper.h"
#include "CFindTemplate.h"
#include "CImageBasis.h"
// #include "camera_define.h"
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
#define BOARD_ESP32CAM_AITHINKER
/**
* 2. Kconfig setup
*
* If you have a Kconfig file, copy the content from
* https://github.com/espressif/esp32-camera/blob/master/Kconfig into it.
* In case you haven't, copy and paste this Kconfig file inside the src directory.
* This Kconfig file has definitions that allows more control over the camera and
* how it will be initialized.
*/
/**
* 3. Enable PSRAM on sdkconfig:
*
* CONFIG_ESP32_SPIRAM_SUPPORT=y
*
* More info on
* https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/kconfig.html#config-esp32-spiram-support
*/
// ================================ CODE ======================================
#include <esp_event_loop.h>
#include <esp_log.h>
@@ -47,31 +25,10 @@
#include "esp_camera.h"
// WROVER-KIT PIN Map
#ifdef BOARD_WROVER_KIT
// #define DEBUG_DETAIL_ON
#define CAM_PIN_PWDN -1 //power down is not used
#define CAM_PIN_RESET -1 //software reset will be performed
#define CAM_PIN_XCLK 21
#define CAM_PIN_SIOD 26
#define CAM_PIN_SIOC 27
#define CAM_PIN_D7 35
#define CAM_PIN_D6 34
#define CAM_PIN_D5 39
#define CAM_PIN_D4 36
#define CAM_PIN_D3 19
#define CAM_PIN_D2 18
#define CAM_PIN_D1 5
#define CAM_PIN_D0 4
#define CAM_PIN_VSYNC 25
#define CAM_PIN_HREF 23
#define CAM_PIN_PCLK 22
#endif
// ESP32Cam (AiThinker) PIN Map
#ifdef BOARD_ESP32CAM_AITHINKER
#define CAM_PIN_PWDN (gpio_num_t) 32
#define CAM_PIN_RESET -1 //software reset will be performed
@@ -91,8 +48,6 @@
#define CAM_PIN_HREF 23
#define CAM_PIN_PCLK 22
#endif
static const char *TAG = "example:take_picture";
static camera_config_t camera_config = {
@@ -115,12 +70,14 @@ static camera_config_t camera_config = {
.pin_pclk = CAM_PIN_PCLK,
//XCLK 20MHz or 10MHz for OV2640 double FPS (Experimental)
.xclk_freq_hz = 20000000,
// .xclk_freq_hz = 20000000, // Orginalwert
.xclk_freq_hz = 5000000, // Test, um die Bildfehler los zu werden !!!!
.ledc_timer = LEDC_TIMER_0,
.ledc_channel = LEDC_CHANNEL_0,
.pixel_format = PIXFORMAT_JPEG, //YUV422,GRAYSCALE,RGB565,JPEG
.frame_size = FRAMESIZE_UXGA, //QQVGA-UXGA Do not use sizes above QVGA when not JPEG
.frame_size = FRAMESIZE_VGA, //QQVGA-UXGA Do not use sizes above QVGA when not JPEG
// .frame_size = FRAMESIZE_UXGA, //QQVGA-UXGA Do not use sizes above QVGA when not JPEG
@@ -128,14 +85,11 @@ static camera_config_t camera_config = {
.fb_count = 1 //if more than one, i2s runs in continuous mode. Use only with JPEG
};
/////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////
#include "driver/ledc.h"
CCamera Camera;
#define FLASH_GPIO GPIO_NUM_4
#define BLINK_GPIO GPIO_NUM_33
@@ -145,8 +99,6 @@ typedef struct {
} jpg_chunking_t;
///////////////////////////////////////////////////////////////////////////////////////////////////////
#define LEDC_LS_CH2_GPIO (4)
#define LEDC_LS_CH2_CHANNEL LEDC_CHANNEL_2
#define LEDC_LS_TIMER LEDC_TIMER_1
@@ -172,14 +124,6 @@ void test(){
////////////////////////////////////////////////////////////////////////////////////////////////////////
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){
@@ -200,15 +144,144 @@ void CCamera::SetQualitySize(int qual, framesize_t resol)
s->set_framesize(s, resol);
ActualResolution = resol;
ActualQuality = qual;
if (resol == FRAMESIZE_QVGA)
{
image_height = 240;
image_width = 320;
}
if (resol == FRAMESIZE_VGA)
{
image_height = 480;
image_width = 640;
}
// No higher Mode than VGA, damit der Kameraspeicher ausreicht.
/*
if (resol == FRAMESIZE_SVGA)
{
image_height = 600;
image_width = 800;
}
if (resol == FRAMESIZE_XGA)
{
image_height = 768;
image_width = 1024;
}
if (resol == FRAMESIZE_SXGA)
{
image_height = 1024;
image_width = 1280;
}
if (resol == FRAMESIZE_UXGA)
{
image_height = 1200;
image_width = 1600;
}
*/
}
esp_err_t CCamera::CaptureToBasisImage(CImageBasis *_Image, int delay)
{
string ftype;
uint8_t *zwischenspeicher = NULL;
LEDOnOff(true);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - Start");
#endif
if (delay > 0)
{
LightOnOff(true);
const TickType_t xDelay = delay / portTICK_PERIOD_MS;
vTaskDelay( xDelay );
}
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - After LightOn");
#endif
camera_fb_t * fb = esp_camera_fb_get();
if (!fb) {
ESP_LOGE(TAGCAMERACLASS, "Camera Capture Failed");
LEDOnOff(false);
return ESP_FAIL;
}
int _size = fb->len;
zwischenspeicher = (uint8_t*) malloc(_size);
for (int i = 0; i < _size; ++i)
*(zwischenspeicher + i) = *(fb->buf + i);
esp_camera_fb_return(fb);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - After fb_get");
#endif
LEDOnOff(false);
if (delay > 0)
LightOnOff(false);
// TickType_t xDelay = 1000 / portTICK_PERIOD_MS;
// vTaskDelay( xDelay ); // wait for power to recover
uint8_t * buf = NULL;
CImageBasis _zwImage;
_zwImage.LoadFromMemory(zwischenspeicher, _size);
free(zwischenspeicher);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - After LoadFromMemory");
#endif
stbi_uc* p_target;
stbi_uc* p_source;
int channels = 3;
int width = image_width;
int height = image_height;
#ifdef DEBUG_DETAIL_ON
std::string _zw = "Targetimage: " + std::to_string((int) _Image->rgb_image) + " Size: " + std::to_string(_Image->width) + ", " + std::to_string(_Image->height);
_zw = _zw + " _zwImage: " + std::to_string((int) _zwImage.rgb_image) + " Size: " + std::to_string(_zwImage.width) + ", " + std::to_string(_zwImage.height);
LogFile.WriteToFile(_zw);
#endif
for (int x = 0; x < width; ++x)
for (int y = 0; y < height; ++y)
{
p_target = _Image->rgb_image + (channels * (y * width + x));
p_source = _zwImage.rgb_image + (channels * (y * width + x));
p_target[0] = p_source[0];
p_target[1] = p_source[1];
p_target[2] = p_source[2];
}
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - After Copy To Target");
#endif
free(buf);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - Done");
#endif
return ESP_OK;
}
esp_err_t CCamera::CaptureToFile(std::string nm, int delay)
{
// nm = "/sdcard/josef_zw.bmp";
string ftype;
LEDOnOff(true);
LEDOnOff(true); // Abgeschaltet, um Strom zu sparen !!!!!!
if (delay > 0)
{
@@ -224,13 +297,22 @@ esp_err_t CCamera::CaptureToFile(std::string nm, int delay)
return ESP_FAIL;
}
LEDOnOff(false);
#ifdef DEBUG_DETAIL_ON
printf("w %d, h %d, size %d\n", fb->width, fb->height, fb->len);
#endif
nm = FormatFileName(nm);
#ifdef DEBUG_DETAIL_ON
printf("Save Camera to : %s\n", nm.c_str());
#endif
ftype = toUpper(getFileType(nm));
#ifdef DEBUG_DETAIL_ON
printf("Filetype: %s\n", ftype.c_str());
#endif
uint8_t * buf = NULL;
size_t buf_len = 0;
@@ -255,7 +337,7 @@ esp_err_t CCamera::CaptureToFile(std::string nm, int delay)
}
}
FILE * fp = fopen(nm.c_str(), "wb");
FILE * fp = OpenFileAndWait(nm.c_str(), "wb");
if (fp == NULL) /* If an error occurs during the file creation */
{
fprintf(stderr, "fopen() failed for '%s'\n", nm.c_str());
@@ -286,15 +368,29 @@ esp_err_t CCamera::CaptureToHTTP(httpd_req_t *req, int delay)
size_t fb_len = 0;
int64_t fr_start = esp_timer_get_time();
LEDOnOff(true);
if (delay > 0)
{
LightOnOff(true);
const TickType_t xDelay = delay / portTICK_PERIOD_MS;
vTaskDelay( xDelay );
}
fb = esp_camera_fb_get();
if (!fb) {
ESP_LOGE(TAGCAMERACLASS, "Camera capture failed");
httpd_resp_send_500(req);
return ESP_FAIL;
}
LEDOnOff(false);
res = httpd_resp_set_type(req, "image/jpeg");
if(res == ESP_OK){
res = httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=capture.jpg");
res = httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=raw.jpg");
}
if(res == ESP_OK){
@@ -312,6 +408,12 @@ esp_err_t CCamera::CaptureToHTTP(httpd_req_t *req, int delay)
int64_t fr_end = esp_timer_get_time();
ESP_LOGI(TAGCAMERACLASS, "JPG: %uKB %ums", (uint32_t)(fb_len/1024), (uint32_t)((fr_end - fr_start)/1000));
if (delay > 0)
{
LightOnOff(false);
}
return res;
}
@@ -357,7 +459,9 @@ void CCamera::GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol
printf("Query: "); printf(_query); printf("\n");
if (httpd_query_key_value(_query, "size", _size, 10) == ESP_OK)
{
#ifdef DEBUG_DETAIL_ON
printf("Size: "); printf(_size); printf("\n");
#endif
if (strcmp(_size, "QVGA") == 0)
resol = FRAMESIZE_QVGA; // 320x240
if (strcmp(_size, "VGA") == 0)
@@ -369,11 +473,13 @@ void CCamera::GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol
if (strcmp(_size, "SXGA") == 0)
resol = FRAMESIZE_SXGA; // 1280x1024
if (strcmp(_size, "UXGA") == 0)
resol = FRAMESIZE_UXGA; // 1600x1200
resol = FRAMESIZE_UXGA; // 1600x1200
}
if (httpd_query_key_value(_query, "quality", _qual, 10) == ESP_OK)
{
#ifdef DEBUG_DETAIL_ON
printf("Quality: "); printf(_qual); printf("\n");
#endif
qual = atoi(_qual);
if (qual > 63)
@@ -404,13 +510,13 @@ framesize_t CCamera::TextToFramesize(const char * _size)
CCamera::CCamera()
{
#ifdef DEBUG_DETAIL_ON
printf("CreateClassCamera\n");
#endif
}
esp_err_t CCamera::InitCam()
{
printf("Init Flash\n");
//power up the camera if PWDN pin is defined
if(CAM_PIN_PWDN != -1){
// Init the GPIO
gpio_pad_select_gpio(CAM_PIN_PWDN);

View File

@@ -10,12 +10,13 @@
#include "esp_camera.h"
#include <string>
#include <esp_http_server.h>
#include "CImageBasis.h"
#define CAMERA_MODEL_AI_THINKER
static const char *TAGCAMERACLASS = "server_part_camera";
static const char *TAGCAMERACLASS = "server_part_camera";
class CCamera {
@@ -24,6 +25,8 @@ class CCamera {
framesize_t ActualResolution;
public:
int image_height, image_width;
CCamera();
esp_err_t InitCam();
@@ -35,13 +38,11 @@ class CCamera {
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);
};
extern CCamera Camera;
#endif

View File

@@ -11,6 +11,9 @@
#define SCRATCH_BUFSIZE2 8192
char scratch2[SCRATCH_BUFSIZE2];
//#define DEBUG_DETAIL_ON
void PowerResetCamera(){
ESP_LOGD(TAGPARTCAMERA, "Resetting camera by power down line");
@@ -29,42 +32,72 @@ void PowerResetCamera(){
esp_err_t handler_lightOn(httpd_req_t *req)
{
LogFile.WriteToFile("handler_lightOn");
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_lightOn - Start");
printf("handler_lightOn uri:\n"); printf(req->uri); printf("\n");
#endif
Camera.LightOnOff(true);
const char* resp_str = (const char*) req->user_ctx;
httpd_resp_send(req, resp_str, strlen(resp_str));
httpd_resp_send(req, resp_str, strlen(resp_str));
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_lightOn - Done");
#endif
return ESP_OK;
};
esp_err_t handler_lightOff(httpd_req_t *req)
{
LogFile.WriteToFile("handler_lightOff");
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_lightOff - Start");
printf("handler_lightOff uri:\n"); printf(req->uri); printf("\n");
#endif
Camera.LightOnOff(false);
const char* resp_str = (const char*) req->user_ctx;
httpd_resp_send(req, resp_str, strlen(resp_str));
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_lightOff - Done");
#endif
return ESP_OK;
};
esp_err_t handler_capture(httpd_req_t *req)
{
LogFile.WriteToFile("handler_capture");
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_capture - Start");
#endif
int quality;
framesize_t res;
Camera.GetCameraParameter(req, quality, res);
#ifdef DEBUG_DETAIL_ON
printf("Size: %d", res); printf(" Quality: %d\n", quality);
#endif
Camera.SetQualitySize(quality, res);
esp_err_t ressult;
ressult = Camera.CaptureToHTTP(req);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_capture - Done");
#endif
return ressult;
};
esp_err_t handler_capture_with_ligth(httpd_req_t *req)
{
LogFile.WriteHeapInfo("handler_capture_with_ligth - Start");
LogFile.WriteToFile("handler_capture_with_ligth");
char _query[100];
char _delay[10];
@@ -78,7 +111,9 @@ esp_err_t handler_capture_with_ligth(httpd_req_t *req)
printf("Query: "); printf(_query); printf("\n");
if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK)
{
printf("Delay: "); printf(_delay); printf("\n");
#ifdef DEBUG_DETAIL_ON
printf("Delay: "); printf(_delay); printf("\n");
#endif
delay = atoi(_delay);
if (delay < 0)
@@ -87,9 +122,12 @@ esp_err_t handler_capture_with_ligth(httpd_req_t *req)
};
Camera.GetCameraParameter(req, quality, res);
printf("Size: %d", res); printf(" Quality: %d\n", quality);
Camera.SetQualitySize(quality, res);
#ifdef DEBUG_DETAIL_ON
printf("Size: %d", res); printf(" Quality: %d\n", quality);
#endif
Camera.SetQualitySize(quality, res);
Camera.LightOnOff(true);
const TickType_t xDelay = delay / portTICK_PERIOD_MS;
vTaskDelay( xDelay );
@@ -98,7 +136,11 @@ esp_err_t handler_capture_with_ligth(httpd_req_t *req)
ressult = Camera.CaptureToHTTP(req);
Camera.LightOnOff(false);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_capture_with_ligth - Done");
#endif
return ressult;
};
@@ -106,7 +148,10 @@ esp_err_t handler_capture_with_ligth(httpd_req_t *req)
esp_err_t handler_capture_save_to_file(httpd_req_t *req)
{
LogFile.WriteToFile("handler_capture_save_to_file");
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_capture_save_to_file - Start");
#endif
char _query[100];
char _delay[10];
int delay = 0;
@@ -123,14 +168,18 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req)
if (httpd_query_key_value(_query, "filename", filename, 100) == ESP_OK)
{
fn.append(filename);
#ifdef DEBUG_DETAIL_ON
printf("Filename: "); printf(fn.c_str()); printf("\n");
#endif
}
else
fn.append("noname.jpg");
if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK)
{
#ifdef DEBUG_DETAIL_ON
printf("Delay: "); printf(_delay); printf("\n");
#endif
delay = atoi(_delay);
if (delay < 0)
@@ -142,7 +191,9 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req)
fn.append("noname.jpg");
Camera.GetCameraParameter(req, quality, res);
#ifdef DEBUG_DETAIL_ON
printf("Size: %d", res); printf(" Quality: %d\n", quality);
#endif
Camera.SetQualitySize(quality, res);
esp_err_t ressult;
@@ -151,6 +202,10 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req)
const char* resp_str = (const char*) fn.c_str();
httpd_resp_send(req, resp_str, strlen(resp_str));
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_capture_save_to_file - Done");
#endif
return ressult;
};
@@ -158,8 +213,10 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req)
void register_server_camera_uri(httpd_handle_t server)
{
#ifdef DEBUG_DETAIL_ON
ESP_LOGI(TAGPARTCAMERA, "server_part_camera - Registering URI handlers");
#endif
httpd_uri_t camuri = { };
camuri.method = HTTP_GET;

View File

@@ -68,6 +68,8 @@ static esp_err_t index_html_get_handler(httpd_req_t *req)
/* Handler to respond with an icon file embedded in flash.
* Browsers expect to GET website icon at URI /favicon.ico.
* This can be overridden by uploading file with same name */
/*
static esp_err_t favicon_get_handler(httpd_req_t *req)
{
extern const unsigned char favicon_ico_start[] asm("_binary_favicon_ico_start");
@@ -75,10 +77,10 @@ static esp_err_t favicon_get_handler(httpd_req_t *req)
const size_t favicon_ico_size = (favicon_ico_end - favicon_ico_start);
httpd_resp_set_type(req, "image/x-icon");
httpd_resp_send(req, (const char *)favicon_ico_start, favicon_ico_size);
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
return ESP_OK;
}
*/
/* Send HTTP response with a run-time generated html consisting of
* a list of all files and folders under the requested path.
@@ -121,7 +123,7 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath, const
/////////////////////////////////////////////////
if (!readonly) {
FILE *fd = fopen("/sdcard/html/upload_script.html", "r");
FILE *fd = OpenFileAndWait("/sdcard/html/upload_script.html", "r");
char *chunk = ((struct file_server_data *)req->user_ctx)->scratch;
size_t chunksize;
do {
@@ -231,7 +233,7 @@ static esp_err_t logfileact_get_handler(httpd_req_t *req)
std::string currentfilename = LogFile.GetCurrentFileName();
fd = fopen(currentfilename.c_str(), "r");
fd = OpenFileAndWait(currentfilename.c_str(), "r");
if (!fd) {
ESP_LOGE(TAG, "Failed to read existing file : %s", filepath);
/* Respond with 500 Internal Server Error */
@@ -337,7 +339,7 @@ static esp_err_t download_get_handler(httpd_req_t *req)
return ESP_FAIL;
}
fd = fopen(filepath, "r");
fd = OpenFileAndWait(filepath, "r");
if (!fd) {
ESP_LOGE(TAG, "Failed to read existing file : %s", filepath);
/* Respond with 500 Internal Server Error */
@@ -424,7 +426,7 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
return ESP_FAIL;
}
fd = fopen(filepath, "w");
fd = OpenFileAndWait(filepath, "w");
if (!fd) {
ESP_LOGE(TAG, "Failed to create file : %s", filepath);
/* Respond with 500 Internal Server Error */
@@ -710,7 +712,7 @@ void unzip(std::string _in_zip_file, std::string _target_directory){
zw = std::string(archive_filename);
zw = _target_directory + zw;
printf("Filename to extract: %s", zw.c_str());
FILE* fpTargetFile = fopen(zw.c_str(), "wb");
FILE* fpTargetFile = OpenFileAndWait(zw.c_str(), "wb");
fwrite(p, 1, (uint)uncomp_size, fpTargetFile);
fclose(fpTargetFile);

View File

@@ -10,6 +10,8 @@
#include "esp_err.h"
#include "esp_log.h"
#include "Helper.h"
#include "esp_http_server.h"
@@ -23,9 +25,9 @@ char scratch[SCRATCH_BUFSIZE];
(strcasecmp(&filename[strlen(filename) - sizeof(ext) + 1], ext) == 0)
esp_err_t send_file(httpd_req_t *req, std::string filename, struct stat * file_stat)
esp_err_t send_file(httpd_req_t *req, std::string filename)
{
FILE *fd = fopen(filename.c_str(), "r");
FILE *fd = OpenFileAndWait(filename.c_str(), "r");
if (!fd) {
ESP_LOGE(TAG, "Failed to read existing file : %s", filename.c_str());
/* Respond with 500 Internal Server Error */
@@ -33,7 +35,7 @@ esp_err_t send_file(httpd_req_t *req, std::string filename, struct stat * file_
return ESP_FAIL;
}
ESP_LOGI(TAG, "Sending file : %s (%ld bytes)...", filename.c_str(), file_stat->st_size);
ESP_LOGI(TAG, "Sending file : %s ...", filename.c_str());
set_content_type_from_file(req, filename.c_str());
/* Retrieve the pointer to scratch buffer for temporary storage */
@@ -65,6 +67,7 @@ esp_err_t send_file(httpd_req_t *req, std::string filename, struct stat * file_
/* Copies the full path into destination buffer and returns
* pointer to path (skipping the preceding base path) */
const char* get_path_from_uri(char *dest, const char *base_path, const char *uri, size_t destsize)

View File

@@ -5,6 +5,6 @@
const char* get_path_from_uri(char *dest, const char *base_path, const char *uri, size_t destsize);
esp_err_t send_file(httpd_req_t *req, std::string filename, struct stat * file_stat);
esp_err_t send_file(httpd_req_t *req, std::string filename);
esp_err_t set_content_type_from_file(httpd_req_t *req, const char *filename);

View File

@@ -31,6 +31,10 @@
#include "ClassLogFile.h"
#include "Helper.h"
// #define DEBUG_DETAIL_ON
#define BUFFSIZE 1024
@@ -89,7 +93,7 @@ static bool ota_example_task(std::string fn)
int data_read;
FILE* f = fopen(fn.c_str(), "rb"); // vorher nur "r"
FILE* f = OpenFileAndWait(fn.c_str(), "rb"); // vorher nur "r"
data_read = fread(ota_write_data, 1, BUFFSIZE, f);
while (data_read > 0) {
@@ -301,6 +305,10 @@ void CheckOTAUpdate(void)
esp_err_t handler_ota_update(httpd_req_t *req)
{
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_ota_update - Start");
#endif
LogFile.WriteToFile("handler_ota_update");
char _query[200];
char _filename[30];
@@ -376,7 +384,11 @@ esp_err_t handler_ota_update(httpd_req_t *req)
}
httpd_resp_send(req, resp_str, strlen(resp_str));
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_ota_update - Done");
#endif
return ESP_OK;
};
@@ -412,6 +424,10 @@ void doReboot(){
esp_err_t handler_reboot(httpd_req_t *req)
{
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_reboot - Start");
#endif
LogFile.WriteToFile("handler_reboot");
ESP_LOGI(TAGPARTOTA, "!!! System will restart within 5 sec!!!");
const char* resp_str = "!!! System will restart within 5 sec!!!";
@@ -419,6 +435,10 @@ esp_err_t handler_reboot(httpd_req_t *req)
doReboot();
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_reboot - Done");
#endif
return ESP_OK;
}

View File

@@ -8,4 +8,5 @@ static const char *TAGPARTOTA = "server_ota";
void register_server_ota_sdcard_uri(httpd_handle_t server);
void CheckOTAUpdate();
void doReboot();
void doReboot();

View File

@@ -2,6 +2,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
idf_component_register(SRCS ${app_sources}
INCLUDE_DIRS "."
REQUIRES jomjol_tfliteclass jomjol_helper jomjol_controlcamera jomjol_mqtt jomjol_fileserver_ota)
REQUIRES jomjol_tfliteclass jomjol_helper jomjol_controlcamera jomjol_mqtt jomjol_fileserver_ota jomjol_image_proc)

View File

@@ -9,9 +9,11 @@
void ClassFlow::SetInitialParameter(void)
{
ListFlowControll = NULL;
previousElement = NULL;
}
//std::vector<string> ClassFlow::ZerlegeZeile(std::string input, std::string delimiter);
std::vector<string> ClassFlow::ZerlegeZeile(std::string input, std::string delimiter)
{
@@ -55,7 +57,6 @@ bool ClassFlow::GetNextParagraph(FILE* pfile, string& aktparamgraph)
ClassFlow::ClassFlow(void)
{
SetInitialParameter();
ListFlowControll = NULL;
}
ClassFlow::ClassFlow(std::vector<ClassFlow*> * lfc)
@@ -64,6 +65,13 @@ ClassFlow::ClassFlow(std::vector<ClassFlow*> * lfc)
ListFlowControll = lfc;
}
ClassFlow::ClassFlow(std::vector<ClassFlow*> * lfc, ClassFlow *_prev)
{
SetInitialParameter();
ListFlowControll = lfc;
previousElement = _prev;
}
bool ClassFlow::ReadParameter(FILE* pfile, string &aktparamgraph)
{
return false;
@@ -100,7 +108,7 @@ bool ClassFlow::getNextLine(FILE* pfile, string *rt)
}
*rt = zw;
*rt = trim(*rt);
while (zw[0] == '#' || (rt->size() == 0)) // Kommentarzeilen und Leerzeilen überspringen
while (zw[0] == ';' || zw[0] == '#' || (rt->size() == 0)) // Kommentarzeilen (; oder #) und Leerzeilen überspringen
{
fgets(zw, 1024, pfile);
printf("%s", zw);

View File

@@ -5,7 +5,7 @@
#include <vector>
#include "Helper.h"
#include "CFindTemplate.h"
#include "CImageBasis.h"
using namespace std;
@@ -16,7 +16,10 @@ using namespace std;
struct HTMLInfo
{
float val;
CImageBasis *image = NULL;
CImageBasis *image_org = NULL;
std::string filename;
std::string filename_org;
};
@@ -30,12 +33,15 @@ protected:
bool getNextLine(FILE* pfile, string* rt);
std::vector<ClassFlow*>* ListFlowControll;
ClassFlow *previousElement;
virtual void SetInitialParameter(void);
public:
ClassFlow(void);
ClassFlow(std::vector<ClassFlow*> * lfc);
ClassFlow(std::vector<ClassFlow*> * lfc, ClassFlow *_prev);
virtual bool ReadParameter(FILE* pfile, string &aktparamgraph);
virtual bool doFlow(string time);
virtual string getHTMLSingleStep(string host);

View File

@@ -1,29 +1,55 @@
#include "ClassFlowAlignment.h"
#include "ClassFlowMakeImage.h"
#include "ClassFlow.h"
#include "CRotateImage.h"
#include "ClassLogFile.h"
ClassFlowAlignment::ClassFlowAlignment()
bool AlignmentExtendedDebugging = true;
void ClassFlowAlignment::SetInitialParameter(void)
{
initalrotate = 0;
anz_ref = 0;
suchex = 40;
suchey = 40;
initialmirror = false;
SaveAllFiles = false;
namerawimage = "/sdcard/img_tmp/raw.jpg";
ListFlowControll = NULL;
AlignAndCutImage = NULL;
ImageBasis = NULL;
ImageTMP = NULL;
previousElement = NULL;
ref_dx[0] = 0; ref_dx[1] = 0;
ref_dy[0] = 0; ref_dy[1] = 0;
}
ClassFlowAlignment::ClassFlowAlignment(std::vector<ClassFlow*>* lfc)
{
initalrotate = 0;
anz_ref = 0;
suchex = 40;
suchey = 40;
initialmirror = false;
namerawimage = "/sdcard/img_tmp/raw.jpg";
SetInitialParameter();
ListFlowControll = lfc;
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowMakeImage") == 0)
{
ImageBasis = ((ClassFlowMakeImage*) (*ListFlowControll)[i])->rawImage;
}
}
if (!ImageBasis) // die Funktion Bilder aufnehmen existiert nicht --> muss erst erzeugt werden NUR ZU TESTZWECKEN
{
if (AlignmentExtendedDebugging) printf("CImageBasis musste erzeugt werden\n");
ImageBasis = new CImageBasis(namerawimage);
}
}
bool ClassFlowAlignment::ReadParameter(FILE* pfile, string& aktparamgraph)
{
std::vector<string> zerlegt;
@@ -59,11 +85,18 @@ bool ClassFlowAlignment::ReadParameter(FILE* pfile, string& aktparamgraph)
}
if ((zerlegt.size() == 3) && (anz_ref < 2))
{
this->reffilename[anz_ref] = FormatFileName("/sdcard" + zerlegt[0]);
this->ref_x[anz_ref] = std::stod(zerlegt[1]);
this->ref_y[anz_ref] = std::stod(zerlegt[2]);
reffilename[anz_ref] = FormatFileName("/sdcard" + zerlegt[0]);
ref_x[anz_ref] = std::stod(zerlegt[1]);
ref_y[anz_ref] = std::stod(zerlegt[2]);
anz_ref++;
}
if ((toUpper(zerlegt[0]) == "SAVEALLFILES") && (zerlegt.size() > 1))
{
if (toUpper(zerlegt[1]) == "TRUE")
SaveAllFiles = true;
}
}
return true;
@@ -80,72 +113,52 @@ string ClassFlowAlignment::getHTMLSingleStep(string host)
}
bool ClassFlowAlignment::doFlow(string time)
bool ClassFlowAlignment::doFlow(string time)
{
string input = namerawimage;
string output = "/sdcard/img_tmp/rot.jpg";
string output3 = "/sdcard/img_tmp/rot_roi.jpg";
string output2 = "/sdcard/img_tmp/alg.jpg";
string output4 = "/sdcard/img_tmp/alg_roi.jpg";
string output1 = "/sdcard/img_tmp/mirror.jpg";
if (!ImageTMP)
ImageTMP = new CImageBasis(ImageBasis, 5);
input = FormatFileName(input);
output = FormatFileName(output);
output2 = FormatFileName(output2);
if (AlignAndCutImage)
delete AlignAndCutImage;
AlignAndCutImage = new CAlignAndCutImage(ImageBasis, ImageTMP);
CRotateImage rt(AlignAndCutImage, ImageTMP);
if (initialmirror){
CRotate *rt;
rt = new CRotate(input);
if (!rt->ImageOkay()){
LogFile.WriteToFile("ClassFlowAlignment::doFlow CRotate Inital Mirror raw.jpg not okay!");
delete rt;
return false;
}
printf("do mirror\n");
rt->Mirror();
rt->SaveToFile(output1);
input = output1;
delete rt;
rt.Mirror();
if (SaveAllFiles) AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/mirror.jpg"));
}
if (initalrotate != 0)
{
CRotate *rt = NULL;
printf("Load rotationfile: %s\n", input.c_str());
rt = new CRotate(input);
if (!rt->ImageOkay()){
LogFile.WriteToFile("ClassFlowAlignment::doFlow CRotate raw.jpg not okay!");
delete rt;
return false;
}
rt->Rotate(this->initalrotate);
rt->SaveToFile(output);
delete rt;
rt.Rotate(initalrotate);
if (SaveAllFiles) AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/rot.jpg"));
}
else
AlignAndCutImage->Align(reffilename[0], ref_x[0], ref_y[0], reffilename[1], ref_x[1], ref_y[1], suchex, suchey, "");
AlignAndCutImage->GetRefSize(ref_dx, ref_dy);
if (SaveAllFiles) AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/alg.jpg"));
if (SaveAllFiles)
{
CopyFile(input, output);
DrawRef(ImageTMP);
ImageTMP->SaveToFile(FormatFileName("/sdcard/img_tmp/alg_roi.jpg"));
}
CAlignAndCutImage *caic;
caic = new CAlignAndCutImage(output);
caic->Align(this->reffilename[0], this->ref_x[0], this->ref_y[0], this->reffilename[1], this->ref_x[1], this->ref_y[1], suchex, suchey, output3);
caic->SaveToFile(output2);
printf("Startwriting Output4:%s\n", output4.c_str());
if (output4.length() > 0)
if (ImageTMP) // nuss gelöscht werden, um Speicherplatz für das Laden von tflite zu haben
{
caic->drawRect(ref_x[0], ref_y[0], caic->t0_dx, caic->t0_dy, 255, 0, 0, 2);
caic->drawRect(ref_x[1], ref_y[1], caic->t1_dx, caic->t1_dy, 255, 0, 0, 2);
caic->SaveToFile(output4);
printf("Write output4: %s\n", output4.c_str());
}
delete ImageTMP;
ImageTMP = NULL;
}
delete caic;
// Align mit Templates
return true;
}
void ClassFlowAlignment::DrawRef(CImageBasis *_zw)
{
_zw->drawRect(ref_x[0], ref_y[0], ref_dx[0], ref_dy[0], 255, 0, 0, 2);
_zw->drawRect(ref_x[1], ref_y[1], ref_dx[1], ref_dy[1], 255, 0, 0, 2);
}

View File

@@ -2,6 +2,7 @@
#include "ClassFlow.h"
#include "Helper.h"
#include "CAlignAndCutImage.h"
#include <string>
@@ -15,13 +16,24 @@ protected:
bool initialmirror;
string reffilename[2];
int ref_x[2], ref_y[2];
int ref_dx[2], ref_dy[2];
int anz_ref;
int suchex, suchey;
string namerawimage;
bool SaveAllFiles;
CAlignAndCutImage *AlignAndCutImage;
void SetInitialParameter(void);
public:
ClassFlowAlignment();
CImageBasis *ImageBasis, *ImageTMP;
ClassFlowAlignment(std::vector<ClassFlow*>* lfc);
CAlignAndCutImage* GetAlignAndCutImage(){return AlignAndCutImage;};
void DrawRef(CImageBasis *_zw);
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string getHTMLSingleStep(string host);

View File

@@ -16,21 +16,30 @@ static const char* TAG = "flow_analog";
bool debugdetailanalog = false;
ClassFlowAnalog::ClassFlowAnalog() : ClassFlowImage(TAG)
void ClassFlowAnalog::SetInitialParameter(void)
{
string cnnmodelfile = "";
modelxsize = 1;
modelysize = 1;
ListFlowControll = NULL;
}
previousElement = NULL;
SaveAllFiles = false;
}
ClassFlowAnalog::ClassFlowAnalog(std::vector<ClassFlow*>* lfc) : ClassFlowImage(lfc, TAG)
{
string cnnmodelfile = "";
modelxsize = 1;
modelysize = 1;
}
SetInitialParameter();
ListFlowControll = lfc;
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowAlignment") == 0)
{
flowpostalignment = (ClassFlowAlignment*) (*ListFlowControll)[i];
}
}
}
string ClassFlowAnalog::getReadout()
@@ -113,9 +122,24 @@ bool ClassFlowAnalog::ReadParameter(FILE* pfile, string& aktparamgraph)
neuroi->deltax = std::stoi(zerlegt[3]);
neuroi->deltay = std::stoi(zerlegt[4]);
neuroi->result = -1;
neuroi->image = NULL;
neuroi->image_org = NULL;
ROI.push_back(neuroi);
}
if ((toUpper(zerlegt[0]) == "SAVEALLFILES") && (zerlegt.size() > 1))
{
if (toUpper(zerlegt[1]) == "TRUE")
SaveAllFiles = true;
}
}
for (int i = 0; i < ROI.size(); ++i)
{
ROI[i]->image = new CImageBasis(modelxsize, modelysize, 3);
ROI[i]->image_org = new CImageBasis(ROI[i]->deltax, ROI[i]->deltay, 3);
}
return true;
}
@@ -162,79 +186,37 @@ bool ClassFlowAnalog::doFlow(string time)
bool ClassFlowAnalog::doAlignAndCut(string time)
{
string input = "/sdcard/img_tmp/alg.jpg";
string input_roi = "/sdcard/img_tmp/alg_roi.jpg";
string ioresize = "/sdcard/img_tmp/resize.bmp";
string output;
string nm;
input = FormatFileName(input);
input_roi = FormatFileName(input_roi);
CResizeImage *rs;
CImageBasis *img_roi = NULL;
CAlignAndCutImage *caic = new CAlignAndCutImage(input);
if (!caic->ImageOkay()){
if (debugdetailanalog) LogFile.WriteToFile("ClassFlowAnalog::doAlignAndCut not okay!");
delete caic;
return false;
}
if (input_roi.length() > 0){
img_roi = new CImageBasis(input_roi);
if (!img_roi->ImageOkay()){
if (debugdetailanalog) LogFile.WriteToFile("ClassFlowAnalog::doAlignAndCut ImageRoi not okay!");
delete caic;
delete img_roi;
return false;
}
}
CAlignAndCutImage *caic = flowpostalignment->GetAlignAndCutImage();
for (int i = 0; i < ROI.size(); ++i)
{
printf("Analog %d - Align&Cut\n", i);
output = "/sdcard/img_tmp/" + ROI[i]->name + ".jpg";
output = FormatFileName(output);
caic->CutAndSave(output, ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay);
caic->CutAndSave(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, ROI[i]->image_org);
if (SaveAllFiles) ROI[i]->image_org->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ROI[i]->name + ".jpg"));
rs = new CResizeImage(output);
if (!rs->ImageOkay()){
if (debugdetailanalog) LogFile.WriteToFile("ClassFlowAnalog::doAlignAndCut CResizeImage(output);!");
delete caic;
delete rs;
return false;
}
rs->Resize(modelxsize, modelysize);
ioresize = "/sdcard/img_tmp/ra" + std::to_string(i) + ".bmp";
ioresize = FormatFileName(ioresize);
rs->SaveToFile(ioresize);
delete rs;
if (img_roi)
{
int r = 0;
int g = 255;
int b = 0;
img_roi->drawRect(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, r, g, b, 1);
img_roi->drawCircle((int) (ROI[i]->posx + ROI[i]->deltax/2), (int) (ROI[i]->posy + ROI[i]->deltay/2), (int) (ROI[i]->deltax/2), r, g, b, 2);
img_roi->drawLine((int) (ROI[i]->posx + ROI[i]->deltax/2), (int) ROI[i]->posy, (int) (ROI[i]->posx + ROI[i]->deltax/2), (int) (ROI[i]->posy + ROI[i]->deltay), r, g, b, 2);
img_roi->drawLine((int) ROI[i]->posx, (int) (ROI[i]->posy + ROI[i]->deltay/2), (int) ROI[i]->posx + ROI[i]->deltax, (int) (ROI[i]->posy + ROI[i]->deltay/2), r, g, b, 2);
}
ROI[i]->image_org->Resize(modelxsize, modelysize, ROI[i]->image);
if (SaveAllFiles) ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ROI[i]->name + ".bmp"));
}
delete caic;
if (img_roi)
{
img_roi->SaveToFile(input_roi);
delete img_roi;
}
return true;
}
void ClassFlowAnalog::DrawROI(CImageBasis *_zw)
{
int r = 0;
int g = 255;
int b = 0;
for (int i = 0; i < ROI.size(); ++i)
{
_zw->drawRect(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, r, g, b, 1);
_zw->drawCircle((int) (ROI[i]->posx + ROI[i]->deltax/2), (int) (ROI[i]->posy + ROI[i]->deltay/2), (int) (ROI[i]->deltax/2), r, g, b, 2);
_zw->drawLine((int) (ROI[i]->posx + ROI[i]->deltax/2), (int) ROI[i]->posy, (int) (ROI[i]->posx + ROI[i]->deltax/2), (int) (ROI[i]->posy + ROI[i]->deltay), r, g, b, 2);
_zw->drawLine((int) ROI[i]->posx, (int) (ROI[i]->posy + ROI[i]->deltay/2), (int) ROI[i]->posx + ROI[i]->deltax, (int) (ROI[i]->posy + ROI[i]->deltay/2), r, g, b, 2);
}
}
bool ClassFlowAnalog::doNeuralNetwork(string time)
{
string logPath = CreateLogFolder(time);
@@ -265,7 +247,8 @@ bool ClassFlowAnalog::doNeuralNetwork(string time)
#ifndef OHNETFLITE
// LogFile.WriteToFile("ClassFlowAnalog::doNeuralNetwork vor CNN tflite->LoadInputImage(ioresize)");
tflite->LoadInputImage(ioresize);
// tflite->LoadInputImage(ioresize);
tflite->LoadInputImageBasis(ROI[i]->image);
tflite->Invoke();
if (debugdetailanalog) LogFile.WriteToFile("Nach Invoke");
@@ -278,9 +261,12 @@ bool ClassFlowAnalog::doNeuralNetwork(string time)
// printf("Result sin, cos, ziffer: %f, %f, %f\n", f1, f2, result);
ROI[i]->result = result * 10;
printf("Result Analog%i: %f\n", i, ROI[i]->result);
printf("Result Analog%i: %f\n", i, ROI[i]->result);
LogImage(logPath, ROI[i]->name, &ROI[i]->result, NULL, time);
if (isLogImage)
{
LogImage(logPath, ROI[i]->name, &ROI[i]->result, NULL, time, ROI[i]->image_org);
}
}
#ifndef OHNETFLITE
delete tflite;
@@ -297,8 +283,11 @@ std::vector<HTMLInfo*> ClassFlowAnalog::GetHTMLInfo()
for (int i = 0; i < ROI.size(); ++i)
{
HTMLInfo *zw = new HTMLInfo;
zw->filename = ROI[i]->name + ".jpg";
zw->filename = ROI[i]->name + ".bmp";
zw->filename_org = ROI[i]->name + ".jpg";
zw->val = ROI[i]->result;
zw->image = ROI[i]->image;
zw->image_org = ROI[i]->image_org;
result.push_back(zw);
}

View File

@@ -1,10 +1,12 @@
#pragma once
#include "ClassFlowImage.h"
#include "ClassFlowAlignment.h"
// #include "CTfLiteClass.h"
struct roianalog {
int posx, posy, deltax, deltay;
float result;
CImageBasis *image, *image_org;
string name;
};
@@ -17,14 +19,21 @@ protected:
string cnnmodelfile;
int modelxsize, modelysize;
int ZeigerEval(float zahl, int ziffer_vorgaenger);
bool SaveAllFiles;
ClassFlowAlignment* flowpostalignment;
void SetInitialParameter(void);
public:
ClassFlowAnalog();
ClassFlowAnalog(std::vector<ClassFlow*>* lfc);
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string getHTMLSingleStep(string host);
string getReadout();
string getReadout();
void DrawROI(CImageBasis *_zw);
bool doNeuralNetwork(string time);
bool doAlignAndCut(string time);

View File

@@ -9,8 +9,13 @@
#include "Helper.h"
#include "server_ota.h"
#include "server_help.h"
//#define DEBUG_DETAIL_ON
static const char* TAG = "flow_controll";
std::string ClassFlowControll::doSingleStep(std::string _stepname, std::string _host){
std::string _classname = "";
std::string result = "";
@@ -68,6 +73,9 @@ void ClassFlowControll::SetInitialParameter(void)
AutoStart = false;
SetupModeActive = false;
AutoIntervall = 10;
flowdigit = NULL;
flowanalog = NULL;
flowpostprocessing = NULL;
}
bool ClassFlowControll::isAutoStart(long &_intervall)
@@ -83,13 +91,25 @@ ClassFlow* ClassFlowControll::CreateClassFlow(std::string _type)
_type = trim(_type);
if (toUpper(_type).compare("[MAKEIMAGE]") == 0)
{
cfc = new ClassFlowMakeImage(&FlowControll);
flowmakeimage = (ClassFlowMakeImage*) cfc;
}
if (toUpper(_type).compare("[ALIGNMENT]") == 0)
{
cfc = new ClassFlowAlignment(&FlowControll);
flowalignment = (ClassFlowAlignment*) cfc;
}
if (toUpper(_type).compare("[ANALOG]") == 0)
{
cfc = new ClassFlowAnalog(&FlowControll);
flowanalog = (ClassFlowAnalog*) cfc;
}
if (toUpper(_type).compare("[DIGITS]") == 0)
{
cfc = new ClassFlowDigit(&FlowControll);
flowdigit = (ClassFlowDigit*) cfc;
}
if (toUpper(_type).compare("[MQTT]") == 0)
cfc = new ClassFlowMQTT(&FlowControll);
if (toUpper(_type).compare("[POSTPROCESSING]") == 0)
@@ -122,7 +142,7 @@ void ClassFlowControll::InitFlow(std::string config)
ClassFlow* cfc;
FILE* pFile;
config = FormatFileName(config);
pFile = fopen(config.c_str(), "r");
pFile = OpenFileAndWait(config.c_str(), "r");
line = "";
@@ -139,6 +159,7 @@ void ClassFlowControll::InitFlow(std::string config)
cfc = CreateClassFlow(line);
if (cfc)
{
printf("Start ReadParameter\n");
cfc->ReadParameter(pFile, line);
}
else
@@ -158,9 +179,7 @@ std::string ClassFlowControll::getActStatus(){
}
void ClassFlowControll::doFlowMakeImageOnly(string time){
bool result = true;
std::string zw_time;
int repeat = 0;
for (int i = 0; i < FlowControll.size(); ++i)
{
@@ -181,12 +200,20 @@ bool ClassFlowControll::doFlow(string time)
std::string zw_time;
int repeat = 0;
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("ClassFlowAnalog::doFlow - Start");
#endif
for (int i = 0; i < FlowControll.size(); ++i)
{
zw_time = gettimestring("%Y%m%d-%H%M%S");
aktstatus = zw_time + ": " + FlowControll[i]->name();
// #ifdef DEBUG_DETAIL_ON
string zw = "FlowControll.doFlow - " + FlowControll[i]->name();
LogFile.WriteToFile(zw);
LogFile.WriteHeapInfo(zw);
// #endif
if (!FlowControll[i]->doFlow(time)){
repeat++;
LogFile.WriteToFile("Fehler im vorheriger Schritt - wird zum " + to_string(repeat) + ". Mal wiederholt");
@@ -202,6 +229,11 @@ bool ClassFlowControll::doFlow(string time)
{
result = true;
}
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("ClassFlowAnalog::doFlow");
#endif
}
zw_time = gettimestring("%Y%m%d-%H%M%S");
aktstatus = zw_time + ": Flow is done";
@@ -320,6 +352,14 @@ bool ClassFlowControll::ReadParameter(FILE* pfile, string& aktparamgraph)
setTimeZone(zerlegt[1]);
}
if ((toUpper(zerlegt[0]) == "TIMESERVER") && (zerlegt.size() > 1))
{
string zw = "Set TimeZone: " + zerlegt[1];
reset_servername(zerlegt[1]);
}
if ((toUpper(zerlegt[0]) == "SETUPMODE") && (zerlegt.size() > 1))
{
if (toUpper(zerlegt[1]) == "TRUE")
@@ -362,4 +402,85 @@ int ClassFlowControll::CleanTempFolder() {
ESP_LOGI(TAG, "%d files deleted", deleted);
return 0;
}
esp_err_t ClassFlowControll::SendRawJPG(httpd_req_t *req)
{
return flowmakeimage->SendRawJPG(req);
}
esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
{
printf("ClassFlowControll::GetJPGStream %s\n", _fn.c_str());
CImageBasis *_send = NULL;
esp_err_t result = ESP_FAIL;
bool Dodelete = false;
if (_fn == "alg.jpg")
{
_send = flowalignment->ImageBasis;
}
if (_fn == "alg_roi.jpg")
{
CImageBasis* _imgzw = new CImageBasis(flowalignment->ImageBasis);
flowalignment->DrawRef(_imgzw);
if (flowdigit) flowdigit->DrawROI(_imgzw);
if (flowanalog) flowanalog->DrawROI(_imgzw);
_send = _imgzw;
Dodelete = true;
}
std::vector<HTMLInfo*> htmlinfo;
htmlinfo = GetAllDigital();
for (int i = 0; i < htmlinfo.size(); ++i)
{
if (_fn == htmlinfo[i]->filename)
{
if (htmlinfo[i]->image)
_send = htmlinfo[i]->image;
}
if (_fn == htmlinfo[i]->filename_org)
{
if (htmlinfo[i]->image_org)
_send = htmlinfo[i]->image_org;
}
}
htmlinfo = GetAllAnalog();
for (int i = 0; i < htmlinfo.size(); ++i)
{
if (_fn == htmlinfo[i]->filename)
{
if (htmlinfo[i]->image)
_send = htmlinfo[i]->image;
}
if (_fn == htmlinfo[i]->filename_org)
{
if (htmlinfo[i]->image_org)
_send = htmlinfo[i]->image_org;
}
}
if (_send)
{
ESP_LOGI(TAG, "Sending file : %s ...", _fn.c_str());
set_content_type_from_file(req, _fn.c_str());
result = _send->SendJPGtoHTTP(req);
ESP_LOGI(TAG, "File sending complete");
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
}
if (Dodelete)
{
delete _send;
}
return result;
}

View File

@@ -17,6 +17,10 @@ class ClassFlowControll :
protected:
std::vector<ClassFlow*> FlowControll;
ClassFlowPostProcessing* flowpostprocessing;
ClassFlowAlignment* flowalignment;
ClassFlowAnalog* flowanalog;
ClassFlowDigit* flowdigit;
ClassFlowMakeImage* flowmakeimage;
ClassFlow* CreateClassFlow(std::string _type);
bool AutoStart;
@@ -35,6 +39,9 @@ public:
string GetPrevalue();
bool ReadParameter(FILE* pfile, string& aktparamgraph);
esp_err_t GetJPGStream(std::string _fn, httpd_req_t *req);
esp_err_t SendRawJPG(httpd_req_t *req);
std::string doSingleStep(std::string _stepname, std::string _host);
bool isAutoStart(long &_intervall);
@@ -49,3 +56,4 @@ public:
string name(){return "ClassFlowControll";};
};

View File

@@ -1,5 +1,6 @@
#include "ClassFlowDigit.h"
//#include "CFindTemplate.h"
//#include "CTfLiteClass.h"
@@ -15,19 +16,49 @@
static const char* TAG = "flow_digital";
ClassFlowDigit::ClassFlowDigit() : ClassFlowImage(TAG)
void ClassFlowDigit::SetInitialParameter(void)
{
string cnnmodelfile = "";
modelxsize = 1;
modelysize = 1;
ListFlowControll = NULL;
previousElement = NULL;
SaveAllFiles = false;
}
ClassFlowDigit::ClassFlowDigit() : ClassFlowImage(TAG)
{
SetInitialParameter();
}
ClassFlowDigit::ClassFlowDigit(std::vector<ClassFlow*>* lfc) : ClassFlowImage(lfc, TAG)
{
string cnnmodelfile = "";
modelxsize = 1;
modelysize = 1;
SetInitialParameter();
ListFlowControll = lfc;
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowAlignment") == 0)
{
flowpostalignment = (ClassFlowAlignment*) (*ListFlowControll)[i];
}
}
}
ClassFlowDigit::ClassFlowDigit(std::vector<ClassFlow*>* lfc, ClassFlow *_prev) : ClassFlowImage(lfc, _prev, TAG)
{
SetInitialParameter();
ListFlowControll = lfc;
previousElement = _prev;
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowAlignment") == 0)
{
flowpostalignment = (ClassFlowAlignment*) (*ListFlowControll)[i];
}
}
}
string ClassFlowDigit::getReadout()
@@ -85,9 +116,25 @@ bool ClassFlowDigit::ReadParameter(FILE* pfile, string& aktparamgraph)
neuroi->deltax = std::stoi(zerlegt[3]);
neuroi->deltay = std::stoi(zerlegt[4]);
neuroi->resultklasse = -1;
neuroi->image = NULL;
neuroi->image_org = NULL;
ROI.push_back(neuroi);
}
if ((toUpper(zerlegt[0]) == "SAVEALLFILES") && (zerlegt.size() > 1))
{
if (toUpper(zerlegt[1]) == "TRUE")
SaveAllFiles = true;
}
}
for (int i = 0; i < ROI.size(); ++i)
{
ROI[i]->image = new CImageBasis(modelxsize, modelysize, 3);
ROI[i]->image_org = new CImageBasis(ROI[i]->deltax, ROI[i]->deltay, 3);
}
return true;
}
@@ -133,60 +180,17 @@ bool ClassFlowDigit::doFlow(string time)
bool ClassFlowDigit::doAlignAndCut(string time)
{
string input = "/sdcard/img_tmp/alg.jpg";
string input_roi = "/sdcard/img_tmp/alg_roi.jpg";
string ioresize = "/sdcard/img_tmp/resize.bmp";
string output;
string nm;
input = FormatFileName(input);
input_roi = FormatFileName(input_roi);
CResizeImage *rs;
CImageBasis *img_roi = NULL;
CAlignAndCutImage *caic = new CAlignAndCutImage(input);
if (!caic->ImageOkay()){
LogFile.WriteToFile("ClassFlowDigit::doAlignAndCut not okay!");
delete caic;
return false;
}
if (input_roi.length() > 0){
img_roi = new CImageBasis(input_roi);
if (!img_roi->ImageOkay()){
LogFile.WriteToFile("ClassFlowDigit::doAlignAndCut ImageRoi not okay!");
delete caic;
delete img_roi;
return false;
}
}
CAlignAndCutImage *caic = flowpostalignment->GetAlignAndCutImage();
for (int i = 0; i < ROI.size(); ++i)
{
printf("DigitalDigit %d - Align&Cut\n", i);
output = "/sdcard/img_tmp/" + ROI[i]->name + ".jpg";
output = FormatFileName(output);
caic->CutAndSave(output, ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay);
caic->CutAndSave(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, ROI[i]->image_org);
if (SaveAllFiles) ROI[i]->image_org->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ROI[i]->name + ".jpg"));
rs = new CResizeImage(output);
rs->Resize(modelxsize, modelysize);
ioresize = "/sdcard/img_tmp/rd" + std::to_string(i) + ".bmp";
ioresize = FormatFileName(ioresize);
rs->SaveToFile(ioresize);
delete rs;
if (img_roi)
{
img_roi->drawRect(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, 0, 0, 255, 2);
}
}
delete caic;
if (img_roi)
{
img_roi->SaveToFile(input_roi);
delete img_roi;
ROI[i]->image_org->Resize(modelxsize, modelysize, ROI[i]->image);
if (SaveAllFiles) ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ROI[i]->name + ".bmp"));
}
return true;
@@ -196,17 +200,9 @@ bool ClassFlowDigit::doNeuralNetwork(string time)
{
string logPath = CreateLogFolder(time);
string input = "/sdcard/img_tmp/alg.jpg";
string ioresize = "/sdcard/img_tmp/resize.bmp";
string output;
string nm;
input = FormatFileName(input);
#ifndef OHNETFLITE
CTfLiteClass *tflite = new CTfLiteClass;
string zwcnn = "/sdcard" + cnnmodelfile;
zwcnn = FormatFileName(zwcnn);
string zwcnn = FormatFileName("/sdcard" + cnnmodelfile);
printf(zwcnn.c_str());printf("\n");
tflite->LoadModel(zwcnn);
tflite->MakeAllocate();
@@ -215,17 +211,18 @@ bool ClassFlowDigit::doNeuralNetwork(string time)
for (int i = 0; i < ROI.size(); ++i)
{
printf("DigitalDigit %d - TfLite\n", i);
ioresize = "/sdcard/img_tmp/rd" + std::to_string(i) + ".bmp";
ioresize = FormatFileName(ioresize);
// printf("output: %s, ioresize: %s\n", output.c_str(), ioresize.c_str());
ROI[i]->resultklasse = 0;
#ifndef OHNETFLITE
ROI[i]->resultklasse = tflite->GetClassFromImage(ioresize);
ROI[i]->resultklasse = tflite->GetClassFromImageBasis(ROI[i]->image);
#endif
printf("Result Digit%i: %d\n", i, ROI[i]->resultklasse);
LogImage(logPath, ROI[i]->name, NULL, &ROI[i]->resultklasse, time);
if (isLogImage)
{
LogImage(logPath, ROI[i]->name, NULL, &ROI[i]->resultklasse, time, ROI[i]->image_org);
}
}
#ifndef OHNETFLITE
delete tflite;
@@ -233,6 +230,11 @@ bool ClassFlowDigit::doNeuralNetwork(string time)
return true;
}
void ClassFlowDigit::DrawROI(CImageBasis *_zw)
{
for (int i = 0; i < ROI.size(); ++i)
_zw->drawRect(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, 0, 0, 255, 2);
}
std::vector<HTMLInfo*> ClassFlowDigit::GetHTMLInfo()
{
@@ -241,10 +243,14 @@ std::vector<HTMLInfo*> ClassFlowDigit::GetHTMLInfo()
for (int i = 0; i < ROI.size(); ++i)
{
HTMLInfo *zw = new HTMLInfo;
zw->filename = ROI[i]->name + ".jpg";
zw->filename = ROI[i]->name + ".bmp";
zw->filename_org = ROI[i]->name + ".jpg";
zw->val = ROI[i]->resultklasse;
zw->image = ROI[i]->image;
zw->image_org = ROI[i]->image_org;
result.push_back(zw);
}
return result;
}
}

View File

@@ -1,5 +1,6 @@
#pragma once
#include "ClassFlowImage.h"
#include "ClassFlowAlignment.h"
#include "Helper.h"
#include <string>
@@ -8,6 +9,7 @@ struct roi {
int posx, posy, deltax, deltay;
int resultklasse;
string name;
CImageBasis *image, *image_org;
roi* next;
};
@@ -18,19 +20,27 @@ protected:
std::vector<roi*> ROI;
string cnnmodelfile;
int modelxsize, modelysize;
bool SaveAllFiles;
ClassFlowAlignment* flowpostalignment;
bool doNeuralNetwork(string time);
bool doAlignAndCut(string time);
void SetInitialParameter(void);
public:
ClassFlowDigit();
ClassFlowDigit(std::vector<ClassFlow*>* lfc);
ClassFlowDigit(std::vector<ClassFlow*>* lfc, ClassFlow *_prev);
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string getHTMLSingleStep(string host);
string getReadout();
std::vector<HTMLInfo*> GetHTMLInfo();
void DrawROI(CImageBasis *_zw);
string name(){return "ClassFlowDigit";};
};

View File

@@ -5,6 +5,7 @@
#include <dirent.h>
#include "time_sntp.h"
#include "ClassLogFile.h"
#include "CImageBasis.h"
ClassFlowImage::ClassFlowImage(const char* logTag)
{
@@ -12,12 +13,19 @@ ClassFlowImage::ClassFlowImage(const char* logTag)
isLogImage = false;
}
ClassFlowImage::ClassFlowImage(std::vector<ClassFlow*> * lfc, const char* logTag) : ClassFlow((std::vector<ClassFlow*>*)lfc)
ClassFlowImage::ClassFlowImage(std::vector<ClassFlow*> * lfc, const char* logTag) : ClassFlow(lfc)
{
this->logTag = logTag;
isLogImage = false;
}
ClassFlowImage::ClassFlowImage(std::vector<ClassFlow*> * lfc, ClassFlow *_prev, const char* logTag) : ClassFlow(lfc, _prev)
{
this->logTag = logTag;
isLogImage = false;
}
string ClassFlowImage::CreateLogFolder(string time) {
if (!isLogImage)
return "";
@@ -32,7 +40,7 @@ string ClassFlowImage::CreateLogFolder(string time) {
return logPath;
}
void ClassFlowImage::LogImage(string logPath, string name, float *resultFloat, int *resultInt, string time) {
void ClassFlowImage::LogImage(string logPath, string name, float *resultFloat, int *resultInt, string time, CImageBasis *_img) {
if (!isLogImage)
return;
@@ -50,7 +58,8 @@ void ClassFlowImage::LogImage(string logPath, string name, float *resultFloat, i
string output = "/sdcard/img_tmp/" + name + ".jpg";
output = FormatFileName(output);
printf("save to file: %s\n", nm.c_str());
CopyFile(output, nm);
_img->SaveToFile(nm);
// CopyFile(output, nm);
}
void ClassFlowImage::RemoveOldLogs()

View File

@@ -12,11 +12,13 @@ protected:
const char* logTag;
string CreateLogFolder(string time);
void LogImage(string logPath, string name, float *resultFloat, int *resultInt, string time);
void LogImage(string logPath, string name, float *resultFloat, int *resultInt, string time, CImageBasis *_img);
public:
ClassFlowImage(const char* logTag);
ClassFlowImage(std::vector<ClassFlow*> * lfc, const char* logTag);
ClassFlowImage(std::vector<ClassFlow*> * lfc, ClassFlow *_prev, const char* logTag);
void RemoveOldLogs();
};

View File

@@ -6,7 +6,7 @@
#include <time.h>
ClassFlowMQTT::ClassFlowMQTT()
void ClassFlowMQTT::SetInitialParameter(void)
{
uri = "";
topic = "";
@@ -15,20 +15,35 @@ ClassFlowMQTT::ClassFlowMQTT()
OldValue = "";
flowpostprocessing = NULL;
user = "";
password = "";
password = "";
previousElement = NULL;
ListFlowControll = NULL;
}
ClassFlowMQTT::ClassFlowMQTT()
{
SetInitialParameter();
}
ClassFlowMQTT::ClassFlowMQTT(std::vector<ClassFlow*>* lfc)
{
uri = "";
topic = "";
topicError = "";
clientname = "watermeter";
OldValue = "";
flowpostprocessing = NULL;
user = "";
password = "";
SetInitialParameter();
ListFlowControll = lfc;
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowPostProcessing") == 0)
{
flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i];
}
}
}
ClassFlowMQTT::ClassFlowMQTT(std::vector<ClassFlow*>* lfc, ClassFlow *_prev)
{
SetInitialParameter();
previousElement = _prev;
ListFlowControll = lfc;
for (int i = 0; i < ListFlowControll->size(); ++i)
@@ -38,9 +53,9 @@ ClassFlowMQTT::ClassFlowMQTT(std::vector<ClassFlow*>* lfc)
flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i];
}
}
}
bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
{
std::vector<string> zerlegt;
@@ -86,7 +101,7 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
if ((uri.length() > 0) && (topic.length() > 0))
{
MQTTInit(uri, clientname, user, password);
MQTTInit(uri, clientname, user, password, topicError, 60);
}
return true;

View File

@@ -13,11 +13,13 @@ protected:
std::string OldValue;
ClassFlowPostProcessing* flowpostprocessing;
std::string user, password;
void SetInitialParameter(void);
public:
ClassFlowMQTT();
ClassFlowMQTT(std::vector<ClassFlow*>* lfc);
ClassFlowMQTT(std::vector<ClassFlow*>* lfc, ClassFlow *_prev);
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string name(){return "ClassFlowMQTT";};

View File

@@ -1,11 +1,14 @@
#include "ClassFlowMakeImage.h"
#include "Helper.h"
#include "ClassLogFile.h"
#include "CFindTemplate.h"
#include "CImageBasis.h"
#include "ClassControllCamera.h"
#include <time.h>
// #define DEBUG_DETAIL_ON
static const char* TAG = "flow_make_image";
esp_err_t ClassFlowMakeImage::camera_capture(){
@@ -16,30 +19,27 @@ esp_err_t ClassFlowMakeImage::camera_capture(){
void ClassFlowMakeImage::takePictureWithFlash(int flashdauer)
{
string nm = namerawimage;
if (isImageSize && (ImageQuality > 0))
Camera.SetQualitySize(ImageQuality, ImageSize);
printf("Start CaptureFile\n");
Camera.CaptureToFile(nm, flashdauer);
Camera.CaptureToBasisImage(rawImage, flashdauer);
if (SaveAllFiles) rawImage->SaveToFile(namerawimage);
}
ClassFlowMakeImage::ClassFlowMakeImage() : ClassFlowImage(TAG)
void ClassFlowMakeImage::SetInitialParameter(void)
{
waitbeforepicture = 5;
isImageSize = false;
ImageQuality = -1;
TimeImageTaken = 0;
ImageQuality = 5;
rawImage = NULL;
ImageSize = FRAMESIZE_VGA;
SaveAllFiles = false;
namerawimage = "/sdcard/img_tmp/raw.jpg";
}
}
ClassFlowMakeImage::ClassFlowMakeImage(std::vector<ClassFlow*>* lfc) : ClassFlowImage(lfc, TAG)
{
waitbeforepicture = 5;
isImageSize = false;
ImageQuality = -1;
TimeImageTaken = 0;
namerawimage = "/sdcard/img_tmp/raw.jpg";
SetInitialParameter();
}
bool ClassFlowMakeImage::ReadParameter(FILE* pfile, string& aktparamgraph)
@@ -64,14 +64,28 @@ bool ClassFlowMakeImage::ReadParameter(FILE* pfile, string& aktparamgraph)
isLogImage = true;
}
if ((zerlegt[0] == "ImageQuality") && (zerlegt.size() > 1))
this->ImageQuality = std::stod(zerlegt[1]);
ImageQuality = std::stod(zerlegt[1]);
if ((zerlegt[0] == "ImageSize") && (zerlegt.size() > 1))
{
ImageSize = Camera.TextToFramesize(zerlegt[1].c_str());
isImageSize = true;
}
if ((toUpper(zerlegt[0]) == "SAVEALLFILES") && (zerlegt.size() > 1))
{
if (toUpper(zerlegt[1]) == "TRUE")
SaveAllFiles = true;
}
}
Camera.SetQualitySize(ImageQuality, ImageSize);
image_width = Camera.image_width;
image_height = Camera.image_height;
rawImage = new CImageBasis();
rawImage->CreateEmptyImage(image_width, image_height, 3);
return true;
}
@@ -84,27 +98,56 @@ string ClassFlowMakeImage::getHTMLSingleStep(string host)
bool ClassFlowMakeImage::doFlow(string zwtime)
{
////////////////////////////////////////////////////////////////////
// TakeImage and Store into /image_tmp/raw.jpg TO BE DONE
////////////////////////////////////////////////////////////////////
string logPath = CreateLogFolder(zwtime);
int flashdauer = (int) waitbeforepicture * 1000;
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("ClassFlowMakeImage::doFlow - Before takePictureWithFlash");
#endif
takePictureWithFlash(flashdauer);
time(&TimeImageTaken);
localtime(&TimeImageTaken);
LogImage(logPath, "raw", NULL, NULL, zwtime);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("ClassFlowMakeImage::doFlow - After takePictureWithFlash");
#endif
LogImage(logPath, "raw", NULL, NULL, zwtime, rawImage);
RemoveOldLogs();
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("ClassFlowMakeImage::doFlow - After RemoveOldLogs");
#endif
return true;
}
esp_err_t ClassFlowMakeImage::SendRawJPG(httpd_req_t *req)
{
int flashdauer = (int) waitbeforepicture * 1000;
return Camera.CaptureToHTTP(req, flashdauer);
}
ImageData* ClassFlowMakeImage::SendRawImage()
{
CImageBasis *zw = new CImageBasis(rawImage);
ImageData *id;
int flashdauer = (int) waitbeforepicture * 1000;
Camera.CaptureToBasisImage(zw, flashdauer);
id = zw->writeToMemoryAsJPG();
delete zw;
return id;
}
time_t ClassFlowMakeImage::getTimeImageTaken()
{
return TimeImageTaken;
}
ClassFlowMakeImage::~ClassFlowMakeImage(void)
{
delete rawImage;
}

View File

@@ -20,19 +20,32 @@ protected:
int ImageQuality;
time_t TimeImageTaken;
string namerawimage;
int image_height, image_width;
bool SaveAllFiles;
void CopyFile(string input, string output);
esp_err_t camera_capture();
void takePictureWithFlash(int flashdauer);
void takePictureWithFlash(int flashdauer);
void SetInitialParameter(void);
public:
ClassFlowMakeImage();
CImageBasis *rawImage;
ClassFlowMakeImage(std::vector<ClassFlow*>* lfc);
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string getHTMLSingleStep(string host);
time_t getTimeImageTaken();
string name(){return "ClassFlowMakeImage";};
ImageData* SendRawImage();
esp_err_t SendRawJPG(httpd_req_t *req);
~ClassFlowMakeImage(void);
};

View File

@@ -108,6 +108,8 @@ void ClassFlowPostProcessing::SavePreValue(float value, string zwtime)
zwtime = std::string(buffer);
}
PreValue = value;
fputs(zwtime.c_str(), pFile);
fputs("\n", pFile);
fputs(to_string(value).c_str(), pFile);

View File

@@ -2,6 +2,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
idf_component_register(SRCS ${app_sources}
INCLUDE_DIRS "."
REQUIRES tfmicro)
REQUIRES tfmicro jomjol_logfile)

View File

@@ -1,5 +1,8 @@
//#pragma warning(disable : 4996)
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "Helper.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -7,11 +10,91 @@
#include <string.h>
#include <esp_log.h>
#include "ClassLogFile.h"
//#include "ClassLogFile.h"
//#define ISWINDOWS_TRUE
#define PATH_MAX_STRING_SIZE 256
using namespace std;
/////////////////////////////////////////////////////////////////////////////////////////////
string getESPHeapInfo(){
string espInfoResultStr = "";
char aMsgBuf[80];
multi_heap_info_t aMultiHead_info ;
heap_caps_get_info (&aMultiHead_info,MALLOC_CAP_8BIT);
size_t aFreeHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT);
size_t aMinFreeHeadSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT);
size_t aMinFreeHeapSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT);
size_t aHeapLargestFreeBlockSize = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT);
sprintf(aMsgBuf," Free Heap Size: %ld", (long) aFreeHeapSize);
size_t aFreeSPIHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_SPIRAM);
size_t aFreeInternalHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_INTERNAL);
size_t aMinFreeInternalHeapSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_INTERNAL);
sprintf(aMsgBuf," Heap: %ld", (long) aFreeHeapSize);
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf," Min Free: %ld", (long) aMinFreeHeapSize);
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf," larg. Block: %ld", (long) aHeapLargestFreeBlockSize);
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf," SPI Heap: %ld", (long) aFreeSPIHeapSize);
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf," Min Free Heap Size: %ld", (long) aMinFreeHeadSize);
sprintf(aMsgBuf," NOT_SPI Heap: %ld", (long) (aFreeHeapSize - aFreeSPIHeapSize));
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf," largest Block Size: %ld", (long) aHeapLargestFreeBlockSize);
sprintf(aMsgBuf," Internal Heap: %ld", (long) (aFreeInternalHeapSize));
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf," Internal Min Heap free: %ld", (long) (aMinFreeInternalHeapSize));
espInfoResultStr += string(aMsgBuf);
return espInfoResultStr;
}
size_t getESPHeapSize(){
size_t aFreeHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT);
return aFreeHeapSize;
}
size_t getInternalESPHeapSize() {
size_t aFreeInternalHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_INTERNAL);
return aFreeInternalHeapSize;
}
///////////////////////////////////////////////////////////////////////////////////////////////
void memCopyGen(uint8_t* _source, uint8_t* _target, int _size)
{
for (int i = 0; i < _size; ++i)
*(_target + i) = *(_source + i);
}
FILE* OpenFileAndWait(const char* nm, char* _mode, int _waitsec)
{
FILE *pfile = fopen(nm, _mode);
if (pfile == NULL)
{
TickType_t xDelay;
xDelay = _waitsec * 1000 / portTICK_PERIOD_MS;
std::string zw = "File is locked: " + std::string(nm) + " - wait for " + std::to_string(_waitsec);
printf(zw.c_str());
printf("\n");
LogFile.WriteToFile(zw);
vTaskDelay( xDelay );
pfile = fopen(nm, _mode);
}
return pfile;
}
std::string FormatFileName(std::string input)
{
#ifdef ISWINDOWS_TRUE
@@ -126,14 +209,14 @@ void CopyFile(string input, string output)
}
char cTemp;
FILE* fpSourceFile = fopen(input.c_str(), "rb");
FILE* fpSourceFile = OpenFileAndWait(input.c_str(), "rb");
if (!fpSourceFile) // Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch!
{
printf("File %s existiert nicht!\n", input.c_str());
return;
}
FILE* fpTargetFile = fopen(output.c_str(), "wb");
FILE* fpTargetFile = OpenFileAndWait(output.c_str(), "wb");
// Code Section

View File

@@ -10,6 +10,8 @@ void FindReplace(std::string& line, std::string& oldString, std::string& newStri
void CopyFile(string input, string output);
FILE* OpenFileAndWait(const char* nm, char* _mode, int _waitsec = 1);
size_t findDelimiterPos(string input, string delimiter);
//string trim(string istring);
string trim(string istring, string adddelimiter = "");
@@ -25,3 +27,12 @@ string toUpper(string in);
float temperatureRead();
time_t addDays(time_t startTime, int days);
void memCopyGen(uint8_t* _source, uint8_t* _target, int _size);
///////////////////////////
size_t getInternalESPHeapSize();
size_t getESPHeapSize();
string getESPHeapInfo();
/////////////////////////////

View File

@@ -0,0 +1,205 @@
#include "CAlignAndCutImage.h"
#include "CRotateImage.h"
#include "CFindTemplate.h"
#define _USE_MATH_DEFINES
#include <math.h>
#include <algorithm>
//#define GET_MEMORY malloc
#define GET_MEMORY(X) heap_caps_malloc(X, MALLOC_CAP_SPIRAM)
CAlignAndCutImage::CAlignAndCutImage(CImageBasis *_org, CImageBasis *_temp)
{
rgb_image = _org->rgb_image;
channels = _org->channels;
width = _org->width;
height = _org->height;
bpp = _org->bpp;
externalImage = true;
islocked = false;
ImageTMP = _temp;
}
void CAlignAndCutImage::GetRefSize(int *ref_dx, int *ref_dy)
{
ref_dx[0] = t0_dx;
ref_dy[0] = t0_dy;
ref_dx[1] = t1_dx;
ref_dy[1] = t1_dy;
}
void CAlignAndCutImage::Align(std::string _template0, int ref0_x, int ref0_y, std::string _template1, int ref1_x, int ref1_y, int deltax, int deltay, std::string imageROI)
{
int dx, dy;
int r0_x, r0_y, r1_x, r1_y;
// CFindTemplate* ft = new CFindTemplate(filename);
CFindTemplate* ft = new CFindTemplate(rgb_image, channels, width, height, bpp);
r0_x = ref0_x;
r0_y = ref0_y;
ft->FindTemplate(_template0, &r0_x, &r0_y, deltax, deltay);
t0_dx = ft->tpl_width;
t0_dy = ft->tpl_height;
r1_x = ref1_x;
r1_y = ref1_y;
ft->FindTemplate(_template1, &r1_x, &r1_y, deltax, deltay);
t1_dx = ft->tpl_width;
t1_dy = ft->tpl_height;
delete ft;
dx = ref0_x - r0_x;
dy = ref0_y - r0_y;
r0_x += dx;
r0_y += dy;
r1_x += dx;
r1_y += dy;
float w_org, w_ist, d_winkel;
w_org = atan2(ref1_y - ref0_y, ref1_x - ref0_x);
w_ist = atan2(r1_y - r0_y, r1_x - r0_x);
d_winkel = (w_org - w_ist) * 180 / M_PI;
if (imageROI.length() > 0)
{
CImageBasis* imgzw = new CImageBasis(this);
imgzw->drawRect(r0_x, r0_y, t0_dx, t0_dy, 255, 0, 0, 2);
imgzw->drawRect(r1_x, r1_y, t1_dx, t1_dy, 255, 0, 0, 2);
imgzw->SaveToFile(imageROI);
printf("Alignment: alignment ROI created: %s\n", imageROI.c_str());
delete imgzw;
}
std::string zw = "\tdx:\t" + std::to_string(dx) + "\tdy:\t" + std::to_string(dy) + "\td_winkel:\t" + std::to_string(d_winkel);
// LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", zw);
CRotateImage rt(this, ImageTMP);
rt.Translate(dx, dy);
rt.Rotate(d_winkel, ref0_x, ref0_y);
printf("Alignment: dx %d - dy %d - rot %f\n", dx, dy, d_winkel);
}
void CAlignAndCutImage::CutAndSave(std::string _template1, int x1, int y1, int dx, int dy)
{
int x2, y2;
x2 = x1 + dx;
y2 = y1 + dy;
x2 = std::min(x2, width - 1);
y2 = std::min(y2, height - 1);
dx = x2 - x1;
dy = y2 - y1;
int memsize = dx * dy * channels;
uint8_t* odata = (unsigned char*) GET_MEMORY(memsize);
stbi_uc* p_target;
stbi_uc* p_source;
RGBImageLock();
for (int x = x1; x < x2; ++x)
for (int y = y1; y < y2; ++y)
{
p_target = odata + (channels * ((y - y1) * dx + (x - x1)));
p_source = rgb_image + (channels * (y * width + x));
for (int _channels = 0; _channels < channels; ++_channels)
p_target[_channels] = p_source[_channels];
}
// stbi_write_jpg(_template1.c_str(), dx, dy, channels, odata, 0);
stbi_write_bmp(_template1.c_str(), dx, dy, channels, odata);
RGBImageRelease();
stbi_image_free(odata);
}
void CAlignAndCutImage::CutAndSave(int x1, int y1, int dx, int dy, CImageBasis *_target)
{
int x2, y2;
x2 = x1 + dx;
y2 = y1 + dy;
x2 = std::min(x2, width - 1);
y2 = std::min(y2, height - 1);
dx = x2 - x1;
dy = y2 - y1;
if ((_target->height != dy) || (_target->width != dx) || (_target->channels != channels))
{
printf("CAlignAndCutImage::CutAndSave - Bildgröße passt nicht !!!!!!!!!");
return;
}
uint8_t* odata = _target->RGBImageLock();
RGBImageLock();
stbi_uc* p_target;
stbi_uc* p_source;
for (int x = x1; x < x2; ++x)
for (int y = y1; y < y2; ++y)
{
p_target = odata + (channels * ((y - y1) * dx + (x - x1)));
p_source = rgb_image + (channels * (y * width + x));
for (int _channels = 0; _channels < channels; ++_channels)
p_target[_channels] = p_source[_channels];
}
RGBImageRelease();
_target->RGBImageRelease();
}
CImageBasis* CAlignAndCutImage::CutAndSave(int x1, int y1, int dx, int dy)
{
int x2, y2;
x2 = x1 + dx;
y2 = y1 + dy;
x2 = std::min(x2, width - 1);
y2 = std::min(y2, height - 1);
dx = x2 - x1;
dy = y2 - y1;
int memsize = dx * dy * channels;
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
stbi_uc* p_target;
stbi_uc* p_source;
RGBImageLock();
for (int x = x1; x < x2; ++x)
for (int y = y1; y < y2; ++y)
{
p_target = odata + (channels * ((y - y1) * dx + (x - x1)));
p_source = rgb_image + (channels * (y * width + x));
for (int _channels = 0; _channels < channels; ++_channels)
p_target[_channels] = p_source[_channels];
}
CImageBasis* rs = new CImageBasis(odata, channels, dx, dy, bpp);
RGBImageRelease();
rs->SetIndepended();
return rs;
}

View File

@@ -0,0 +1,18 @@
#include "CImageBasis.h"
class CAlignAndCutImage : public CImageBasis
{
public:
int t0_dx, t0_dy, t1_dx, t1_dy;
CImageBasis *ImageTMP;
CAlignAndCutImage(std::string _image) : CImageBasis(_image) {ImageTMP = NULL;};
CAlignAndCutImage(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL;};
CAlignAndCutImage(CImageBasis *_org, CImageBasis *_temp);
void Align(std::string _template1, int x1, int y1, std::string _template2, int x2, int y2, int deltax = 40, int deltay = 40, std::string imageROI = "");
void CutAndSave(std::string _template1, int x1, int y1, int dx, int dy);
CImageBasis* CutAndSave(int x1, int y1, int dx, int dy);
void CutAndSave(int x1, int y1, int dx, int dy, CImageBasis *_target);
void GetRefSize(int *ref_dx, int *ref_dy);
};

View File

@@ -1,197 +1,26 @@
#include "CFindTemplate.h"
#include "Helper.h"
#include "ClassLogFile.h"
#include "esp_system.h"
#define _USE_MATH_DEFINES
#include <math.h>
#include <algorithm>
#define _ESP32_PSRAM
using namespace std;
#define GET_MEMORY malloc
/*
CResizeImage::CResizeImage(std::string _image, int _new_dx, int _new_dy)
{
CImageBasis::CImageBasis(_image);
}
*/
uint8_t CImageBasis::GetPixelColor(int x, int y, int ch)
{
stbi_uc* p_source;
p_source = this->rgb_image + (this->channels * (y * this->width + x));
return p_source[ch];
}
void CResizeImage::Resize(int _new_dx, int _new_dy)
{
int memsize = _new_dx * _new_dy * this->channels;
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
stbir_resize_uint8(this->rgb_image, this->width, this->height, 0, odata, _new_dx, _new_dy, 0, this->channels);
stbi_image_free(this->rgb_image);
this->rgb_image = (unsigned char*)GET_MEMORY(memsize);
this->memCopy(odata, this->rgb_image, memsize);
this->width = _new_dx;
this->height = _new_dy;
stbi_image_free(odata);
}
void CRotate::Mirror(){
int memsize = this->width * this->height * this->channels;
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
int x_source, y_source;
stbi_uc* p_target;
stbi_uc* p_source;
for (int x = 0; x < this->width; ++x)
for (int y = 0; y < this->height; ++y)
{
p_target = odata + (this->channels * (y * this->width + x));
x_source = this->width - x;
y_source = y;
p_source = this->rgb_image + (this->channels * (y_source * this->width + x_source));
for (int channels = 0; channels < this->channels; ++channels)
p_target[channels] = p_source[channels];
}
// memcpy(this->rgb_image, odata, memsize);
this->memCopy(odata, this->rgb_image, memsize);
stbi_image_free(odata);
}
void CRotate::Rotate(float _angle, int _centerx, int _centery)
{
float m[2][3];
float x_center = _centerx;
float y_center = _centery;
_angle = _angle / 180 * M_PI;
m[0][0] = cos(_angle);
m[0][1] = sin(_angle);
m[0][2] = (1 - m[0][0]) * x_center - m[0][1] * y_center;
m[1][0] = -m[0][1];
m[1][1] = m[0][0];
m[1][2] = m[0][1] * x_center + (1 - m[0][0]) * y_center;
int memsize = this->width * this->height * this->channels;
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
int x_source, y_source;
stbi_uc* p_target;
stbi_uc* p_source;
for (int x = 0; x < this->width; ++x)
for (int y = 0; y < this->height; ++y)
{
p_target = odata + (this->channels * (y * this->width + x));
x_source = int(m[0][0] * x + m[0][1] * y);
y_source = int(m[1][0] * x + m[1][1] * y);
x_source += int(m[0][2]);
y_source += int(m[1][2]);
if ((x_source >= 0) && (x_source < this->width) && (y_source >= 0) && (y_source < this->height))
{
p_source = this->rgb_image + (this->channels * (y_source * this->width + x_source));
for (int channels = 0; channels < this->channels; ++channels)
p_target[channels] = p_source[channels];
}
else
{
for (int channels = 0; channels < this->channels; ++channels)
p_target[channels] = 255;
}
}
// memcpy(this->rgb_image, odata, memsize);
this->memCopy(odata, this->rgb_image, memsize);
stbi_image_free(odata);
}
void CRotate::Rotate(float _angle)
{
this->Rotate(_angle, this->width / 2, this->height / 2);
}
void CRotate::Translate(int _dx, int _dy)
{
int memsize = this->width * this->height * this->channels;
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
int x_source, y_source;
stbi_uc* p_target;
stbi_uc* p_source;
for (int x = 0; x < this->width; ++x)
for (int y = 0; y < this->height; ++y)
{
p_target = odata + (this->channels * (y * this->width + x));
x_source = x - _dx;
y_source = y - _dy;
if ((x_source >= 0) && (x_source < this->width) && (y_source >= 0) && (y_source < this->height))
{
p_source = this->rgb_image + (this->channels * (y_source * this->width + x_source));
for (int channels = 0; channels < this->channels; ++channels)
p_target[channels] = p_source[channels];
}
else
{
for (int channels = 0; channels < this->channels; ++channels)
p_target[channels] = 255;
}
}
// memcpy(this->rgb_image, odata, memsize);
this->memCopy(odata, this->rgb_image, memsize);
stbi_image_free(odata);
}
CFindTemplate::CFindTemplate(std::string _image)
{
this->channels = 1;
this->rgb_image = stbi_load(_image.c_str(), &(this->width), &(this->height), &(this->bpp), this->channels);
}
void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found_y)
{
this->FindTemplate(_template, found_x, found_y, 0, 0);
FindTemplate(_template, found_x, found_y, 0, 0);
}
void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found_y, int _dx, int _dy)
{
uint8_t* rgb_template = stbi_load(_template.c_str(), &tpl_width, &tpl_height, &tpl_bpp, this->channels);
uint8_t* rgb_template = stbi_load(_template.c_str(), &tpl_width, &tpl_height, &tpl_bpp, channels);
int ow, ow_start, ow_stop;
int oh, oh_start, oh_stop;
if (_dx == 0)
{
_dx = this->width;
_dx = width;
*found_x = 0;
}
if (_dy == 0)
{
_dy = this->height;
_dy = height;
*found_y = 0;
}
@@ -199,22 +28,24 @@ void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found
ow_start = *found_x - _dx;
ow_start = std::max(ow_start, 0);
ow_stop = *found_x + _dx;
if ((ow_stop + tpl_width) > this->width)
ow_stop = this->width - tpl_width;
if ((ow_stop + tpl_width) > width)
ow_stop = width - tpl_width;
ow = ow_stop - ow_start + 1;
oh_start = *found_y - _dy;
oh_start = std::max(oh_start, 0);
oh_stop = *found_y + _dy;
if ((oh_stop + tpl_height) > this->height)
oh_stop = this->height - tpl_height;
if ((oh_stop + tpl_height) > height)
oh_stop = height - tpl_height;
oh = oh_stop - oh_start + 1;
uint8_t* odata = (unsigned char*)GET_MEMORY(ow * oh * this->channels);
uint8_t* odata = (unsigned char*)GET_MEMORY(ow * oh * channels);
double aktSAD;
double minSAD = pow(tpl_width * tpl_height * 255, 2);
RGBImageLock();
for (int xouter = ow_start; xouter <= ow_stop; xouter++)
for (int youter = oh_start; youter <= oh_stop; ++youter)
{
@@ -222,11 +53,11 @@ void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found
for (int tpl_x = 0; tpl_x < tpl_width; tpl_x++)
for (int tpl_y = 0; tpl_y < tpl_height; tpl_y++)
{
stbi_uc* p_org = this->rgb_image + (this->channels * ((youter + tpl_y) * this->width + (xouter + tpl_x)));
stbi_uc* p_tpl = rgb_template + (this->channels * (tpl_y * tpl_width + tpl_x));
stbi_uc* p_org = rgb_image + (channels * ((youter + tpl_y) * width + (xouter + tpl_x)));
stbi_uc* p_tpl = rgb_template + (channels * (tpl_y * tpl_width + tpl_x));
aktSAD += pow(p_tpl[0] - p_org[0], 2);
}
stbi_uc* p_out = odata + (this->channels * ((youter - oh_start) * ow + (xouter - ow_start)));
stbi_uc* p_out = odata + (channels * ((youter - oh_start) * ow + (xouter - ow_start)));
p_out[0] = int(sqrt(aktSAD / (tpl_width * tpl_height)));
if (aktSAD < minSAD)
@@ -237,7 +68,9 @@ void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found
}
}
stbi_write_bmp("sdcard\\find.bmp", ow, oh, this->channels, odata);
RGBImageRelease();
stbi_write_bmp("sdcard\\find.bmp", ow, oh, channels, odata);
stbi_image_free(odata);
stbi_image_free(rgb_template);
@@ -245,303 +78,14 @@ void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found
void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found_y, std::string _imageout)
{
this->FindTemplate(_template, found_x, found_y);
this->SaveToFile(_imageout);
FindTemplate(_template, found_x, found_y);
SaveToFile(_imageout);
}
void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found_y, int _dx, int _dy, std::string _imageout)
{
this->FindTemplate(_template, found_x, found_y, _dx, _dy);
this->SaveToFile(_imageout);
FindTemplate(_template, found_x, found_y, _dx, _dy);
SaveToFile(_imageout);
}
void CImageBasis::memCopy(uint8_t* _source, uint8_t* _target, int _size)
{
#ifdef _ESP32_PSRAM
for (int i = 0; i < _size; ++i)
*(_target + i) = *(_source + i);
#else
memcpy(_target, _source, _size);
#endif
}
bool CImageBasis::isInImage(int x, int y)
{
if ((x < 0) || (x > this->width - 1))
return false;
if ((y < 0) || (y > this->height- 1))
return false;
return true;
}
void CImageBasis::setPixelColor(int x, int y, int r, int g, int b)
{
stbi_uc* p_source;
p_source = this->rgb_image + (this->channels * (y * this->width + x));
p_source[0] = r;
if (this-> channels > 2)
{
p_source[1] = g;
p_source[2] = b;
}
}
void CImageBasis::drawRect(int x, int y, int dx, int dy, int r, int g, int b, int thickness)
{
int zwx1, zwx2, zwy1, zwy2;
int _x, _y, _thick;
zwx1 = x - thickness + 1;
zwx2 = x + dx + thickness - 1;
zwy1 = y;
zwy2 = y;
for (_thick = 0; _thick < thickness; _thick++)
for (_x = zwx1; _x <= zwx2; ++_x)
for (_y = zwy1; _y <= zwy2; _y++)
if (isInImage(_x, _y))
setPixelColor(_x, _y - _thick, r, g, b);
zwx1 = x - thickness + 1;
zwx2 = x + dx + thickness - 1;
zwy1 = y + dy;
zwy2 = y + dy;
for (_thick = 0; _thick < thickness; _thick++)
for (_x = zwx1; _x <= zwx2; ++_x)
for (_y = zwy1; _y <= zwy2; _y++)
if (isInImage(_x, _y))
setPixelColor(_x, _y + _thick, r, g, b);
zwx1 = x;
zwx2 = x;
zwy1 = y;
zwy2 = y + dy;
for (_thick = 0; _thick < thickness; _thick++)
for (_x = zwx1; _x <= zwx2; ++_x)
for (_y = zwy1; _y <= zwy2; _y++)
if (isInImage(_x, _y))
setPixelColor(_x - _thick, _y, r, g, b);
zwx1 = x + dx;
zwx2 = x + dx;
zwy1 = y;
zwy2 = y + dy;
for (_thick = 0; _thick < thickness; _thick++)
for (_x = zwx1; _x <= zwx2; ++_x)
for (_y = zwy1; _y <= zwy2; _y++)
if (isInImage(_x, _y))
setPixelColor(_x + _thick, _y, r, g, b);
}
void CImageBasis::drawLine(int x1, int y1, int x2, int y2, int r, int g, int b, int thickness)
{
int _x, _y, _thick;
int _zwy1, _zwy2;
thickness = (thickness-1) / 2;
for (_thick = 0; _thick <= thickness; ++_thick)
for (_x = x1 - _thick; _x <= x2 + _thick; ++_x)
{
if (x2 == x1)
{
_zwy1 = y1;
_zwy2 = y2;
}
else
{
_zwy1 = (y2 - y1) * (float)(_x - x1) / (float)(x2 - x1) + y1;
_zwy2 = (y2 - y1) * (float)(_x + 1 - x1) / (float)(x2 - x1) + y1;
}
for (_y = _zwy1 - _thick; _y <= _zwy2 + _thick; _y++)
if (isInImage(_x, _y))
setPixelColor(_x, _y, r, g, b);
}
}
void CImageBasis::drawCircle(int x1, int y1, int rad, int r, int g, int b, int thickness)
{
float deltarad, aktrad;
int _thick, _x, _y;
deltarad = 1 / (4 * M_PI * (rad + thickness - 1));
for (aktrad = 0; aktrad <= (2 * M_PI); aktrad += deltarad)
for (_thick = 0; _thick < thickness; ++_thick)
{
_x = sin(aktrad) * (rad + _thick) + x1;
_y = cos(aktrad) * (rad + _thick) + y1;
if (isInImage(_x, _y))
setPixelColor(_x, _y, r, g, b);
}
}
CImageBasis::CImageBasis()
{
this->externalImage = false;
}
CImageBasis::CImageBasis(std::string _image)
{
channels = 3;
externalImage = false;
filename = _image;
// long freebefore = esp_get_free_heap_size();
rgb_image = stbi_load(_image.c_str(), &width, &height, &bpp, channels);
// if (rgb_image == NULL)
// LogFile.WriteToFile("Image Load failed:" + _image + " FreeHeapSize before: " + to_string(freebefore) + " after: " + to_string(esp_get_free_heap_size()));
// printf("CImageBasis after load\n");
// printf("w %d, h %d, b %d, c %d", this->width, this->height, this->bpp, this->channels);
}
bool CImageBasis::ImageOkay(){
return rgb_image != NULL;
}
CImageBasis::CImageBasis(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp)
{
this->rgb_image = _rgb_image;
this->channels = _channels;
this->width = _width;
this->height = _height;
this->bpp = _bpp;
this->externalImage = true;
}
void CImageBasis::Contrast(float _contrast) //input range [-100..100]
{
stbi_uc* p_source;
float contrast = (_contrast/100) + 1; //convert to decimal & shift range: [0..2]
float intercept = 128 * (1 - contrast);
for (int x = 0; x < width; ++x)
for (int y = 0; y < height; ++y)
{
p_source = this->rgb_image + (this->channels * (y * this->width + x));
for (int channels = 0; channels < this->channels; ++channels)
p_source[channels] = (uint8_t) std::min(255, std::max(0, (int) (p_source[channels] * contrast + intercept)));
}
}
CImageBasis::~CImageBasis()
{
if (!this->externalImage)
stbi_image_free(this->rgb_image);
}
void CImageBasis::SaveToFile(std::string _imageout)
{
string typ = getFileType(_imageout);
if ((typ == "jpg") || (typ == "JPG")) // ACHTUNG PROBLEMATISCH IM ESP32
{
stbi_write_jpg(_imageout.c_str(), this->width, this->height, this->channels, this->rgb_image, 0);
}
if ((typ == "bmp") || (typ == "BMP"))
{
stbi_write_bmp(_imageout.c_str(), this->width, this->height, this->channels, this->rgb_image);
}
// stbi_write_jpg(_imageout.c_str(), this->width, this->height, this->channels, this->rgb_image, 0);
// stbi_write_bmp(_imageout.c_str(), this->width, this->height, this->channels, this->rgb_image);
}
void CAlignAndCutImage::Align(std::string _template0, int ref0_x, int ref0_y, std::string _template1, int ref1_x, int ref1_y, int deltax, int deltay, std::string imageROI)
{
int dx, dy;
int r0_x, r0_y, r1_x, r1_y;
CFindTemplate* ft = new CFindTemplate(this->filename);
r0_x = ref0_x;
r0_y = ref0_y;
ft->FindTemplate(_template0, &r0_x, &r0_y, deltax, deltay);
t0_dx = ft->tpl_width;
t0_dy = ft->tpl_height;
r1_x = ref1_x;
r1_y = ref1_y;
ft->FindTemplate(_template1, &r1_x, &r1_y, deltax, deltay);
t1_dx = ft->tpl_width;
t1_dy = ft->tpl_height;
delete ft;
dx = ref0_x - r0_x;
dy = ref0_y - r0_y;
r0_x += dx;
r0_y += dy;
r1_x += dx;
r1_y += dy;
float w_org, w_ist, d_winkel;
w_org = atan2(ref1_y - ref0_y, ref1_x - ref0_x);
w_ist = atan2(r1_y - r0_y, r1_x - r0_x);
d_winkel = (w_org - w_ist) * 180 / M_PI;
if (imageROI.length() > 0)
{
CImageBasis* imgzw = new CImageBasis(this->filename);
imgzw->drawRect(r0_x, r0_y, t0_dx, t0_dy, 255, 0, 0, 2);
imgzw->drawRect(r1_x, r1_y, t1_dx, t1_dy, 255, 0, 0, 2);
imgzw->SaveToFile(imageROI);
printf("Alignment: alignment ROI created: %s\n", imageROI.c_str());
delete imgzw;
}
string zw = "\tdx:\t" + to_string(dx) + "\tdy:\t" + to_string(dy) + "\td_winkel:\t" + to_string(d_winkel);
LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", zw);
CRotate rt(this->rgb_image, this->channels, this->width, this->height, this->bpp);
rt.Translate(dx, dy);
rt.Rotate(d_winkel, ref0_x, ref0_y);
printf("Alignment: dx %d - dy %d - rot %f\n", dx, dy, d_winkel);
}
void CAlignAndCutImage::CutAndSave(std::string _template1, int x1, int y1, int dx, int dy)
{
int x2, y2;
x2 = x1 + dx;
y2 = y1 + dy;
x2 = min(x2, this->width - 1);
y2 = min(y2, this->height - 1);
dx = x2 - x1;
dy = y2 - y1;
int memsize = dx * dy * this->channels;
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
stbi_uc* p_target;
stbi_uc* p_source;
for (int x = x1; x < x2; ++x)
for (int y = y1; y < y2; ++y)
{
p_target = odata + (this->channels * ((y - y1) * dx + (x - x1)));
p_source = this->rgb_image + (this->channels * (y * this->width + x));
for (int channels = 0; channels < this->channels; ++channels)
p_target[channels] = p_source[channels];
}
// stbi_write_jpg(_template1.c_str(), dx, dy, this->channels, odata, 0);
stbi_write_bmp(_template1.c_str(), dx, dy, this->channels, odata);
stbi_image_free(odata);
}

View File

@@ -1,98 +1,16 @@
#pragma once
#include "CImageBasis.h"
#ifndef __CFINDTEMPLATE
#define __CFINGTEMPLATE
#include <stdint.h>
#include <string>
#define _USE_MATH_DEFINES
#include <math.h>
#include "stb_image.h"
#include "stb_image_write.h"
#include "stb_image_resize.h"
class CImageBasis
{
protected:
uint8_t* rgb_image;
int channels;
int width, height, bpp;
bool externalImage;
std::string filename;
void memCopy(uint8_t* _source, uint8_t* _target, int _size);
bool isInImage(int x, int y);
public:
int getWidth(){return this->width;};
int getHeight(){return this->height;};
int getChannels(){return this->channels;};
void drawRect(int x, int y, int dx, int dy, int r = 255, int g = 255, int b = 255, int thickness = 1);
void drawLine(int x1, int y1, int x2, int y2, int r, int g, int b, int thickness = 1);
void drawCircle(int x1, int y1, int rad, int r, int g, int b, int thickness = 1);
void setPixelColor(int x, int y, int r, int g, int b);
void Contrast(float _contrast);
bool ImageOkay();
CImageBasis();
CImageBasis(std::string _image);
CImageBasis(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp);
uint8_t GetPixelColor(int x, int y, int ch);
~CImageBasis();
void SaveToFile(std::string _imageout);
};
class CFindTemplate : public CImageBasis
{
public:
int tpl_width, tpl_height, tpl_bpp;
CFindTemplate(std::string _image);
// CFindTemplate(std::string _image);
CFindTemplate(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {};
void FindTemplate(std::string _template, int* found_x, int* found_y, std::string _imageout);
void FindTemplate(std::string _template, int* found_x, int* found_y, int _dx, int _dy, std::string _imageout);
void FindTemplate(std::string _template, int* found_x, int* found_y);
void FindTemplate(std::string _template, int* found_x, int* found_y, int _dx, int _dy);
};
class CRotate: public CImageBasis
{
public:
CRotate(std::string _image) : CImageBasis(_image) {};
CRotate(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {};
void Rotate(float _angle);
void Rotate(float _angle, int _centerx, int _centery);
void Translate(int _dx, int _dy);
void Mirror();
};
class CAlignAndCutImage : public CImageBasis
{
public:
int t0_dx, t0_dy, t1_dx, t1_dy;
CAlignAndCutImage(std::string _image) : CImageBasis(_image) {};
void Align(std::string _template1, int x1, int y1, std::string _template2, int x2, int y2, int deltax = 40, int deltay = 40, std::string imageROI = "");
void CutAndSave(std::string _template1, int x1, int y1, int dx, int dy);
};
class CResizeImage : public CImageBasis
{
public:
CResizeImage(std::string _image) : CImageBasis(_image) {};
// CResizeImage(std::string _image, int _new_dx, int _new_dy);
void Resize(int _new_dx, int _new_dy);
};
#endif
};

View File

@@ -0,0 +1,523 @@
#include "CImageBasis.h"
#include "Helper.h"
#include "ClassLogFile.h"
#include <esp_log.h>
#include "esp_system.h"
#include <cstring>
#define _USE_MATH_DEFINES
#include <math.h>
#include <algorithm>
#define _ESP32_PSRAM
using namespace std;
static const char *TAG = "CImageBasis";
//#define DEBUG_DETAIL_ON
uint8_t * CImageBasis::RGBImageLock(int _waitmaxsec)
{
if (islocked)
{
#ifdef DEBUG_DETAIL_ON
printf("Image is locked: sleep for : %ds\n", _waitmaxsec);
#endif
TickType_t xDelay;
xDelay = 1000 / portTICK_PERIOD_MS;
for (int i = 0; i <= _waitmaxsec; ++i)
{
vTaskDelay( xDelay );
if (!islocked)
break;
}
}
if (islocked)
return NULL;
return rgb_image;
}
void CImageBasis::RGBImageRelease()
{
islocked = false;
}
uint8_t * CImageBasis::RGBImageGet()
{
return rgb_image;
}
void writejpghelp(void *context, void *data, int size)
{
// printf("Size all: %d, size %d\n", ((ImageData*)context)->size, size);
ImageData* _zw = (ImageData*) context;
uint8_t *voidstart = _zw->data;
uint8_t *datastart = (uint8_t*) data;
voidstart += _zw->size;
for (int i = 0; i < size; ++i)
*(voidstart + i) = *(datastart + i);
_zw->size += size;
}
ImageData* CImageBasis::writeToMemoryAsJPG(const int quality)
{
ImageData* ii = new ImageData;
RGBImageLock();
stbi_write_jpg_to_func(writejpghelp, ii, width, height, channels, rgb_image, quality);
RGBImageRelease();
return ii;
}
#define HTTP_BUFFER_SENT 1024
struct SendJPGHTTP
{
httpd_req_t *req;
esp_err_t res;
char buf[HTTP_BUFFER_SENT];
int size = 0;
};
inline void writejpgtohttphelp(void *context, void *data, int size)
{
SendJPGHTTP* _send = (SendJPGHTTP*) context;
if ((_send->size + size) >= HTTP_BUFFER_SENT) // data passt nich mehr in buffer
{
httpd_req_t *_req = _send->req;
if (httpd_resp_send_chunk(_req, _send->buf, _send->size) != ESP_OK)
{
ESP_LOGE(TAG, "File sending failed!");
_send->res = ESP_FAIL;
}
_send->size = 0;
}
std::memcpy((void*) (&(_send->buf[0]) + _send->size), data, size);
_send->size+= size;
}
esp_err_t CImageBasis::SendJPGtoHTTP(httpd_req_t *_req, const int quality)
{
SendJPGHTTP ii;
ii.req = _req;
ii.res = ESP_OK;
ii.size = 0;
RGBImageLock();
stbi_write_jpg_to_func(writejpgtohttphelp, &ii, width, height, channels, rgb_image, quality);
RGBImageRelease();
if (ii.size > 0)
{
if (httpd_resp_send_chunk(_req, (char*) ii.buf, ii.size) != ESP_OK) // verschicke noch den Rest
{
ESP_LOGE(TAG, "File sending failed!");
ii.res = ESP_FAIL;
}
}
return ii.res;
}
bool CImageBasis::CopyFromMemory(uint8_t* _source, int _size)
{
int gr = height * width * channels;
if (gr != _size) // Größe passt nicht
{
printf("Kann Bild nicht von Speicher kopierte - Größen passen nicht zusammen: soll %d, ist %d\n", _size, gr);
return false;
}
RGBImageLock();
memCopy(_source, rgb_image, _size);
RGBImageRelease();
return true;
}
uint8_t CImageBasis::GetPixelColor(int x, int y, int ch)
{
stbi_uc* p_source;
p_source = rgb_image + (channels * (y * width + x));
return p_source[ch];
}
void CImageBasis::memCopy(uint8_t* _source, uint8_t* _target, int _size)
{
#ifdef _ESP32_PSRAM
for (int i = 0; i < _size; ++i)
*(_target + i) = *(_source + i);
#else
memcpy(_target, _source, _size);
#endif
}
bool CImageBasis::isInImage(int x, int y)
{
if ((x < 0) || (x > width - 1))
return false;
if ((y < 0) || (y > height- 1))
return false;
return true;
}
void CImageBasis::setPixelColor(int x, int y, int r, int g, int b)
{
stbi_uc* p_source;
RGBImageLock();
p_source = rgb_image + (channels * (y * width + x));
p_source[0] = r;
if ( channels > 2)
{
p_source[1] = g;
p_source[2] = b;
}
RGBImageRelease();
}
void CImageBasis::drawRect(int x, int y, int dx, int dy, int r, int g, int b, int thickness)
{
int zwx1, zwx2, zwy1, zwy2;
int _x, _y, _thick;
zwx1 = x - thickness + 1;
zwx2 = x + dx + thickness - 1;
zwy1 = y;
zwy2 = y;
for (_thick = 0; _thick < thickness; _thick++)
for (_x = zwx1; _x <= zwx2; ++_x)
for (_y = zwy1; _y <= zwy2; _y++)
if (isInImage(_x, _y))
setPixelColor(_x, _y - _thick, r, g, b);
zwx1 = x - thickness + 1;
zwx2 = x + dx + thickness - 1;
zwy1 = y + dy;
zwy2 = y + dy;
for (_thick = 0; _thick < thickness; _thick++)
for (_x = zwx1; _x <= zwx2; ++_x)
for (_y = zwy1; _y <= zwy2; _y++)
if (isInImage(_x, _y))
setPixelColor(_x, _y + _thick, r, g, b);
zwx1 = x;
zwx2 = x;
zwy1 = y;
zwy2 = y + dy;
for (_thick = 0; _thick < thickness; _thick++)
for (_x = zwx1; _x <= zwx2; ++_x)
for (_y = zwy1; _y <= zwy2; _y++)
if (isInImage(_x, _y))
setPixelColor(_x - _thick, _y, r, g, b);
zwx1 = x + dx;
zwx2 = x + dx;
zwy1 = y;
zwy2 = y + dy;
for (_thick = 0; _thick < thickness; _thick++)
for (_x = zwx1; _x <= zwx2; ++_x)
for (_y = zwy1; _y <= zwy2; _y++)
if (isInImage(_x, _y))
setPixelColor(_x + _thick, _y, r, g, b);
}
void CImageBasis::drawLine(int x1, int y1, int x2, int y2, int r, int g, int b, int thickness)
{
int _x, _y, _thick;
int _zwy1, _zwy2;
thickness = (thickness-1) / 2;
for (_thick = 0; _thick <= thickness; ++_thick)
for (_x = x1 - _thick; _x <= x2 + _thick; ++_x)
{
if (x2 == x1)
{
_zwy1 = y1;
_zwy2 = y2;
}
else
{
_zwy1 = (y2 - y1) * (float)(_x - x1) / (float)(x2 - x1) + y1;
_zwy2 = (y2 - y1) * (float)(_x + 1 - x1) / (float)(x2 - x1) + y1;
}
for (_y = _zwy1 - _thick; _y <= _zwy2 + _thick; _y++)
if (isInImage(_x, _y))
setPixelColor(_x, _y, r, g, b);
}
}
void CImageBasis::drawCircle(int x1, int y1, int rad, int r, int g, int b, int thickness)
{
float deltarad, aktrad;
int _thick, _x, _y;
deltarad = 1 / (4 * M_PI * (rad + thickness - 1));
for (aktrad = 0; aktrad <= (2 * M_PI); aktrad += deltarad)
for (_thick = 0; _thick < thickness; ++_thick)
{
_x = sin(aktrad) * (rad + _thick) + x1;
_y = cos(aktrad) * (rad + _thick) + y1;
if (isInImage(_x, _y))
setPixelColor(_x, _y, r, g, b);
}
}
CImageBasis::CImageBasis()
{
externalImage = false;
rgb_image = NULL;
width = 0;
height = 0;
channels = 0;
islocked = false;
}
void CImageBasis::CreateEmptyImage(int _width, int _height, int _channels)
{
bpp = _channels;
width = _width;
height = _height;
channels = _channels;
RGBImageLock();
int memsize = width * height * channels;
rgb_image = (unsigned char*)GET_MEMORY(memsize);
stbi_uc* p_source;
for (int x = 0; x < width; ++x)
for (int y = 0; y < height; ++y)
{
p_source = rgb_image + (channels * (y * width + x));
for (int _channels = 0; _channels < channels; ++_channels)
p_source[_channels] = (uint8_t) 0;
}
RGBImageRelease();
}
void CImageBasis::LoadFromMemory(stbi_uc *_buffer, int len)
{
RGBImageLock();
if (rgb_image)
stbi_image_free(rgb_image);
rgb_image = stbi_load_from_memory(_buffer, len, &width, &height, &channels, 3);
bpp = channels;
printf("Image loaded from memory: %d, %d, %d\n", width, height, channels);
RGBImageRelease();
}
CImageBasis::CImageBasis(CImageBasis *_copyfrom, int _anzrepeat)
{
islocked = false;
externalImage = false;
channels = _copyfrom->channels;
width = _copyfrom->width;
height = _copyfrom->height;
bpp = _copyfrom->bpp;
RGBImageLock();
int memsize = width * height * channels;
rgb_image = (unsigned char*)GET_MEMORY(memsize);
TickType_t xDelay;
int anz = 1;
while (!rgb_image && (anz < _anzrepeat))
{
printf("Create Image from Copy - Speicher ist voll - Versuche es erneut: %d.\n", anz);
xDelay = 1000 / portTICK_PERIOD_MS;
rgb_image = (unsigned char*) malloc(memsize);
anz++;
}
if (!rgb_image)
{
printf(getESPHeapInfo().c_str());
printf("\nKein freier Speicher mehr!!!! Benötigt: %d %d %d %d\n", width, height, channels, memsize);
RGBImageRelease();
return;
}
memCopy(_copyfrom->rgb_image, rgb_image, memsize);
RGBImageRelease();
}
CImageBasis::CImageBasis(int _width, int _height, int _channels)
{
islocked = false;
externalImage = false;
channels = _channels;
width = _width;
height = _height;
bpp = _channels;
int memsize = width * height * channels;
rgb_image = (unsigned char*)GET_MEMORY(memsize);
if (!rgb_image)
{
printf(getESPHeapInfo().c_str());
printf("\nKein freier Speicher mehr!!!! Benötigt: %d %d %d %d\n", width, height, channels, memsize);
return;
}
}
CImageBasis::CImageBasis(std::string _image)
{
islocked = false;
channels = 3;
externalImage = false;
filename = _image;
long zwld = esp_get_free_heap_size();
printf("freeheapsize before: %ld\n", zwld);
RGBImageLock();
rgb_image = stbi_load(_image.c_str(), &width, &height, &bpp, channels);
RGBImageRelease();
zwld = esp_get_free_heap_size();
printf("freeheapsize after : %ld\n", zwld);
std::string zw = "Image Load failed:" + _image + "\n";
if (rgb_image == NULL)
printf(zw.c_str());
zw = "CImageBasis after load " + _image + "\n";
printf(zw.c_str());
printf("w %d, h %d, b %d, c %d\n", width, height, bpp, channels);
}
bool CImageBasis::ImageOkay(){
return rgb_image != NULL;
}
CImageBasis::CImageBasis(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp)
{
islocked = false;
rgb_image = _rgb_image;
channels = _channels;
width = _width;
height = _height;
bpp = _bpp;
externalImage = true;
}
void CImageBasis::Contrast(float _contrast) //input range [-100..100]
{
stbi_uc* p_source;
float contrast = (_contrast/100) + 1; //convert to decimal & shift range: [0..2]
float intercept = 128 * (1 - contrast);
RGBImageLock();
for (int x = 0; x < width; ++x)
for (int y = 0; y < height; ++y)
{
p_source = rgb_image + (channels * (y * width + x));
for (int _channels = 0; _channels < channels; ++_channels)
p_source[_channels] = (uint8_t) std::min(255, std::max(0, (int) (p_source[_channels] * contrast + intercept)));
}
RGBImageRelease();
}
CImageBasis::~CImageBasis()
{
RGBImageLock();
if (!externalImage)
stbi_image_free(rgb_image);
}
void CImageBasis::SaveToFile(std::string _imageout)
{
string typ = getFileType(_imageout);
RGBImageLock();
if ((typ == "jpg") || (typ == "JPG")) // ACHTUNG PROBLEMATISCH IM ESP32
{
stbi_write_jpg(_imageout.c_str(), width, height, channels, rgb_image, 0);
}
if ((typ == "bmp") || (typ == "BMP"))
{
stbi_write_bmp(_imageout.c_str(), width, height, channels, rgb_image);
}
RGBImageRelease();
}
void CImageBasis::Resize(int _new_dx, int _new_dy)
{
int memsize = _new_dx * _new_dy * channels;
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
RGBImageLock();
stbir_resize_uint8(rgb_image, width, height, 0, odata, _new_dx, _new_dy, 0, channels);
stbi_image_free(rgb_image);
rgb_image = (unsigned char*)GET_MEMORY(memsize);
memCopy(odata, rgb_image, memsize);
RGBImageRelease();
width = _new_dx;
height = _new_dy;
stbi_image_free(odata);
}
void CImageBasis::Resize(int _new_dx, int _new_dy, CImageBasis *_target)
{
if ((_target->height != _new_dy) || (_target->width != _new_dx) || (_target->channels != channels))
{
printf("CImageBasis::Resize - Targetbildgröße passt nicht !!!!!!!!!");
return;
}
RGBImageLock();
uint8_t* odata = _target->rgb_image;
stbir_resize_uint8(rgb_image, width, height, 0, odata, _new_dx, _new_dy, 0, channels);
RGBImageRelease();
}

View File

@@ -0,0 +1,94 @@
#pragma once
#ifndef __CIMAGEBASIS
#define __CIMAGEBASIS
#include <stdint.h>
#include <string>
#include <esp_http_server.h>
#define _USE_MATH_DEFINES
#include <math.h>
#include "stb_image.h"
#include "stb_image_write.h"
#include "stb_image_resize.h"
#include "esp_heap_caps.h"
//#define GET_MEMORY malloc
#define GET_MEMORY(X) heap_caps_malloc(X, MALLOC_CAP_SPIRAM)
#define MAX_JPG_SIZE 128000
struct ImageData
{
uint8_t data[MAX_JPG_SIZE];
size_t size = 0;
};
class CImageBasis
{
protected:
bool externalImage;
std::string filename;
void memCopy(uint8_t* _source, uint8_t* _target, int _size);
bool isInImage(int x, int y);
bool islocked;
public:
uint8_t* rgb_image;
int channels;
int width, height, bpp;
uint8_t * RGBImageLock(int _waitmaxsec = 60);
void RGBImageRelease();
uint8_t * RGBImageGet();
int getWidth(){return this->width;};
int getHeight(){return this->height;};
int getChannels(){return this->channels;};
void drawRect(int x, int y, int dx, int dy, int r = 255, int g = 255, int b = 255, int thickness = 1);
void drawLine(int x1, int y1, int x2, int y2, int r, int g, int b, int thickness = 1);
void drawCircle(int x1, int y1, int rad, int r, int g, int b, int thickness = 1);
void setPixelColor(int x, int y, int r, int g, int b);
void Contrast(float _contrast);
bool ImageOkay();
bool CopyFromMemory(uint8_t* _source, int _size);
void SetIndepended(){externalImage = false;};
void CreateEmptyImage(int _width, int _height, int _channels);
CImageBasis();
CImageBasis(std::string _image);
CImageBasis(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp);
CImageBasis(int _width, int _height, int _channels);
CImageBasis(CImageBasis *_copyfrom, int _anzrepeat = 0);
void Resize(int _new_dx, int _new_dy);
void Resize(int _new_dx, int _new_dy, CImageBasis *_target);
void LoadFromMemory(stbi_uc *_buffer, int len);
ImageData* writeToMemoryAsJPG(const int quality = 90);
esp_err_t SendJPGtoHTTP(httpd_req_t *req, const int quality = 90);
uint8_t GetPixelColor(int x, int y, int ch);
~CImageBasis();
void SaveToFile(std::string _imageout);
};
#endif

View File

@@ -2,6 +2,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
idf_component_register(SRCS ${app_sources}
INCLUDE_DIRS "."
REQUIRES jomjol_helper jomjol_logfile)
REQUIRES jomjol_helper jomjol_logfile esp_http_server)

View File

@@ -0,0 +1,192 @@
#include "CRotateImage.h"
CRotateImage::CRotateImage(CImageBasis *_org, CImageBasis *_temp)
{
rgb_image = _org->rgb_image;
channels = _org->channels;
width = _org->width;
height = _org->height;
bpp = _org->bpp;
externalImage = true;
ImageTMP = _temp;
islocked = false;
}
void CRotateImage::Mirror(){
int memsize = width * height * channels;
uint8_t* odata;
if (ImageTMP)
{
odata = ImageTMP->RGBImageLock();
}
else
{
odata = (unsigned char*)GET_MEMORY(memsize);
}
int x_source, y_source;
stbi_uc* p_target;
stbi_uc* p_source;
RGBImageLock();
for (int x = 0; x < width; ++x)
for (int y = 0; y < height; ++y)
{
p_target = odata + (channels * (y * width + x));
x_source = width - x;
y_source = y;
p_source = rgb_image + (channels * (y_source * width + x_source));
for (int _channels = 0; _channels < channels; ++_channels)
p_target[_channels] = p_source[_channels];
}
// memcpy(rgb_image, odata, memsize);
memCopy(odata, rgb_image, memsize);
if (!ImageTMP)
stbi_image_free(odata);
if (ImageTMP)
ImageTMP->RGBImageRelease();
RGBImageRelease();
}
void CRotateImage::Rotate(float _angle, int _centerx, int _centery)
{
float m[2][3];
float x_center = _centerx;
float y_center = _centery;
_angle = _angle / 180 * M_PI;
m[0][0] = cos(_angle);
m[0][1] = sin(_angle);
m[0][2] = (1 - m[0][0]) * x_center - m[0][1] * y_center;
m[1][0] = -m[0][1];
m[1][1] = m[0][0];
m[1][2] = m[0][1] * x_center + (1 - m[0][0]) * y_center;
int memsize = width * height * channels;
uint8_t* odata;
if (ImageTMP)
{
odata = ImageTMP->RGBImageLock();
}
else
{
odata = (unsigned char*)GET_MEMORY(memsize);
}
int x_source, y_source;
stbi_uc* p_target;
stbi_uc* p_source;
RGBImageLock();
for (int x = 0; x < width; ++x)
for (int y = 0; y < height; ++y)
{
p_target = odata + (channels * (y * width + x));
x_source = int(m[0][0] * x + m[0][1] * y);
y_source = int(m[1][0] * x + m[1][1] * y);
x_source += int(m[0][2]);
y_source += int(m[1][2]);
if ((x_source >= 0) && (x_source < width) && (y_source >= 0) && (y_source < height))
{
p_source = rgb_image + (channels * (y_source * width + x_source));
for (int _channels = 0; _channels < channels; ++_channels)
p_target[_channels] = p_source[_channels];
}
else
{
for (int _channels = 0; _channels < channels; ++_channels)
p_target[_channels] = 255;
}
}
// memcpy(rgb_image, odata, memsize);
memCopy(odata, rgb_image, memsize);
if (!ImageTMP)
{
stbi_image_free(odata);
}
if (ImageTMP)
ImageTMP->RGBImageRelease();
RGBImageRelease();
}
void CRotateImage::Rotate(float _angle)
{
// printf("width %d, height %d\n", width, height);
Rotate(_angle, width / 2, height / 2);
}
void CRotateImage::Translate(int _dx, int _dy)
{
int memsize = width * height * channels;
uint8_t* odata;
if (ImageTMP)
{
odata = ImageTMP->RGBImageLock();
}
else
{
odata = (unsigned char*)GET_MEMORY(memsize);
}
int x_source, y_source;
stbi_uc* p_target;
stbi_uc* p_source;
RGBImageLock();
for (int x = 0; x < width; ++x)
for (int y = 0; y < height; ++y)
{
p_target = odata + (channels * (y * width + x));
x_source = x - _dx;
y_source = y - _dy;
if ((x_source >= 0) && (x_source < width) && (y_source >= 0) && (y_source < height))
{
p_source = rgb_image + (channels * (y_source * width + x_source));
for (int _channels = 0; _channels < channels; ++_channels)
p_target[_channels] = p_source[_channels];
}
else
{
for (int _channels = 0; _channels < channels; ++_channels)
p_target[_channels] = 255;
}
}
// memcpy(rgb_image, odata, memsize);
memCopy(odata, rgb_image, memsize);
if (!ImageTMP)
{
stbi_image_free(odata);
}
if (ImageTMP)
{
ImageTMP->RGBImageRelease();
}
RGBImageRelease();
}

View File

@@ -0,0 +1,16 @@
#include "CImageBasis.h"
class CRotateImage: public CImageBasis
{
public:
CImageBasis *ImageTMP;
CRotateImage(std::string _image) : CImageBasis(_image) {ImageTMP = NULL;};
CRotateImage(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL;};
CRotateImage(CImageBasis *_org, CImageBasis *_temp);
void Rotate(float _angle);
void Rotate(float _angle, int _centerx, int _centery);
void Translate(int _dx, int _dy);
void Mirror();
};

View File

@@ -10,6 +10,48 @@ static const char *TAG = "log";
ClassLogFile LogFile("/sdcard/log/message", "log_%Y-%m-%d.txt");
void ClassLogFile::WriteHeapInfo(std::string _id)
{
std::string _zw;
_zw = "\t" + _id + "\t" + getESPHeapInfo();
WriteToFile(_zw);
}
std::string ClassLogFile::getESPHeapInfo(){
string espInfoResultStr = "";
char aMsgBuf[80];
multi_heap_info_t aMultiHead_info ;
heap_caps_get_info (&aMultiHead_info,MALLOC_CAP_8BIT);
size_t aFreeHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT);
size_t aMinFreeHeadSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT);
size_t aMinFreeHeapSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT);
size_t aHeapLargestFreeBlockSize = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT);
sprintf(aMsgBuf,"Free Heap Size: \t%ld", (long) aFreeHeapSize);
size_t aFreeSPIHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_SPIRAM);
size_t aFreeInternalHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_INTERNAL);
size_t aMinFreeInternalHeapSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_INTERNAL);
sprintf(aMsgBuf,"\tHeap:\t%ld", (long) aFreeHeapSize);
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf,"\tMin Free:\t%ld", (long) aMinFreeHeapSize);
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf,"\tlarg. Block: \t%ld", (long) aHeapLargestFreeBlockSize);
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf,"\tSPI Heap:\t%ld", (long) aFreeSPIHeapSize);
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf,"\tMin Free Heap Size:\t%ld", (long) aMinFreeHeadSize);
sprintf(aMsgBuf,"\tNOT_SPI Heap:\t%ld", (long) (aFreeHeapSize - aFreeSPIHeapSize));
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf,"\tlargest Block Size: \t%ld", (long) aHeapLargestFreeBlockSize);
sprintf(aMsgBuf,"\tInternal Heap:\t%ld", (long) (aFreeInternalHeapSize));
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf,"\tInternal Min Heap free:\t%ld", (long) (aMinFreeInternalHeapSize));
espInfoResultStr += string(aMsgBuf);
return espInfoResultStr;
}
void ClassLogFile::WriteToDedicatedFile(std::string _fn, std::string info, bool _time)
{
FILE* pFile;
@@ -19,7 +61,10 @@ void ClassLogFile::WriteToDedicatedFile(std::string _fn, std::string info, bool
return;
}
// pFile = OpenFileAndWait(_fn.c_str(), "a");
pFile = fopen(_fn.c_str(), "a+");
printf("Logfile opened: %s\n", _fn.c_str());
if (pFile!=NULL) {
if (_time)
{
@@ -54,6 +99,7 @@ void ClassLogFile::SetRetention(unsigned short _retentionInDays){
void ClassLogFile::WriteToFile(std::string info, bool _time)
{
/*
struct stat path_stat;
if (stat(logroot.c_str(), &path_stat) != 0) {
ESP_LOGI(TAG, "Create log folder: %s", logroot.c_str());
@@ -61,7 +107,7 @@ void ClassLogFile::WriteToFile(std::string info, bool _time)
ESP_LOGI(TAG, "Can't create log foolder");
}
}
*/
time_t rawtime;
struct tm* timeinfo;
char buffer[30];
@@ -79,12 +125,12 @@ std::string ClassLogFile::GetCurrentFileName()
{
time_t rawtime;
struct tm* timeinfo;
char buffer[30];
char buffer[60];
time(&rawtime);
timeinfo = localtime(&rawtime);
strftime(buffer, 30, logfile.c_str(), timeinfo);
strftime(buffer, 60, logfile.c_str(), timeinfo);
std::string logpath = logroot + "/" + buffer;
return logpath;

View File

@@ -12,6 +12,10 @@ private:
public:
ClassLogFile(std::string _logpath, std::string _logfile);
std::string getESPHeapInfo();
void WriteHeapInfo(std::string _id);
void SwitchOnOff(bool _doLogFile);
void SetRetention(unsigned short _retentionInDays);

View File

@@ -64,10 +64,18 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
mqtt_event_handler_cb((esp_mqtt_event_handle_t) event_data);
}
void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password){
void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password, std::string _LWTContext, int _keepalive){
std::string _zwmessage = "connection lost";
int _lzw = _zwmessage.length();
esp_mqtt_client_config_t mqtt_cfg = {
.uri = _mqttURI.c_str(),
.client_id = _clientid.c_str(),
.lwt_topic = _LWTContext.c_str(),
.lwt_msg = _zwmessage.c_str(),
.lwt_msg_len = _lzw,
.keepalive = _keepalive
};
if (_user.length() && _password.length()){
@@ -79,4 +87,6 @@ void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, st
client = esp_mqtt_client_init(&mqtt_cfg);
esp_mqtt_client_register_event(client, esp_mmqtt_ID, mqtt_event_handler, client);
esp_mqtt_client_start(client);
MQTTPublish(_LWTContext, "");
}

View File

@@ -1,4 +1,7 @@
#include <string>
void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user = "", std::string _password = "");
void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password, std::string _LWTContext, int _keepalive);
//void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user = "", std::string _password = "");
void MQTTPublish(std::string _key, std::string _content);

View File

@@ -2,6 +2,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
idf_component_register(SRCS ${app_sources}
INCLUDE_DIRS "."
REQUIRES jomjol_image_proc jomjol_logfile esp_http_server esp32-camera-master jomjol_controlcamera jomjol_flowcontroll)
REQUIRES jomjol_image_proc jomjol_logfile esp_http_server esp32-camera-master jomjol_controlcamera jomjol_flowcontroll jomjol_helper)

View File

@@ -1,12 +1,10 @@
#include "CTfLiteClass.h"
#include "bitmap_image.hpp"
#include "ClassLogFile.h"
#include "Helper.h"
#include <sys/stat.h>
bool debugdetailtflite = false;
// #define DEBUG_DETAIL_ON
float CTfLiteClass::GetOutputValue(int nr)
{
@@ -19,19 +17,14 @@ float CTfLiteClass::GetOutputValue(int nr)
return output2->data.f[nr];
}
int CTfLiteClass::GetClassFromImage(std::string _fn)
int CTfLiteClass::GetClassFromImageBasis(CImageBasis *rs)
{
// printf("Before Load image %s\n", _fn.c_str());
if (!LoadInputImage(_fn))
if (!LoadInputImageBasis(rs))
return -1000;
// printf("After Load image %s\n", _fn.c_str());
Invoke();
printf("After Invoke %s\n", _fn.c_str());
return GetOutClassification();
// return 0;
}
int CTfLiteClass::GetOutClassification()
@@ -55,7 +48,6 @@ int CTfLiteClass::GetOutClassification()
zw_class = i;
}
}
// printf("Result Ziffer: %d\n", zw_class);
return zw_class;
}
@@ -107,21 +99,17 @@ void CTfLiteClass::GetOutPut()
void CTfLiteClass::Invoke()
{
interpreter->Invoke();
// printf("Invoke Done.\n");
}
bool CTfLiteClass::LoadInputImage(std::string _fn)
bool CTfLiteClass::LoadInputImageBasis(CImageBasis *rs)
{
std::string zw = "ClassFlowAnalog::doNeuralNetwork nach Load Image: " + _fn;
// LogFile.WriteToFile(zw);
bitmap_image image(_fn);
if (debugdetailtflite) LogFile.WriteToFile(zw);
std::string zw = "ClassFlowAnalog::doNeuralNetwork nach LoadInputResizeImage: ";
unsigned int w = image.width();
unsigned int h = image.height();
unsigned int w = rs->width;
unsigned int h = rs->height;
unsigned char red, green, blue;
// printf("Image: %s size: %d x %d\n", _fn.c_str(), w, h);
input_i = 0;
@@ -130,21 +118,20 @@ bool CTfLiteClass::LoadInputImage(std::string _fn)
for (int y = 0; y < h; ++y)
for (int x = 0; x < w; ++x)
{
red = image.red_channel(x, y);
green = image.green_channel(x, y);
blue = image.blue_channel(x, y);
red = rs->GetPixelColor(x, y, 0);
green = rs->GetPixelColor(x, y, 1);
blue = rs->GetPixelColor(x, y, 2);
*(input_data_ptr) = (float) red;
input_data_ptr++;
*(input_data_ptr) = (float) green;
input_data_ptr++;
*(input_data_ptr) = (float) blue;
input_data_ptr++;
// printf("BMP: %f %f %f\n", (float) red, (float) green, (float) blue);
}
if (debugdetailtflite) LogFile.WriteToFile("Nach dem Laden in input");
#ifdef DEBUG_DETAIL_ON
LogFile.WriteToFile("Nach dem Laden in input");
#endif
return true;
}
@@ -152,7 +139,6 @@ bool CTfLiteClass::LoadInputImage(std::string _fn)
void CTfLiteClass::MakeAllocate()
{
// static tflite::ops::micro::AllOpsResolver resolver;
static tflite::AllOpsResolver resolver;
this->interpreter = new tflite::MicroInterpreter(this->model, resolver, this->tensor_arena, this->kTensorArenaSize, this->error_reporter);
@@ -162,16 +148,15 @@ void CTfLiteClass::MakeAllocate()
this->GetInputDimension();
return;
}
// printf("Allocate Done.\n");
}
void CTfLiteClass::GetInputTensorSize(){
float *zw = this->input;
int test = sizeof(zw);
#ifdef DEBUG_DETAIL_ON
printf("Input Tensor Dimension: %d\n", test);
printf("Input Tensor Dimension: %d\n", test);
#endif
}
long CTfLiteClass::GetFileSize(std::string filename)
@@ -186,24 +171,34 @@ unsigned char* CTfLiteClass::ReadFileToCharArray(std::string _fn)
{
long size;
size = this->GetFileSize(_fn);
size = GetFileSize(_fn);
if (size == -1)
{
printf("\nFile existiert nicht.\n");
return NULL;
printf("\nFile existiert nicht.\n");
return NULL;
}
unsigned char *result = (unsigned char*) malloc(size);
int anz = 1;
TickType_t xDelay;
while (!result && (anz < 6)) // maximal 5x versuchen (= 5s)
{
#ifdef DEBUG_DETAIL_ON
printf("Speicher ist voll - Versuche es erneut: %d.\n", anz);
#endif
xDelay = 1000 / portTICK_PERIOD_MS;
result = (unsigned char*) malloc(size);
anz++;
}
if(result != NULL) {
// printf("\nSpeicher ist reserviert\n");
FILE* f = fopen(_fn.c_str(), "rb"); // vorher nur "r"
if(result != NULL) {
FILE* f = OpenFileAndWait(_fn.c_str(), "rb"); // vorher nur "r"
fread(result, 1, size, f);
fclose(f);
}else {
printf("\nKein freier Speicher vorhanden.\n");
}else {
printf("\nKein freier Speicher vorhanden.\n");
}
@@ -219,14 +214,11 @@ void CTfLiteClass::LoadModel(std::string _fn){
#endif
unsigned char *rd;
rd = this->ReadFileToCharArray(_fn.c_str());
// printf("loadedfile: %d", (int) rd);
rd = ReadFileToCharArray(_fn.c_str());
this->model = tflite::GetModel(rd);
free(rd);
TFLITE_MINIMAL_CHECK(model != nullptr);
// printf("tfile Loaded.\n");
}
@@ -237,7 +229,7 @@ CTfLiteClass::CTfLiteClass()
this->interpreter = nullptr;
this->input = nullptr;
this->output = nullptr;
this->kTensorArenaSize = 600 * 1024;
this->kTensorArenaSize = 150 * 1024; /// laut testfile: 108000 - bisher 600
this->tensor_arena = new uint8_t[kTensorArenaSize];
}
@@ -255,6 +247,6 @@ namespace tflite {
return 0;
}
} // namespace tflite
}

View File

@@ -14,6 +14,8 @@
#include "esp_err.h"
#include "esp_log.h"
#include "CImageBasis.h"
#define SUPRESS_TFLITE_ERRORS // use, to avoid error messages from TFLITE
@@ -39,7 +41,6 @@ class CTfLiteClass
const tflite::Model* model;
tflite::MicroInterpreter* interpreter;
TfLiteTensor* output = nullptr;
// static tflite::ops::micro::AllOpsResolver *resolver;
static tflite::AllOpsResolver resolver;
int kTensorArenaSize;
@@ -58,11 +59,11 @@ class CTfLiteClass
void LoadModel(std::string _fn);
void MakeAllocate();
void GetInputTensorSize();
bool LoadInputImage(std::string _fn);
bool LoadInputImageBasis(CImageBasis *rs);
void Invoke();
void GetOutPut();
int GetOutClassification();
int GetClassFromImage(std::string _fn);
int GetClassFromImageBasis(CImageBasis *rs);
float GetOutputValue(int nr);
void GetInputDimension(bool silent);

View File

@@ -18,17 +18,41 @@
#include "ClassLogFile.h"
//#define DEBUG_DETAIL_ON
ClassFlowControll tfliteflow;
TaskHandle_t xHandleblink_task_doFlow = NULL;
TaskHandle_t xHandletask_autodoFlow = NULL;
bool flowisrunning = false;
long auto_intervall = 0;
bool auto_isrunning = false;
int countRounds = 0;
int getCountFlowRounds() {
return countRounds;
}
esp_err_t GetJPG(std::string _filename, httpd_req_t *req)
{
return tfliteflow.GetJPGStream(_filename, req);
}
esp_err_t GetRawJPG(httpd_req_t *req)
{
return tfliteflow.SendRawJPG(req);
}
bool isSetupModusActive() {
return tfliteflow.getStatusSetupModus();
return false;
@@ -37,28 +61,40 @@ bool isSetupModusActive() {
void KillTFliteTasks()
{
printf("Handle: xHandleblink_task_doFlow: %ld\n", (long) xHandleblink_task_doFlow);
#ifdef DEBUG_DETAIL_ON
printf("Handle: xHandleblink_task_doFlow: %ld\n", (long) xHandleblink_task_doFlow);
#endif
if (xHandleblink_task_doFlow)
{
vTaskDelete(xHandleblink_task_doFlow);
#ifdef DEBUG_DETAIL_ON
printf("Killed: xHandleblink_task_doFlow\n");
#endif
}
#ifdef DEBUG_DETAIL_ON
printf("Handle: xHandletask_autodoFlow: %ld\n", (long) xHandletask_autodoFlow);
#endif
if (xHandletask_autodoFlow)
{
vTaskDelete(xHandletask_autodoFlow);
#ifdef DEBUG_DETAIL_ON
printf("Killed: xHandletask_autodoFlow\n");
#endif
}
}
void doInit(void)
{
string config = "/sdcard/config/config.ini";
string config = "/sdcard/config/config.ini";
#ifdef DEBUG_DETAIL_ON
printf("Start tfliteflow.InitFlow(config);\n");
#endif
tfliteflow.InitFlow(config);
#ifdef DEBUG_DETAIL_ON
printf("Finished tfliteflow.InitFlow(config);\n");
#endif
}
@@ -71,13 +107,17 @@ bool doflow(void)
tfliteflow.doFlow(zw_time);
flowisrunning = false;
#ifdef DEBUG_DETAIL_ON
printf("doflow - end %s\n", zw_time.c_str());
#endif
return true;
}
void blink_task_doFlow(void *pvParameter)
{
#ifdef DEBUG_DETAIL_ON
printf("blink_task_doFlow\n");
#endif
if (!flowisrunning)
{
flowisrunning = true;
@@ -91,8 +131,10 @@ void blink_task_doFlow(void *pvParameter)
esp_err_t handler_init(httpd_req_t *req)
{
LogFile.WriteToFile("handler_init");
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_init - Start");
printf("handler_doinit uri:\n"); printf(req->uri); printf("\n");
#endif
char* resp_str = "Init started<br>";
httpd_resp_send(req, resp_str, strlen(resp_str));
@@ -104,12 +146,19 @@ esp_err_t handler_init(httpd_req_t *req)
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_init - Done");
#endif
return ESP_OK;
};
esp_err_t handler_doflow(httpd_req_t *req)
{
LogFile.WriteToFile("handler_doflow");
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_doflow - Start");
#endif
char* resp_str;
printf("handler_doFlow uri: "); printf(req->uri); printf("\n");
@@ -127,7 +176,12 @@ esp_err_t handler_doflow(httpd_req_t *req)
resp_str = "doFlow gestartet - dauert ca. 60 Sekunden";
httpd_resp_send(req, resp_str, strlen(resp_str));
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
httpd_resp_send_chunk(req, NULL, 0);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_doflow - Done");
#endif
return ESP_OK;
};
@@ -136,7 +190,10 @@ esp_err_t handler_doflow(httpd_req_t *req)
esp_err_t handler_wasserzaehler(httpd_req_t *req)
{
LogFile.WriteToFile("handler_wasserzaehler");
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_wasserzaehler - Start");
#endif
bool _rawValue = false;
bool _noerror = false;
string zw;
@@ -151,12 +208,16 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
// printf("Query: "); printf(_query); printf("\n");
if (httpd_query_key_value(_query, "rawvalue", _size, 10) == ESP_OK)
{
#ifdef DEBUG_DETAIL_ON
printf("rawvalue is found"); printf(_size); printf("\n");
#endif
_rawValue = true;
}
if (httpd_query_key_value(_query, "noerror", _size, 10) == ESP_OK)
{
#ifdef DEBUG_DETAIL_ON
printf("noerror is found"); printf(_size); printf("\n");
#endif
_noerror = true;
}
}
@@ -171,7 +232,7 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
{
string txt, zw;
txt = "<p>Aligned Image: <p><img src=\"/img_tmp/alg.jpg\"> <p>\n";
txt = "<p>Aligned Image: <p><img src=\"/img_tmp/alg_roi.jpg\"> <p>\n";
txt = txt + "Digital Counter: <p> ";
httpd_resp_sendstr_chunk(req, txt.c_str());
@@ -205,7 +266,7 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
httpd_resp_sendstr_chunk(req, txt.c_str());
delete htmlinfo[i];
}
htmlinfo.clear();
htmlinfo.clear();
}
@@ -217,13 +278,18 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_sendstr_chunk(req, NULL);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_wasserzaehler - Done");
#endif
return ESP_OK;
};
esp_err_t handler_editflow(httpd_req_t *req)
{
LogFile.WriteToFile("handler_editflow");
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_editflow - Start");
#endif
printf("handler_editflow uri: "); printf(req->uri); printf("\n");
@@ -235,7 +301,9 @@ esp_err_t handler_editflow(httpd_req_t *req)
{
if (httpd_query_key_value(_query, "task", _valuechar, 30) == ESP_OK)
{
#ifdef DEBUG_DETAIL_ON
printf("task is found: %s\n", _valuechar);
#endif
_task = string(_valuechar);
}
}
@@ -246,11 +314,13 @@ esp_err_t handler_editflow(httpd_req_t *req)
httpd_query_key_value(_query, "in", _valuechar, 30);
in = string(_valuechar);
printf("in: "); printf(in.c_str()); printf("\n");
httpd_query_key_value(_query, "out", _valuechar, 30);
out = string(_valuechar);
#ifdef DEBUG_DETAIL_ON
printf("in: "); printf(in.c_str()); printf("\n");
printf("out: "); printf(out.c_str()); printf("\n");
#endif
in = "/sdcard" + in;
out = "/sdcard" + out;
@@ -269,31 +339,34 @@ esp_err_t handler_editflow(httpd_req_t *req)
httpd_query_key_value(_query, "in", _valuechar, 30);
in = string(_valuechar);
printf("in: "); printf(in.c_str()); printf("\n");
httpd_query_key_value(_query, "out", _valuechar, 30);
out = string(_valuechar);
printf("out: "); printf(out.c_str()); printf("\n");
httpd_query_key_value(_query, "x", _valuechar, 30);
zw = string(_valuechar);
x = stoi(zw);
printf("x: "); printf(zw.c_str()); printf("\n");
httpd_query_key_value(_query, "y", _valuechar, 30);
zw = string(_valuechar);
y = stoi(zw);
printf("y: "); printf(zw.c_str()); printf("\n");
httpd_query_key_value(_query, "dx", _valuechar, 30);
zw = string(_valuechar);
dx = stoi(zw);
printf("dx: "); printf(zw.c_str()); printf("\n");
httpd_query_key_value(_query, "dy", _valuechar, 30);
zw = string(_valuechar);
dy = stoi(zw);
#ifdef DEBUG_DETAIL_ON
printf("in: "); printf(in.c_str()); printf("\n");
printf("out: "); printf(out.c_str()); printf("\n");
printf("x: "); printf(zw.c_str()); printf("\n");
printf("y: "); printf(zw.c_str()); printf("\n");
printf("dx: "); printf(zw.c_str()); printf("\n");
printf("dy: "); printf(zw.c_str()); printf("\n");
#endif
if (httpd_query_key_value(_query, "enhance", _valuechar, 10) == ESP_OK)
{
@@ -324,6 +397,7 @@ esp_err_t handler_editflow(httpd_req_t *req)
zw = "CutImage Done";
httpd_resp_sendstr_chunk(req, zw.c_str());
}
if (_task.compare("test_take") == 0)
@@ -379,13 +453,20 @@ esp_err_t handler_editflow(httpd_req_t *req)
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_sendstr_chunk(req, NULL);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_editflow - Done");
#endif
return ESP_OK;
};
esp_err_t handler_prevalue(httpd_req_t *req)
{
LogFile.WriteToFile("handler_prevalue");
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_prevalue - Start");
#endif
const char* resp_str;
string zw;
@@ -399,7 +480,9 @@ esp_err_t handler_prevalue(httpd_req_t *req)
// printf("Query: "); printf(_query); printf("\n");
if (httpd_query_key_value(_query, "value", _size, 10) == ESP_OK)
{
#ifdef DEBUG_DETAIL_ON
printf("Value: "); printf(_size); printf("\n");
#endif
}
}
@@ -414,6 +497,10 @@ esp_err_t handler_prevalue(httpd_req_t *req)
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_prevalue - Start");
#endif
return ESP_OK;
};
@@ -434,20 +521,27 @@ void task_autodoFlow(void *pvParameter)
while (auto_isrunning)
{
LogFile.WriteToFile("task_autodoFlow - next round");
std::string _zw = "task_autodoFlow - next round - Round #" + std::to_string(++countRounds);
LogFile.WriteToFile(_zw);
printf("Autoflow: start\n");
fr_start = esp_timer_get_time();
if (flowisrunning)
{
#ifdef DEBUG_DETAIL_ON
printf("Autoflow: doFLow laeuft bereits!\n");
#endif
}
else
{
#ifdef DEBUG_DETAIL_ON
printf("Autoflow: doFLow wird gestartet\n");
#endif
flowisrunning = true;
doflow();
#ifdef DEBUG_DETAIL_ON
printf("Remove older log files\n");
#endif
LogFile.RemoveOld();
}
@@ -507,5 +601,4 @@ void register_server_tflite_uri(httpd_handle_t server)
camuri.handler = handler_wasserzaehler;
camuri.user_ctx = (void*) "Wasserzaehler";
httpd_register_uri_handler(server, &camuri);
}

View File

@@ -1,6 +1,7 @@
#include <esp_log.h>
#include <esp_http_server.h>
#include "CImageBasis.h"
//#include "ClassControllCamera.h"
@@ -12,4 +13,8 @@ void KillTFliteTasks();
void TFliteDoAutoStart();
bool isSetupModusActive();
bool isSetupModusActive();
esp_err_t GetJPG(std::string _filename, httpd_req_t *req);
esp_err_t GetRawJPG(httpd_req_t *req);

View File

@@ -1,11 +1,5 @@
#include "time_sntp.h"
/* LwIP SNTP example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string>
#include <time.h>
#include <sys/time.h>
@@ -17,25 +11,19 @@
#include "esp_log.h"
#include "esp_attr.h"
#include "esp_sleep.h"
// #include "nvs_flash.h"
// #include "protocol_examples_common.h"
#include "esp_sntp.h"
#include "ClassLogFile.h"
static const char *TAG = "sntp";
RTC_DATA_ATTR int boot_count = 0;
bool setTimeAlwaysOnReboot = true;
static void obtain_time(void);
static void initialize_sntp(void);
void time_sync_notification_cb(struct timeval *tv)
{
// LogFile.WriteToFile("Notification of a time synchronization event");
ESP_LOGI(TAG, "Notification of a time synchronization event");
}
@@ -54,9 +42,6 @@ std::string gettimestring(const char * frm)
void setup_time()
{
++boot_count;
ESP_LOGI(TAG, "Boot count: %d", boot_count);
time_t now;
struct tm timeinfo;
time(&now);
@@ -72,8 +57,6 @@ void setup_time()
char strftime_buf[64];
setTimeZone("CET-1CEST,M3.5.0,M10.5.0/3");
// setTimeZone("Europe/Berlin");
// setTimeZone("Asia/Tokyo");
localtime_r(&now, &timeinfo);
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
@@ -97,9 +80,6 @@ void setTimeZone(std::string _tzstring)
static void obtain_time(void)
{
// initialize_sntp();
// wait for time to be set
time_t now = 0;
struct tm timeinfo = {};
int retry = 0;
@@ -110,18 +90,23 @@ static void obtain_time(void)
ESP_LOGI(TAG, "Waiting for system time to be set... (%d/%d)", retry, retry_count);
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
if (retry == retry_count) {
// LogFile.WriteToFile("Time Synchzronisation nicht erfolgreich ...");
}
else
{
// LogFile.WriteToFile("Time erfolgreich ...");
}
time(&now);
localtime_r(&now, &timeinfo);
}
void reset_servername(std::string _servername)
{
printf("Set SNTP-Server: %s\n", _servername.c_str());
sntp_stop();
sntp_setoperatingmode(SNTP_OPMODE_POLL);
sntp_setservername(0, _servername.c_str());
sntp_init();
obtain_time();
std::string zw = gettimestring("%Y%m%d-%H%M%S");
printf("Time ist %s\n", zw.c_str());
}
static void initialize_sntp(void)
{
ESP_LOGI(TAG, "Initializing SNTP");

View File

@@ -15,4 +15,5 @@
void setup_time(void);
std::string gettimestring(const char * frm);
void setTimeZone(std::string _tzstring);
void setTimeZone(std::string _tzstring);
void reset_servername(std::string _servername);

View File

@@ -25,7 +25,7 @@
#include "ClassControllCamera.h"
#include "server_main.h"
#include "server_camera.h"
#include "server_GPIO.h"
static const char *TAGMAIN = "connect_wlan_main";
#define FLASH_GPIO GPIO_NUM_4
@@ -44,10 +44,15 @@ void Init_NVS_SDCard()
// sdmmc_host_t host = SDMMC_HOST_SLOT_1();
// host.flags = SDMMC_HOST_FLAG_1BIT;
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
slot_config.width = 1; // 1 line SD mode
esp_vfs_fat_sdmmc_mount_config_t mount_config = { };
mount_config.format_if_mount_failed = false;
mount_config.max_files = 5;
gpio_set_pull_mode((gpio_num_t) 15, GPIO_PULLUP_ONLY); // CMD, needed in 4- and 1- line modes
gpio_set_pull_mode((gpio_num_t) 2, GPIO_PULLUP_ONLY); // D0, needed in 4- and 1-line modes
sdmmc_card_t* card;
ret = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card);
if (ret != ESP_OK) {
@@ -88,11 +93,12 @@ extern "C" void app_main(void)
// LoadWlanFromFile("/sdcard/wlan.ini", ssid, password, hostname, ip, gw, netmask, dns);
LoadWlanFromFile("/sdcard/wlan.ini", ssid, password, hostname);
LoadNetConfigFromFile("/sdcard/wlan.ini", ip, gw, netmask, dns);
// LogFile.WriteToFile("Startsequence 04");
printf("To use WLan: %s, %s\n", ssid.c_str(), password.c_str());
printf("To set Hostename: %s\n", hostname.c_str());
printf("Fixed IP: %s, Gateway %s, Netmask %s\n", ip.c_str(), gw.c_str(), netmask.c_str());
printf("Fixed IP: %s, Gateway %s, Netmask %s, DNS %s\n", ip.c_str(), gw.c_str(), netmask.c_str(), dns.c_str());
if (ip.length() == 0 || gw.length() == 0 || netmask.length() == 0)
{
@@ -115,7 +121,9 @@ extern "C" void app_main(void)
vTaskDelay( xDelay );
// LogFile.WriteToFile("Startsequence 07");
setup_time();
LogFile.WriteToFile("============================== Main Started =======================================");
LogFile.WriteToFile("=============================================================================================");
LogFile.WriteToFile("=================================== Main Started ============================================");
LogFile.WriteToFile("=============================================================================================");
LogFile.SwitchOnOff(false);
std::string zw = gettimestring("%Y%m%d-%H%M%S");

View File

@@ -15,16 +15,22 @@
#include "server_tflite.h"
//#define DEBUG_DETAIL_ON
httpd_handle_t server = NULL;
std::string starttime = "";
/* An HTTP GET handler */
esp_err_t info_get_handler(httpd_req_t *req)
{
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("info_get_handler - Start");
#endif
LogFile.WriteToFile("info_get_handler");
char _query[200];
char _valuechar[30];
@@ -125,25 +131,40 @@ esp_err_t info_get_handler(httpd_req_t *req)
return ESP_OK;
}
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("info_get_handler - Done");
#endif
return ESP_OK;
}
esp_err_t starttime_get_handler(httpd_req_t *req)
{
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("starttime_get_handler - Start");
#endif
httpd_resp_send(req, starttime.c_str(), strlen(starttime.c_str()));
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
httpd_resp_send_chunk(req, NULL, 0);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("starttime_get_handler - Done");
#endif
return ESP_OK;
}
esp_err_t hello_main_handler(httpd_req_t *req)
{
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("hello_main_handler - Start");
#endif
char filepath[50];
struct stat file_stat;
printf("uri: %s\n", req->uri);
int _pos;
esp_err_t res;
char *base_path = (char*) req->user_ctx;
std::string filetosend(base_path);
@@ -182,60 +203,37 @@ esp_err_t hello_main_handler(httpd_req_t *req)
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long");
return ESP_FAIL;
}
if (stat(filetosend.c_str(), &file_stat) == -1) {
/* If file not present on SPIFFS check if URI
* corresponds to one of the hardcoded paths */
ESP_LOGE(TAG, "Failed to stat file : %s", filetosend.c_str());
/* Respond with 404 Not Found */
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File does not exist");
return ESP_FAIL;
}
esp_err_t res;
res = httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
if (res != ESP_OK)
return res;
res = send_file(req, filetosend, &file_stat);
res = send_file(req, filetosend);
if (res != ESP_OK)
return res;
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("hello_main_handler - Stop");
#endif
return ESP_OK;
}
esp_err_t img_tmp_handler(httpd_req_t *req)
{
char filepath[50];
struct stat file_stat;
printf("uri: %s\n", req->uri);
char *base_path = (char*) req->user_ctx;
std::string filetosend(base_path);
const char *filename = get_path_from_uri(filepath, base_path,
req->uri + sizeof("/img_tmp") - 1, sizeof(filepath));
req->uri + sizeof("/img_tmp/") - 1, sizeof(filepath));
printf("1 uri: %s, filename: %s, filepath: %s\n", req->uri, filename, filepath);
filetosend = filetosend + "/img_tmp/" + std::string(filename);
printf("File to upload: %s\n", filetosend.c_str());
if (!filename) {
ESP_LOGE(TAG, "Filename is too long");
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long");
return ESP_FAIL;
}
if (stat(filetosend.c_str(), &file_stat) == -1) {
/* If file not present on SPIFFS check if URI
* corresponds to one of the hardcoded paths */
ESP_LOGE(TAG, "Failed to stat file : %s", filetosend.c_str());
/* Respond with 404 Not Found */
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File does not exist");
return ESP_FAIL;
}
esp_err_t res = send_file(req, filetosend, &file_stat);
esp_err_t res = send_file(req, filetosend);
if (res != ESP_OK)
return res;
@@ -244,8 +242,54 @@ esp_err_t img_tmp_handler(httpd_req_t *req)
return ESP_OK;
}
esp_err_t img_tmp_virtual_handler(httpd_req_t *req)
{
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("img_tmp_virtual_handler - Start");
#endif
char filepath[50];
printf("uri: %s\n", req->uri);
char *base_path = (char*) req->user_ctx;
std::string filetosend(base_path);
const char *filename = get_path_from_uri(filepath, base_path,
req->uri + sizeof("/img_tmp/") - 1, sizeof(filepath));
printf("1 uri: %s, filename: %s, filepath: %s\n", req->uri, filename, filepath);
filetosend = std::string(filename);
printf("File to upload: %s\n", filetosend.c_str());
if (filetosend == "raw.jpg")
{
return GetRawJPG(req);
}
esp_err_t zw = GetJPG(filetosend, req);
if (zw == ESP_OK)
return ESP_OK;
// File wird nicht intern bereit gestellt --> klassischer weg:
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("img_tmp_virtual_handler - Done");
#endif
return img_tmp_handler(req);
}
esp_err_t sysinfo_handler(httpd_req_t *req)
{
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("sysinfo_handler - Start");
#endif
const char* resp_str;
std::string zw;
std::string cputemp = std::to_string(temperatureRead());
@@ -279,7 +323,11 @@ esp_err_t sysinfo_handler(httpd_req_t *req)
httpd_resp_set_type(req, "application/json");
httpd_resp_send(req, resp_str, strlen(resp_str));
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
httpd_resp_send_chunk(req, NULL, 0);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("sysinfo_handler - Done");
#endif
return ESP_OK;
}
@@ -314,7 +362,7 @@ void register_server_main_uri(httpd_handle_t server, const char *base_path)
httpd_uri_t img_tmp_handle = {
.uri = "/img_tmp/*", // Match all URIs of type /path/to/file
.method = HTTP_GET,
.handler = img_tmp_handler,
.handler = img_tmp_virtual_handler,
.user_ctx = (void*) base_path // Pass server data as context
};
httpd_register_uri_handler(server, &img_tmp_handle);

View File

@@ -22,9 +22,4 @@ httpd_handle_t start_webserver(void);
void register_server_main_uri(httpd_handle_t server, const char *base_path);
//void disconnect_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
//void connect_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
#endif

View File

@@ -1,4 +1,4 @@
const char* GIT_REV="bcdd0c6";
const char* GIT_REV="0e36010";
const char* GIT_TAG="";
const char* GIT_BRANCH="master";
const char* BUILD_TIME="2020-12-06 19:32";
const char* GIT_BRANCH="rolling";
const char* BUILD_TIME="2021-01-02 08:39";

View File

@@ -39,6 +39,7 @@ lib_deps =
jomjol_time_sntp
jomjol_logfile
jomjol_mqtt
jomjol_controlGPIO
monitor_speed = 115200

View File

@@ -173,7 +173,95 @@ CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1
CONFIG_BT_RESERVE_DRAM=0
# end of Bluetooth
# CONFIG_BLE_MESH is not set
CONFIG_BLE_MESH=y
CONFIG_BLE_MESH_HCI_5_0=y
# CONFIG_BLE_MESH_ALLOC_FROM_PSRAM_FIRST is not set
# CONFIG_BLE_MESH_FAST_PROV is not set
# CONFIG_BLE_MESH_NODE is not set
# CONFIG_BLE_MESH_PROVISIONER is not set
CONFIG_BLE_MESH_PROV=y
CONFIG_BLE_MESH_PB_ADV=y
# CONFIG_BLE_MESH_PB_GATT is not set
CONFIG_BLE_MESH_PROXY=y
# CONFIG_BLE_MESH_GATT_PROXY_CLIENT is not set
CONFIG_BLE_MESH_NET_BUF_POOL_USAGE=y
# CONFIG_BLE_MESH_SETTINGS is not set
CONFIG_BLE_MESH_SUBNET_COUNT=3
CONFIG_BLE_MESH_APP_KEY_COUNT=3
CONFIG_BLE_MESH_MODEL_KEY_COUNT=3
CONFIG_BLE_MESH_MODEL_GROUP_COUNT=3
CONFIG_BLE_MESH_LABEL_COUNT=3
CONFIG_BLE_MESH_CRPL=10
CONFIG_BLE_MESH_MSG_CACHE_SIZE=10
CONFIG_BLE_MESH_ADV_BUF_COUNT=60
# CONFIG_BLE_MESH_SUPPORT_BLE_ADV is not set
CONFIG_BLE_MESH_IVU_DIVIDER=4
CONFIG_BLE_MESH_TX_SEG_MSG_COUNT=1
CONFIG_BLE_MESH_RX_SEG_MSG_COUNT=1
CONFIG_BLE_MESH_RX_SDU_MAX=384
CONFIG_BLE_MESH_TX_SEG_MAX=32
# CONFIG_BLE_MESH_FRIEND is not set
# CONFIG_BLE_MESH_NO_LOG is not set
#
# BLE Mesh STACK DEBUG LOG LEVEL
#
# CONFIG_BLE_MESH_TRACE_LEVEL_NONE is not set
# CONFIG_BLE_MESH_TRACE_LEVEL_ERROR is not set
CONFIG_BLE_MESH_TRACE_LEVEL_WARNING=y
# CONFIG_BLE_MESH_TRACE_LEVEL_INFO is not set
# CONFIG_BLE_MESH_TRACE_LEVEL_DEBUG is not set
# CONFIG_BLE_MESH_TRACE_LEVEL_VERBOSE is not set
CONFIG_BLE_MESH_STACK_TRACE_LEVEL=2
# end of BLE Mesh STACK DEBUG LOG LEVEL
#
# BLE Mesh NET BUF DEBUG LOG LEVEL
#
# CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_NONE is not set
# CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_ERROR is not set
CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_WARNING=y
# CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_INFO is not set
# CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_DEBUG is not set
# CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_VERBOSE is not set
CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL=2
# end of BLE Mesh NET BUF DEBUG LOG LEVEL
CONFIG_BLE_MESH_CLIENT_MSG_TIMEOUT=4000
#
# Support for BLE Mesh Client Models
#
# CONFIG_BLE_MESH_CFG_CLI is not set
# CONFIG_BLE_MESH_HEALTH_CLI is not set
# CONFIG_BLE_MESH_GENERIC_ONOFF_CLI is not set
# CONFIG_BLE_MESH_GENERIC_LEVEL_CLI is not set
# CONFIG_BLE_MESH_GENERIC_DEF_TRANS_TIME_CLI is not set
# CONFIG_BLE_MESH_GENERIC_POWER_ONOFF_CLI is not set
# CONFIG_BLE_MESH_GENERIC_POWER_LEVEL_CLI is not set
# CONFIG_BLE_MESH_GENERIC_BATTERY_CLI is not set
# CONFIG_BLE_MESH_GENERIC_LOCATION_CLI is not set
# CONFIG_BLE_MESH_GENERIC_PROPERTY_CLI is not set
# CONFIG_BLE_MESH_SENSOR_CLI is not set
# CONFIG_BLE_MESH_TIME_CLI is not set
# CONFIG_BLE_MESH_SCENE_CLI is not set
# CONFIG_BLE_MESH_SCHEDULER_CLI is not set
# CONFIG_BLE_MESH_LIGHT_LIGHTNESS_CLI is not set
# CONFIG_BLE_MESH_LIGHT_CTL_CLI is not set
# CONFIG_BLE_MESH_LIGHT_HSL_CLI is not set
# CONFIG_BLE_MESH_LIGHT_XYL_CLI is not set
# CONFIG_BLE_MESH_LIGHT_LC_CLI is not set
# end of Support for BLE Mesh Client Models
# CONFIG_BLE_MESH_IV_UPDATE_TEST is not set
#
# BLE Mesh specific test option
#
# CONFIG_BLE_MESH_SELF_TEST is not set
# CONFIG_BLE_MESH_SHELL is not set
# CONFIG_BLE_MESH_DEBUG is not set
# end of BLE Mesh specific test option
#
# CoAP Configuration
@@ -537,8 +625,8 @@ CONFIG_FATFS_MAX_LFN=255
CONFIG_FATFS_API_ENCODING_ANSI_OEM=y
# CONFIG_FATFS_API_ENCODING_UTF_16 is not set
# CONFIG_FATFS_API_ENCODING_UTF_8 is not set
CONFIG_FATFS_FS_LOCK=5
CONFIG_FATFS_TIMEOUT_MS=10000
CONFIG_FATFS_FS_LOCK=10
CONFIG_FATFS_TIMEOUT_MS=5000
CONFIG_FATFS_PER_FILE_CACHE=y
CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y
# end of FAT Filesystem support
@@ -965,7 +1053,7 @@ CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
#
# Virtual file system
#
CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y
# CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT is not set
CONFIG_VFS_SUPPORT_TERMIOS=y
#
@@ -1166,6 +1254,6 @@ CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread"
CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y
# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set
# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set
CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y
# CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT is not set
CONFIG_SUPPORT_TERMIOS=y
# End of deprecated options

View File

@@ -83,11 +83,11 @@ CONFIG_ESPTOOLPY_FLASHFREQ_40M=y
# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set
CONFIG_ESPTOOLPY_FLASHFREQ="40m"
# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y
# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set
# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set
CONFIG_ESPTOOLPY_FLASHSIZE="2MB"
CONFIG_ESPTOOLPY_FLASHSIZE="4MB"
CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y
CONFIG_ESPTOOLPY_BEFORE_RESET=y
# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
@@ -315,8 +315,8 @@ CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y
CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4
# CONFIG_ESP32_ULP_COPROC_ENABLED is not set
CONFIG_ESP32_ULP_COPROC_RESERVE_MEM=0
# CONFIG_ESP32_PANIC_PRINT_HALT is not set
CONFIG_ESP32_PANIC_PRINT_REBOOT=y
CONFIG_ESP32_PANIC_PRINT_HALT=y
# CONFIG_ESP32_PANIC_PRINT_REBOOT is not set
# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set
# CONFIG_ESP32_PANIC_GDBSTUB is not set
CONFIG_ESP32_DEBUG_OCDAWARE=y
@@ -537,8 +537,8 @@ CONFIG_FATFS_MAX_LFN=255
CONFIG_FATFS_API_ENCODING_ANSI_OEM=y
# CONFIG_FATFS_API_ENCODING_UTF_16 is not set
# CONFIG_FATFS_API_ENCODING_UTF_8 is not set
CONFIG_FATFS_FS_LOCK=5
CONFIG_FATFS_TIMEOUT_MS=10000
CONFIG_FATFS_FS_LOCK=10
CONFIG_FATFS_TIMEOUT_MS=5000
CONFIG_FATFS_PER_FILE_CACHE=y
CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y
# end of FAT Filesystem support
@@ -965,7 +965,7 @@ CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
#
# Virtual file system
#
CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y
# CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT is not set
CONFIG_VFS_SUPPORT_TERMIOS=y
#
@@ -1166,6 +1166,6 @@ CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread"
CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y
# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set
# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set
CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y
# CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT is not set
CONFIG_SUPPORT_TERMIOS=y
# End of deprecated options

View File

@@ -1,4 +1,4 @@
const char* GIT_REV="bcdd0c6";
const char* GIT_REV="0e36010";
const char* GIT_TAG="";
const char* GIT_BRANCH="master";
const char* BUILD_TIME="2020-12-06 19:32";
const char* GIT_BRANCH="rolling";
const char* BUILD_TIME="2021-01-02 08:39";

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -14,7 +14,7 @@ SearchFieldY = 20
[Digits]
Model = /config/dig0720s1.tflite
Model = /config/dig0721s1.tflite
;LogImageLocation = /log/digit
;LogfileRetentionInDays = 3
ModelInputSize = 20 32
@@ -39,13 +39,13 @@ PreValueAgeStartup = 720
AllowNegativeRates = false
MaxRateValue = 0.1
ErrorMessage = true
CheckDigitIncreaseConsistency = true
CheckDigitIncreaseConsistency = false
[MQTT]
Uri = mqtt://IP-ADRESS:1883
Topic = wasserzaehler/zaehlerstand
TopicError = wasserzaehler/error
ClientID = wasser
;Uri = mqtt://IP-ADRESS:1883
;Topic = wasserzaehler/zaehlerstand
;TopicError = wasserzaehler/error
;ClientID = wasser
;user = USERNAME
;password = PASSWORD
@@ -59,6 +59,7 @@ LogfileRetentionInDays = 3
[System]
TimeZone = CET-1CEST,M3.5.0,M10.5.0/3
;TimeServer = fritz.box
SetupMode = true
[Ende]

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -61,7 +61,7 @@ textarea {
</tr>
<tr>
<td width="20px" style="padding-left: 40px;">
<input type="checkbox" id="MakeImage_LogImageLocation_enabled" value="1" onclick = 'document.getElementById("MakeImage_LogImageLocation_value").disabled = !document.getElementById("MakeImage_LogImageLocation_value1").disabled' unchecked >
<input type="checkbox" id="MakeImage_LogImageLocation_enabled" value="1" onclick = 'document.getElementById("MakeImage_LogImageLocation_value1").disabled = !document.getElementById("MakeImage_LogImageLocation_value1").disabled' unchecked >
</td>
<td width="200px">
<class id="MakeImage_LogImageLocation_text" style="color:black;">LogImageLocation</class>
@@ -75,7 +75,7 @@ textarea {
</tr>
<tr>
<td width="20px" style="padding-left: 40px;">
<td"><input type="checkbox" id="MakeImage_LogfileRetentionInDays_enabled" value="1" onclick = 'document.getElementById("MakeImage_LogfileRetentionInDays_value").disabled = !document.getElementById("MakeImage_LogfileRetentionInDays_value1").disabled' unchecked ></td>
<td"><input type="checkbox" id="MakeImage_LogfileRetentionInDays_enabled" value="1" onclick = 'document.getElementById("MakeImage_LogfileRetentionInDays_value1").disabled = !document.getElementById("MakeImage_LogfileRetentionInDays_value1").disabled' unchecked ></td>
</td>
<td>
<class id="MakeImage_LogfileRetentionInDays_text" style="color:black;">LogfileRetentionInDays</class>
@@ -123,7 +123,7 @@ textarea {
<td>
<select id="MakeImage_ImageSize_value1">
<option value="0" selected>VGA</option>
<option value="1" >SVGA</option>
<option value="1" >QVGA</option>
</select>
</td>
<td style="font-size: 80%;">
@@ -538,7 +538,7 @@ textarea {
</tr>
<tr>
<td width="20px" style="padding-left: 40px;">
<td"><input type="checkbox" id="Debug_LogfileRetentionInDays_enabled" value="1" onclick = 'document.getElementById("Debug_LogfileRetentionInDays_value").disabled = !document.getElementById("Debug_LogfileRetentionInDays_value1").disabled' unchecked ></td>
<td"><input type="checkbox" id="Debug_LogfileRetentionInDays_enabled" value="1" onclick = 'document.getElementById("Debug_LogfileRetentionInDays_value1").disabled = !document.getElementById("Debug_LogfileRetentionInDays_value1").disabled' unchecked ></td>
</td>
<td>
<class id="Debug_LogfileRetentionInDays_text" style="color:black;">LogfileRetentionInDays</class>
@@ -556,7 +556,7 @@ textarea {
</tr>
<tr>
<td width="20px" style="padding-left: 40px;">
<td"><input type="checkbox" id="System_TimeZone_enabled" value="1" onclick = 'document.getElementById("System_TimeZone_value").disabled = !document.getElementById("System_TimeZone_value1").disabled' unchecked ></td>
<td"><input type="checkbox" id="System_TimeZone_enabled" value="1" onclick = 'document.getElementById("System_TimeZone_value1").disabled = !document.getElementById("System_TimeZone_value1").disabled' unchecked ></td>
</td>
<td>
<class id="System_TimeZone_text" style="color:black;">TimeZone</class>
@@ -570,16 +570,16 @@ textarea {
</tr>
<tr class="expert" id="ex16">
<td width="20px" style="padding-left: 40px;">
<input type="checkbox" id="System_TimeUpdateIntervall_enabled" value="1" onclick = 'document.getElementById("System_TimeUpdateIntervall_value1").disabled = !document.getElementById("System_TimeUpdateIntervall_value1").disabled' unchecked >
</td>
<td width="200px">
<class id="System_TimeUpdateIntervall_text" style="color:black;">TimeUpdateIntervall</class>
<td"><input type="checkbox" id="System_TimeServer_enabled" value="1" onclick = 'document.getElementById("System_TimeServer_value1").disabled = !document.getElementById("System_TimeServer_value1").disabled' unchecked ></td>
</td>
<td>
<input type="number" id="System_TimeUpdateIntervall_value1" size="13" min="0" step="1">
<class id="System_TimeServer_text" style="color:black;">TimeServer</class>
</td>
<td>
<input type="text" id="System_TimeServer_value1">
</td>
<td style="font-size: 80%;">
Intervall for synchronizing the time with the time server (in hours)
Time server to synchronize system time (default: "pool.ntp.org" - used if nothing is specified)
</td>
</tr>
</table>
@@ -717,7 +717,7 @@ function UpdateInput() {
WriteParameter(param, "Debug", "LogfileRetentionInDays", true);
WriteParameter(param, "System", "TimeZone", true);
WriteParameter(param, "System", "TimeUpdateIntervall", true);
WriteParameter(param, "System", "TimeServer", true);
}
function WriteConfig(){
@@ -731,13 +731,13 @@ function WriteConfig(){
ReadParameter(param, "Alignment", "SearchFieldY", false);
ReadParameter(param, "Digits", "Model", false);
ReadParameter(param, "Digits", "LogImageLocation", false);
ReadParameter(param, "Digits", "LogfileRetentionInDays", false);
ReadParameter(param, "Digits", "LogImageLocation", true);
ReadParameter(param, "Digits", "LogfileRetentionInDays", true);
ReadParameter(param, "Digits", "ModelInputSize", false, false, 2);
ReadParameter(param, "Analog", "Model", false);
ReadParameter(param, "Analog", "LogImageLocation", false);
ReadParameter(param, "Analog", "LogfileRetentionInDays", false);
ReadParameter(param, "Analog", "LogImageLocation", true);
ReadParameter(param, "Analog", "LogfileRetentionInDays", true);
ReadParameter(param, "Analog", "ModelInputSize", false, false, 2);
ReadParameter(param, "PostProcessing", "DecimalShift", true);
@@ -762,7 +762,7 @@ function WriteConfig(){
ReadParameter(param, "Debug", "LogfileRetentionInDays", true);
ReadParameter(param, "System", "TimeZone", true);
ReadParameter(param, "System", "TimeUpdateIntervall", true);
ReadParameter(param, "System", "TimeServer", true);
FormatDecimalValue(param, "PostProcessing", "MaxRateValue");

View File

@@ -87,7 +87,7 @@ table {
}
function loadRawImage(){
url = basepath + "/fileserver/img_tmp/raw.jpg" + "?session=" + Math.floor((Math.random() * 1000000) + 1);
url = basepath + "/img_tmp/raw.jpg" + "?session=" + Math.floor((Math.random() * 1000000) + 1);
document.getElementById("finerotate").value = 0;
document.getElementById("prerotateangle").value = getPreRotate();
document.getElementById("mirror").checked = getMirror();

View File

@@ -7,9 +7,11 @@ function getbasepath(){
var host = window.location.hostname;
if ((host == "127.0.0.1") || (host == "localhost"))
{
host = "http://192.168.178.26"; // jomjol interner test
host = "http://192.168.2.118"; // jomjol interner test
// host = "http://192.168.178.26"; // jomjol interner test
// host = "http://192.168.178.22"; // jomjol interner Real
// host = "."; // jomjol interner localhost
}
else
{

View File

@@ -350,7 +350,7 @@ function GetReferenceSize(name){
function ZerlegeZeile(input)
{
var Output = Array(0);
delimiter = " =,";
delimiter = " =,\r";
input = trim(input, delimiter);
var pos = findDelimiterPos(input, delimiter);

View File

@@ -72,9 +72,9 @@ function ParseConfig() {
var catname = "System";
param[catname] = new Object();
ParamAddValue(param, catname, "TimeZone");
ParamAddValue(param, catname, "TimeServer");
ParamAddValue(param, catname, "AutoAdjustSummertime");
ParamAddValue(param, catname, "TimeUpdateIntervall");
ParamAddValue(param, catname, "SetupMode");
ParamAddValue(param, catname, "SetupMode");
while (aktline < config_split.length){
if (config_split[aktline].trim().toUpperCase() == "[MAKEIMAGE]") {
@@ -149,6 +149,7 @@ function ParseConfigParamSystem(_aktline){
var linesplit = ZerlegeZeile(input, " =");
ParamExtractValue(param, linesplit, catname, "TimeZone", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "TimeServer", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "AutoAdjustSummertime", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "TimeUpdateIntervall", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "SetupMode", _aktline, isCom);

View File

@@ -1 +1 @@
3.0.0
4.0.2

View File

@@ -1,4 +1,12 @@
ssid = "SSID"
password = "PASSWORD"
hostname = "watermeter"
;hostname is optional
;hostname is optional
;if you want to use a fixed IP you need to specify the following 3 parameters (ip, gateway, netmask) with IP4-Addresses "123.456.789.012"
;ip = "IP4-ADDRESS"
;gateway = "IP4-ADDRESS"
;netmask = "255.255.255.0"
;in some cases you want to specify the DNS server as well (especially, if it is not identical to the gateway - this is optional for a fixed IP
;dns = "IP4-ADDRESS"