Feature/rewrite to asyncwebserver (#11)

* Rewrite get parameters and streaming to asyncwebserver

* Code cleanup
This commit is contained in:
Zdzislaw Goik 2022-04-26 00:10:59 +02:00 committed by GitHub
parent 6bf42bd52d
commit f7c659a3bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 898 additions and 448 deletions

33
ESP/CMakeLists.txt Normal file
View File

@ -0,0 +1,33 @@
# !!! WARNING !!! AUTO-GENERATED FILE, PLEASE DO NOT MODIFY IT AND USE
# https://docs.platformio.org/page/projectconf/section_env_build.html#build-flags
#
# If you need to override existing CMake configuration or add extra,
# please create `CMakeListsUser.txt` in the root of project.
# The `CMakeListsUser.txt` will not be overwritten by PlatformIO.
cmake_minimum_required(VERSION 3.13)
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER_WORKS 1)
set(CMAKE_CXX_COMPILER_WORKS 1)
project("ESP" C CXX)
include(CMakeListsPrivate.txt)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/CMakeListsUser.txt)
include(CMakeListsUser.txt)
endif()
add_custom_target(
Production ALL
COMMAND platformio -c clion run "$<$<NOT:$<CONFIG:All>>:-e${CMAKE_BUILD_TYPE}>"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
add_custom_target(
Debug ALL
COMMAND platformio -c clion debug "$<$<NOT:$<CONFIG:All>>:-e${CMAKE_BUILD_TYPE}>"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
add_executable(Z_DUMMY_TARGET ${SRC_LIST})

155
ESP/CMakeListsPrivate.txt Normal file
View File

@ -0,0 +1,155 @@
# !!! WARNING !!! AUTO-GENERATED FILE, PLEASE DO NOT MODIFY IT AND USE
# https://docs.platformio.org/page/projectconf/section_env_build.html#build-flags
#
# If you need to override existing CMake configuration or add extra,
# please create `CMakeListsUser.txt` in the root of project.
# The `CMakeListsUser.txt` will not be overwritten by PlatformIO.
set(CMAKE_CONFIGURATION_TYPES "esp32cam" CACHE STRING "Build Types reflect PlatformIO Environments" FORCE)
# Convert "Home Directory" that may contain unescaped backslashes on Windows
file(TO_CMAKE_PATH $ENV{HOMEDRIVE}$ENV{HOMEPATH} ENV_HOME_PATH)
SET(CMAKE_C_COMPILER "${ENV_HOME_PATH}/.platformio/packages/toolchain-xtensa32/bin/xtensa-esp32-elf-gcc.exe")
SET(CMAKE_CXX_COMPILER "${ENV_HOME_PATH}/.platformio/packages/toolchain-xtensa32/bin/xtensa-esp32-elf-g++.exe")
SET(CMAKE_CXX_FLAGS "-fno-rtti -fno-exceptions -std=gnu++11 -mfix-esp32-psram-cache-issue -mfix-esp32-psram-cache-issue -g3 -Wall -nostdlib -Wpointer-arith -Wno-error=unused-but-set-variable -Wno-error=unused-variable -mlongcalls -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -Wno-error=deprecated-declarations -Wno-error=unused-function -Wno-unused-parameter -Wno-sign-compare -fstack-protector -fexceptions -Werror=reorder")
SET(CMAKE_C_FLAGS "-std=gnu99 -Wno-old-style-declaration -mfix-esp32-psram-cache-issue -mfix-esp32-psram-cache-issue -g3 -Wall -nostdlib -Wpointer-arith -Wno-error=unused-but-set-variable -Wno-error=unused-variable -mlongcalls -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -Wno-error=deprecated-declarations -Wno-error=unused-function -Wno-unused-parameter -Wno-sign-compare -fstack-protector -fexceptions -Werror=reorder")
SET(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 11)
if (CMAKE_BUILD_TYPE MATCHES "esp32cam")
add_definitions(-DPLATFORMIO=50205)
add_definitions(-DARDUINO_ESP32_DEV)
add_definitions(-DBOARD_HAS_PSRAM)
add_definitions(-DDEBUG_ESP_PORT=Serial)
add_definitions(-DDEBUG_ESP_OTA)
add_definitions(-DBOARD_HAS_PSRAM)
add_definitions(-DESP32)
add_definitions(-DESP_PLATFORM)
add_definitions(-DF_CPU=240000000L)
add_definitions(-DHAVE_CONFIG_H)
add_definitions(-DMBEDTLS_CONFIG_FILE=\"mbedtls/esp_config.h\")
add_definitions(-DARDUINO=10805)
add_definitions(-DARDUINO_ARCH_ESP32)
add_definitions(-DARDUINO_VARIANT=\"esp32\")
add_definitions(-DARDUINO_BOARD=\"AI\ Thinker\ ESP32-CAM\")
include_directories("${CMAKE_CURRENT_LIST_DIR}/include")
include_directories("${CMAKE_CURRENT_LIST_DIR}/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/ArduinoOTA/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/Update/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/ESPmDNS/src")
include_directories("${CMAKE_CURRENT_LIST_DIR}/.pio/libdeps/esp32cam/ESP Async WebServer/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/WiFi/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/FS/src")
include_directories("${CMAKE_CURRENT_LIST_DIR}/.pio/libdeps/esp32cam/AsyncTCP/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/config")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/app_trace")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/app_update")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/asio")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/bootloader_support")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/bt")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/coap")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/console")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/driver")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/efuse")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp-tls")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp32")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_adc_cal")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_event")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_http_client")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_http_server")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_https_ota")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_https_server")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_ringbuf")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_websocket_client")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/espcoredump")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/ethernet")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/expat")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/fatfs")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/freemodbus")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/freertos")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/heap")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/idf_test")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/jsmn")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/json")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/libsodium")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/log")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/lwip")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/mbedtls")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/mdns")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/micro-ecc")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/mqtt")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/newlib")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/nghttp")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/nvs_flash")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/openssl")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/protobuf-c")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/protocomm")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/pthread")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/sdmmc")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/smartconfig_ack")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/soc")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/spi_flash")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/spiffs")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/tcp_transport")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/tcpip_adapter")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/ulp")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/unity")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/vfs")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/wear_levelling")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/wifi_provisioning")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/wpa_supplicant")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/xtensa-debug-module")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp-face")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp32-camera")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/fb_gfx")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/cores/esp32")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/variants/esp32")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/AsyncUDP/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/AzureIoT/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/BLE/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/BluetoothSerial/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/DNSServer/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/EEPROM/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/ESP32/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/FFat/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/HTTPClient/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/HTTPUpdate/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/HTTPUpdateServer/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/NetBIOS/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/Preferences/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/SD/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/SD_MMC/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/SPI/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/SPIFFS/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/SimpleBLE/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/Ticker/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/WebServer/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/WiFiClientSecure/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/WiFiProv/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/framework-arduinoespressif32/libraries/Wire/src")
include_directories("${ENV_HOME_PATH}/.platformio/packages/toolchain-xtensa32/xtensa-esp32-elf/include/c++/5.2.0")
include_directories("${ENV_HOME_PATH}/.platformio/packages/toolchain-xtensa32/xtensa-esp32-elf/include/c++/5.2.0/xtensa-esp32-elf")
include_directories("${ENV_HOME_PATH}/.platformio/packages/toolchain-xtensa32/lib/gcc/xtensa-esp32-elf/5.2.0/include")
include_directories("${ENV_HOME_PATH}/.platformio/packages/toolchain-xtensa32/lib/gcc/xtensa-esp32-elf/5.2.0/include-fixed")
include_directories("${ENV_HOME_PATH}/.platformio/packages/toolchain-xtensa32/xtensa-esp32-elf/include")
include_directories("${ENV_HOME_PATH}/.platformio/packages/tool-unity")
FILE(GLOB_RECURSE EXTRA_LIB_SOURCES
${CMAKE_CURRENT_LIST_DIR}/.pio/libdeps/esp32cam/*.*
)
endif()
FILE(GLOB_RECURSE SRC_LIST
${CMAKE_CURRENT_LIST_DIR}/src/*.*
${CMAKE_CURRENT_LIST_DIR}/lib/*.*
${CMAKE_CURRENT_LIST_DIR}/test/*.*
)
list(APPEND SRC_LIST ${EXTRA_LIB_SOURCES})

View File

@ -5,9 +5,8 @@
#include "StateManager.h"
#include "LEDManager.h"
#include "cameraHandler.h"
extern char* MDSNTrackerName;
extern char *MDSNTrackerName;
extern int STREAM_SERVER_PORT;
extern int CONTROL_SERVER_PORT;
extern OpenIris::LEDManager ledManager;
extern OpenIris::StateManager stateManager;

View File

@ -1,19 +1,21 @@
#pragma once
#include <Arduino.h>
namespace OpenIris{
namespace OpenIris
{
class LEDManager{
private:
uint8_t ledPin;
class LEDManager
{
private:
uint8_t ledPin;
public:
explicit LEDManager(uint8_t pin) : ledPin(pin) {}
public:
explicit LEDManager(uint8_t pin) : ledPin(pin) {}
void setupLED() const;
void on() const;
void off() const;
void blink(unsigned int time);
void displayStatus();
};
void setupLED() const;
void on() const;
void off() const;
void blink(unsigned int time);
void displayStatus();
};
}

View File

@ -1,8 +1,10 @@
#pragma once
#include <ESPmDNS.h>
namespace OpenIris{
namespace MDNSHandler{
void setupMDNS();
}
namespace OpenIris
{
namespace MDNSHandler
{
void setupMDNS();
}
}

View File

@ -1,59 +1,65 @@
#pragma once
#include <ArduinoOTA.h>
namespace OpenIris{
class OTA {
private:
unsigned long bootTimestamp = 0;
bool isOtaEnabled = true;
public:
void SetupOTA(const char *OTAPassword, uint16_t OTAServerPort) {
Serial.println("Setting up OTA updates");
namespace OpenIris
{
class OTA
{
private:
unsigned long bootTimestamp = 0;
bool isOtaEnabled = true;
if (OTAPassword == nullptr) {
Serial.println("THE PASSWORD IS REQUIRED, [[ABORTING]]");
return;
}
ArduinoOTA.setPort(OTAServerPort);
public:
void SetupOTA(const char *OTAPassword, uint16_t OTAServerPort)
{
Serial.println("Setting up OTA updates");
ArduinoOTA
.onStart([]() {
if (OTAPassword == nullptr)
{
Serial.println("THE PASSWORD IS REQUIRED, [[ABORTING]]");
return;
}
ArduinoOTA.setPort(OTAServerPort);
ArduinoOTA
.onStart([]()
{
String type;
if (ArduinoOTA.getCommand() == U_FLASH)
type = "sketch";
else // U_SPIFFS
type = "filesystem";
})
.onEnd([]() {
Serial.println("OTA updated finished successfully!");
})
.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
})
.onError([](ota_error_t error) {
type = "filesystem"; })
.onEnd([]()
{ Serial.println("OTA updated finished successfully!"); })
.onProgress([](unsigned int progress, unsigned int total)
{ Serial.printf("Progress: %u%%\r", (progress / (total / 100))); })
.onError([](ota_error_t error)
{
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
});
Serial.println("Starting up basic OTA server");
Serial.println("OTA will be live for 30s, after which it will be disabled until restart");
ArduinoOTA.begin();
bootTimestamp = millis();
}
else if (error == OTA_END_ERROR) Serial.println("End Failed"); });
Serial.println("Starting up basic OTA server");
Serial.println("OTA will be live for 30s, after which it will be disabled until restart");
ArduinoOTA.begin();
bootTimestamp = millis();
}
void HandleOTAUpdate() {
if (isOtaEnabled) {
if (bootTimestamp + 30000 < millis()) {
// we're disabling ota after first 30sec so that nothing bad happens during playtime
isOtaEnabled = false;
Serial.println("From now on, OTA is disabled");
return;
}
ArduinoOTA.handle();
}
void HandleOTAUpdate()
{
if (isOtaEnabled)
{
if (bootTimestamp + 30000 < millis())
{
// we're disabling ota after first 30sec so that nothing bad happens during playtime
isOtaEnabled = false;
Serial.println("From now on, OTA is disabled");
return;
}
};
ArduinoOTA.handle();
}
}
};
}

View File

@ -1,24 +1,28 @@
#pragma once
namespace OpenIris{
enum State {
Starting = 1,
ConnectingToWifi = 2,
ConnectingToWifiError = 3,
ConnectingToWifiSuccess = 4,
ServerError = 5,
CameraError = 6,
MDNSSuccess = 7,
MDNSError = 8,
};
namespace OpenIris
{
enum State
{
Starting = 1,
ConnectingToWifi = 2,
ConnectingToWifiError = 3,
ConnectingToWifiSuccess = 4,
ServerError = 5,
CameraError = 6,
MDNSSuccess = 7,
MDNSError = 8,
};
class StateManager{
public:
StateManager() : current_state(Starting) {}
void setState(State state);
State getCurrentState();
private:
State current_state;
};
class StateManager
{
public:
StateManager() : current_state(Starting) {}
void setState(State state);
State getCurrentState();
private:
State current_state;
};
}

View File

@ -2,8 +2,10 @@
#include <WiFi.h>
#include "pinout.h"
namespace OpenIris {
namespace WiFiHandler {
void setupWifi(const char *ssid, const char *password);
}
namespace OpenIris
{
namespace WiFiHandler
{
void setupWifi(const char *ssid, const char *password);
}
}

View File

@ -3,12 +3,13 @@
#include "esp_camera.h"
#include <Arduino.h>
namespace OpenIris{
class CameraHandler {
namespace OpenIris
{
class CameraHandler
{
private:
sensor_t* camera_sensor;
camera_config_t config;
sensor_t *camera_sensor;
camera_config_t config;
public:
int setupCamera();

View File

@ -1,5 +1,5 @@
const char* ssid = "";
const char* password = "";
const char *ssid = "";
const char *password = "";
const char* OTAPassword = ""; // if empty, no password will be required
uint16_t OTAServerPort = 3232;
const char *OTAPassword = ""; // if empty, no password will be required
uint16_t OTAServerPort = 3232;

View File

@ -1,21 +0,0 @@
#pragma once
#define PART_BOUNDARY "123456789000000000000987654321"
#include "esp_camera.h"
#include "esp_http_server.h"
namespace OpenIris{
namespace HTTPHelpers {
esp_err_t stream_handler(httpd_req_t *req);
esp_err_t parse_get(httpd_req_t *req, char **obuf);
esp_err_t command_handler(httpd_req_t *req);
}
class HTTPDHandler{
private:
httpd_handle_t camera_httpd = nullptr;
httpd_handle_t control_httpd = nullptr;
public:
int startStreamServer();
};
}

View File

@ -0,0 +1,163 @@
#pragma once
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include "esp_camera.h"
#define PART_BOUNDARY "123456789000000000000987654321"
namespace OpenIris
{
namespace WebServerHelpers
{
static const char *STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
static const char *STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
static const char *STREAM_PART = "Content-Type: %s\r\nContent-Length: %u\r\n\r\n";
static const char *JPG_CONTENT_TYPE = "image/jpeg";
}
typedef struct
{
camera_fb_t *fb;
size_t index;
} camera_frame_t;
class AsyncJpegStreamResponse : public AsyncAbstractResponse
{
private:
camera_frame_t _frame;
size_t _index;
size_t _jpg_buf_len;
uint8_t *_jpg_buf;
long lastAsyncRequest;
public:
AsyncJpegStreamResponse()
{
_callback = nullptr;
_code = 200;
_contentLength = 0;
_contentType = OpenIris::WebServerHelpers::STREAM_CONTENT_TYPE;
_sendContentLength = false;
_chunked = true;
_index = 0;
_jpg_buf_len = 0;
_jpg_buf = NULL;
lastAsyncRequest = 0;
memset(&_frame, 0, sizeof(camera_frame_t));
}
~AsyncJpegStreamResponse()
{
if (_frame.fb)
{
if (_frame.fb->format != PIXFORMAT_JPEG)
{
free(_jpg_buf);
}
esp_camera_fb_return(_frame.fb);
}
}
bool _sourceValid() const
{
return true;
}
virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override
{
size_t ret = _content(buf, maxLen, _index);
if (ret != RESPONSE_TRY_AGAIN)
{
_index += ret;
}
return ret;
}
size_t _content(uint8_t *buffer, size_t maxLen, size_t index)
{
if (!_frame.fb || _frame.index == _jpg_buf_len)
{
if (index && _frame.fb)
{
long end = millis();
int fp = (end - lastAsyncRequest);
log_d("Size: %uKB, Time: %ums (%ifps)\n", _jpg_buf_len / 1024, fp, 1000 / fp);
lastAsyncRequest = end;
if (_frame.fb->format != PIXFORMAT_JPEG)
{
free(_jpg_buf);
}
esp_camera_fb_return(_frame.fb);
_frame.fb = NULL;
_jpg_buf_len = 0;
_jpg_buf = NULL;
}
if (maxLen < (strlen(OpenIris::WebServerHelpers::STREAM_BOUNDARY) + strlen(OpenIris::WebServerHelpers::STREAM_PART) + strlen(OpenIris::WebServerHelpers::JPG_CONTENT_TYPE) + 8))
{
// log_w("Not enough space for headers");
return RESPONSE_TRY_AGAIN;
}
// get frame
_frame.index = 0;
_frame.fb = esp_camera_fb_get();
if (_frame.fb == NULL)
{
log_e("Camera frame failed");
return 0;
}
if (_frame.fb->format != PIXFORMAT_JPEG)
{
unsigned long st = millis();
bool jpeg_converted = frame2jpg(_frame.fb, 80, &_jpg_buf, &_jpg_buf_len);
if (!jpeg_converted)
{
log_e("JPEG compression failed");
esp_camera_fb_return(_frame.fb);
_frame.fb = NULL;
_jpg_buf_len = 0;
_jpg_buf = NULL;
return 0;
}
log_i("JPEG: %lums, %uB", millis() - st, _jpg_buf_len);
}
else
{
_jpg_buf_len = _frame.fb->len;
_jpg_buf = _frame.fb->buf;
}
// send boundary
size_t blen = 0;
if (index)
{
blen = strlen(OpenIris::WebServerHelpers::STREAM_BOUNDARY);
memcpy(buffer, OpenIris::WebServerHelpers::STREAM_BOUNDARY, blen);
buffer += blen;
}
// send header
size_t hlen = sprintf((char *)buffer, OpenIris::WebServerHelpers::STREAM_PART, OpenIris::WebServerHelpers::JPG_CONTENT_TYPE, _jpg_buf_len);
buffer += hlen;
// send frame
hlen = maxLen - hlen - blen;
if (hlen > _jpg_buf_len)
{
maxLen -= hlen - _jpg_buf_len;
hlen = _jpg_buf_len;
}
memcpy(buffer, _jpg_buf, hlen);
_frame.index += hlen;
return maxLen;
}
size_t available = _jpg_buf_len - _frame.index;
if (maxLen > available)
{
maxLen = available;
}
memcpy(buffer, _jpg_buf + _frame.index, maxLen);
_frame.index += maxLen;
return maxLen;
}
};
}

View File

@ -0,0 +1,20 @@
#pragma once
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include "esp_camera.h"
namespace OpenIris
{
class HTTPDHandler
{
private:
void command_handler(AsyncWebServerRequest *request);
void stream_handler(AsyncWebServerRequest *request);
void roi_crop_command_handler(AsyncWebServerRequest *request);
AsyncWebServer *server;
public:
HTTPDHandler();
void startStreamServer();
};
}

View File

@ -15,21 +15,15 @@ framework = arduino
monitor_speed = 115200
monitor_rts = 0
monitor_dtr = 0
build_flags =
-O2
-mfix-esp32-psram-cache-issue
build_flags =
-DDEBUG_ESP_PORT=Serial
-DDEBUG_ESP_OTA
-DBOARD_HAS_PSRAM
-mfix-esp32-psram-cache-issue
build_unflags = -Os
;upload_port = 192.168.1.43 ;replace this with your own ip
;upload_protocol = espota
;upload_flags =
; --auth=Password
board_build.partitions = min_spiffs.csv
lib_ldf_mode=deep
lib_deps =
esp32-camera
me-no-dev/AsyncTCP@^1.1.1
me-no-dev/ESP Async WebServer@^1.2.3
lib_ldf_mode = deep
lib_deps =
me-no-dev/AsyncTCP@^1.1.1
me-no-dev/ESP Async WebServer@^1.2.3
esp32-camera

View File

@ -1,24 +1,27 @@
# include "LEDManager.h"
#include "LEDManager.h"
void OpenIris::LEDManager::setupLED() const {
pinMode(ledPin, OUTPUT);
void OpenIris::LEDManager::setupLED() const
{
pinMode(ledPin, OUTPUT);
}
void OpenIris::LEDManager::on() const {
digitalWrite(ledPin, LOW);
void OpenIris::LEDManager::on() const
{
digitalWrite(ledPin, LOW);
}
void OpenIris::LEDManager::off() const {
digitalWrite(ledPin, HIGH);
void OpenIris::LEDManager::off() const
{
digitalWrite(ledPin, HIGH);
}
void OpenIris::LEDManager::blink(unsigned int time) {
on();
delay(time);
off();
void OpenIris::LEDManager::blink(unsigned int time)
{
on();
delay(time);
off();
}
void OpenIris::LEDManager::displayStatus() {
void OpenIris::LEDManager::displayStatus()
{
}

View File

@ -1,15 +1,18 @@
#include "MDNSManager.h"
#include "GlobalVars.h"
void OpenIris::MDNSHandler::setupMDNS() {
if(MDNS.begin(MDSNTrackerName)){
stateManager.setState(OpenIris::State::MDNSSuccess);
MDNS.addService("openIrisTracker", "tcp", 80);
MDNS.addServiceTxt("openIrisTracker", "tcp", "stream_port", String(80));
MDNS.addServiceTxt("openIrisTracker", "tcp", "api_port", String(81));
Serial.println("MDNS initialized!");
}else{
stateManager.setState(OpenIris::State::MDNSError);
Serial.println("Error initializing MDNS");
}
void OpenIris::MDNSHandler::setupMDNS()
{
if (MDNS.begin(MDSNTrackerName))
{
stateManager.setState(OpenIris::State::MDNSSuccess);
MDNS.addService("openIrisTracker", "tcp", 80);
MDNS.addServiceTxt("openIrisTracker", "tcp", "stream_port", String(80));
Serial.println("MDNS initialized!");
}
else
{
stateManager.setState(OpenIris::State::MDNSError);
Serial.println("Error initializing MDNS");
}
}

View File

@ -1,11 +1,14 @@
#include "StateManager.h"
namespace OpenIris{
void StateManager::setState(State state){
current_state=state;
}
namespace OpenIris
{
void StateManager::setState(State state)
{
current_state = state;
}
State StateManager::getCurrentState(){
return current_state;
}
State StateManager::getCurrentState()
{
return current_state;
}
}

View File

@ -1,83 +1,98 @@
#include "cameraHandler.h"
int OpenIris::CameraHandler::setupCamera(){
Serial.print("Setting up camera \r\n");
int OpenIris::CameraHandler::setupCamera()
{
Serial.print("Setting up camera \r\n");
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
if (psramFound()){
Serial.println("Found psram, setting the 176x144 image quality");
config.frame_size = FRAMESIZE_QCIF;
config.jpeg_quality = 10;
config.fb_count = 2;
}else{
Serial.println("Did not find psram, setting svga quality");
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
if (psramFound())
{
Serial.println("Found psram, setting the 176x144 image quality");
config.frame_size = FRAMESIZE_QCIF;
config.jpeg_quality = 10;
config.fb_count = 2;
}
else
{
Serial.println("Did not find psram, setting svga quality");
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
esp_err_t err = esp_camera_init(&config);
esp_err_t err = esp_camera_init(&config);
camera_sensor = esp_camera_sensor_get();
camera_sensor->set_special_effect(camera_sensor, 2);
camera_sensor = esp_camera_sensor_get();
camera_sensor->set_special_effect(camera_sensor, 2);
if (err != ESP_OK){
Serial.printf("Camera initialization failed with error: 0x%x \r\n", err);
// TODO add led blinking here
return -1;
}else{
Serial.println("Sucessfully initialized the camera!");
// TODO add led blinking here
return 0;
}
}
int OpenIris::CameraHandler::setCameraResolution(framesize_t frameSize){
if(camera_sensor->pixformat == PIXFORMAT_JPEG){
try{
return camera_sensor->set_framesize(camera_sensor, frameSize);
}catch(...){
// they sent us a malformed or unsupported frameSize - rather than crash - tell them about it
return -1;
}
}
if (err != ESP_OK)
{
Serial.printf("Camera initialization failed with error: 0x%x \r\n", err);
// TODO add led blinking here
return -1;
}
else
{
Serial.println("Sucessfully initialized the camera!");
// TODO add led blinking here
return 0;
}
}
int OpenIris::CameraHandler::setVFlip(int direction){
return camera_sensor->set_vflip(camera_sensor, direction);
int OpenIris::CameraHandler::setCameraResolution(framesize_t frameSize)
{
if (camera_sensor->pixformat == PIXFORMAT_JPEG)
{
try
{
return camera_sensor->set_framesize(camera_sensor, frameSize);
}
catch (...)
{
// they sent us a malformed or unsupported frameSize - rather than crash - tell them about it
return -1;
}
}
return -1;
}
int OpenIris::CameraHandler::setHFlip(int direction){
return camera_sensor->set_hmirror(camera_sensor, direction);
int OpenIris::CameraHandler::setVFlip(int direction)
{
return camera_sensor->set_vflip(camera_sensor, direction);
}
int OpenIris::CameraHandler::setVieWindow(int offsetX, int offsetY, int outputX, int outputY) {
// we're only providing these parameters as these are the only ones that actually affect the ov2640
// TODO: if we're going to support different sensors - this will have to be moved to per-sensor implementation 'cause
// TODO: manufacturers handle it differently each time
int OpenIris::CameraHandler::setHFlip(int direction)
{
return camera_sensor->set_hmirror(camera_sensor, direction);
}
// we're doubling the totalX and totalY parameters to make it easier for end user to adjust the eye ROI
// it also seems to produce a cleaner image
return camera_sensor->set_res_raw(camera_sensor, 0, 0, 0, 0, offsetX, offsetY, outputX * 2, outputY * 2, outputX, outputY, true, true);
int OpenIris::CameraHandler::setVieWindow(int offsetX, int offsetY, int outputX, int outputY)
{
// we're only providing these parameters as these are the only ones that actually affect the ov2640
// TODO: if we're going to support different sensors - this will have to be moved to per-sensor implementation 'cause
// TODO: manufacturers handle it differently each time
// we're doubling the totalX and totalY parameters to make it easier for end user to adjust the eye ROI
// it also seems to produce a cleaner image
return camera_sensor->set_res_raw(camera_sensor, 0, 0, 0, 0, offsetX, offsetY, outputX * 2, outputY * 2, outputX, outputY, true, true);
}

View File

@ -1,172 +0,0 @@
#include <Arduino.h>
#include "GlobalVars.h"
#include "httpdHandler.h"
constexpr static char* STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
constexpr static char* STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
constexpr static char* STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\nX-Timestamp: %d.%06d\r\n\r\n";
esp_err_t OpenIris::HTTPHelpers::stream_handler(httpd_req_t *req) {
camera_fb_t *fb = NULL;
struct timeval _timestamp;
esp_err_t res = ESP_OK;
size_t _jpg_buf_len = 0;
uint8_t *_jpg_buf = NULL;
char *part_buf[128];
static int64_t last_frame = 0;
if (!last_frame)
last_frame = esp_timer_get_time();
res = httpd_resp_set_type(req, STREAM_CONTENT_TYPE);
if (res != ESP_OK)
return res;
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin; Content-Type: multipart/x-mixed-replace; boundary=123456789000000000000987654321\r\n", "*");
httpd_resp_set_hdr(req, "X-Framerate", "60");
while (true) {
fb = esp_camera_fb_get();
if (!fb){
ESP_LOGE(TAG, "Camera capture failed");
res = ESP_FAIL;
}
else{
_timestamp.tv_sec = fb->timestamp.tv_sec;
_timestamp.tv_usec = fb->timestamp.tv_usec;
if (fb->format != PIXFORMAT_JPEG){
bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
esp_camera_fb_return(fb);
fb = NULL;
if (!jpeg_converted){
ESP_LOGE(TAG, "JPEG compression failed");
res = ESP_FAIL;
}
}
else{
_jpg_buf_len = fb->len;
_jpg_buf = fb->buf;
}
}
if (res == ESP_OK){
res = httpd_resp_send_chunk(req, STREAM_BOUNDARY, strlen(STREAM_BOUNDARY));
}
if (res == ESP_OK){
size_t hlen = snprintf((char *)part_buf, 128, STREAM_PART, _jpg_buf_len, _timestamp.tv_sec, _timestamp.tv_usec);
res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);
}
if (res == ESP_OK){
res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);
}
if (fb){
esp_camera_fb_return(fb);
fb = NULL;
_jpg_buf = NULL;
}
else if (_jpg_buf){
free(_jpg_buf);
_jpg_buf = NULL;
}
if (res != ESP_OK){
break;
}
}
last_frame = 0;
return res;
}
esp_err_t OpenIris::HTTPHelpers::parse_get(httpd_req_t *req, char **obuf) {
char *buf = nullptr;
size_t buf_len = 0;
buf_len = httpd_req_get_url_query_len(req) + 1;
if (buf_len > 1) {
buf = (char *)malloc(buf_len);
if (!buf) {
httpd_resp_send_500(req);
return ESP_FAIL;
}
if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) {
*obuf = buf;
return ESP_OK;
}
free(buf);
}
httpd_resp_send_404(req);
return ESP_FAIL;
}
esp_err_t OpenIris::HTTPHelpers::command_handler(httpd_req_t *req) {
char *buf = nullptr;
char variable[32];
char value[32];
if (parse_get(req, &buf) != ESP_OK)
return ESP_FAIL;
if (httpd_query_key_value(buf, "var", variable, sizeof(variable)) != ESP_OK ||
httpd_query_key_value(buf, "val", value, sizeof(value)) != ESP_OK) {
free(buf);
httpd_resp_send_404(req);
return ESP_FAIL;
}
free(buf);
int val = atoi(value);
int res = 0;
if (!strcmp(variable, "framesize"))
res = cameraHandler.setCameraResolution((framesize_t)val);
else if (!strcmp(variable, "hmirror"))
res = cameraHandler.setHFlip(val);
else if (!strcmp(variable, "vflip"))
res = cameraHandler.setVFlip(val);
else
res = -1; // invalid command
if (res < 0)
return httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Command not supported");
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
return httpd_resp_send(req, nullptr, 0);
}
int OpenIris::HTTPDHandler::startStreamServer(){
Serial.println("Setting up the server");
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.max_uri_handlers = 3;
config.server_port = STREAM_SERVER_PORT;
config.ctrl_port = STREAM_SERVER_PORT;
httpd_uri_t control_page = {
.uri = "/control/",
.method = HTTP_GET,
.handler = &OpenIris::HTTPHelpers::command_handler,
.user_ctx = nullptr
};
httpd_uri_t stream_page = {
.uri = "/",
.method = HTTP_GET,
.handler = &OpenIris::HTTPHelpers::stream_handler,
.user_ctx = nullptr
};
int streamer_status = httpd_start(&control_httpd, &config);
config.server_port = CONTROL_SERVER_PORT;
config.ctrl_port = CONTROL_SERVER_PORT;
int cmd_controller_status = httpd_start(&camera_httpd, &config);
if (streamer_status != ESP_OK || cmd_controller_status != ESP_OK)
return -1;
else {
httpd_register_uri_handler(control_httpd, &control_page);
httpd_register_uri_handler(camera_httpd, &stream_page);
Serial.println("Server is ready to serve!");
return 0;
}
}

View File

@ -5,13 +5,12 @@
#include "MDNSManager.h"
#include "cameraHandler.h"
#include "LEDManager.h"
#include "httpdHandler.h"
#include "webServer/webserverHandler.h"
#include "OTA.h"
#include "StateManager.h"
char* MDSNTrackerName = "OpenIrisTracker";
char *MDSNTrackerName = "OpenIrisTracker";
int STREAM_SERVER_PORT = 80;
int CONTROL_SERVER_PORT = 81;
auto ota = OpenIris::OTA();
auto ledManager = OpenIris::LEDManager(33);
@ -19,21 +18,23 @@ auto cameraHandler = OpenIris::CameraHandler();
auto stateManager = OpenIris::StateManager();
auto httpdHandler = OpenIris::HTTPDHandler();
void setup(){
Serial.begin(115200);
Serial.setDebugOutput(true);
Serial.println();
ledManager.setupLED();
cameraHandler.setupCamera();
OpenIris::WiFiHandler::setupWifi(ssid, password);
httpdHandler.startStreamServer();
OpenIris::MDNSHandler::setupMDNS();
ledManager.on();
void setup()
{
Serial.begin(115200);
Serial.setDebugOutput(true);
Serial.println();
ledManager.setupLED();
cameraHandler.setupCamera();
OpenIris::WiFiHandler::setupWifi(ssid, password);
OpenIris::MDNSHandler::setupMDNS();
httpdHandler.startStreamServer();
ledManager.on();
ota.SetupOTA(OTAPassword, OTAServerPort);
ota.SetupOTA(OTAPassword, OTAServerPort);
}
void loop(){
ota.HandleOTAUpdate();
ledManager.displayStatus();
void loop()
{
ota.HandleOTAUpdate();
ledManager.displayStatus();
}

View File

@ -0,0 +1,94 @@
#include "GlobalVars.h"
#include "webServer/asyncJPGResponse.h"
#include "webServer/webserverHandler.h"
OpenIris::HTTPDHandler::HTTPDHandler()
{
this->server = new AsyncWebServer(STREAM_SERVER_PORT);
}
void OpenIris::HTTPDHandler::startStreamServer()
{
this->server->on(
"/",
HTTP_GET,
std::bind(&OpenIris::HTTPDHandler::stream_handler, this, std::placeholders::_1));
this->server->on(
"/control",
HTTP_GET,
std::bind(&OpenIris::HTTPDHandler::command_handler, this, std::placeholders::_1));
this->server->on(
"/crop-roi",
HTTP_GET,
std::bind(&OpenIris::HTTPDHandler::roi_crop_command_handler, this, std::placeholders::_1));
Serial.println("Initializing web server");
this->server->begin();
}
void OpenIris::HTTPDHandler::roi_crop_command_handler(AsyncWebServerRequest *request)
{
int offsetX = 0;
int offsetY = 0;
int outputX = 0;
int outputY = 0;
if (request->hasParam("offsetX"))
{
AsyncWebParameter *offsetX_param = request->getParam("offsetX");
offsetX = atoi(offsetX_param->value().c_str());
}
if (request->hasParam("offsetY"))
{
AsyncWebParameter *offsetY_param = request->getParam("offsetY");
offsetY = atoi(offsetY_param->value().c_str());
}
if (request->hasParam("outputX"))
{
AsyncWebParameter *outputX_param = request->getParam("outputX");
outputX = atoi(outputX_param->value().c_str());
}
if (request->hasParam("outputY"))
{
AsyncWebParameter *outputY_param = request->getParam("outputY");
outputY = atoi(outputY_param->value().c_str());
}
if (offsetX != 0 && offsetY != 0 && outputX != 0 && outputY != 0)
cameraHandler.setVieWindow(offsetX, offsetY, outputX, outputY);
request->send(200);
}
void OpenIris::HTTPDHandler::command_handler(AsyncWebServerRequest *request)
{
if (request->hasParam("framesize"))
{
AsyncWebParameter *framesize_param = request->getParam("framesize");
cameraHandler.setCameraResolution((framesize_t)atoi(framesize_param->value().c_str()));
}
if (request->hasParam("hmirror"))
{
AsyncWebParameter *hmirror_param = request->getParam("hmirror");
cameraHandler.setHFlip(atoi(hmirror_param->value().c_str()));
}
if (request->hasParam("vflip"))
{
AsyncWebParameter *vflip_param = request->getParam("vflip");
cameraHandler.setVFlip(atoi(vflip_param->value().c_str()));
}
request->send(200);
}
void OpenIris::HTTPDHandler::stream_handler(AsyncWebServerRequest *request)
{
OpenIris::AsyncJpegStreamResponse *response = new OpenIris::AsyncJpegStreamResponse();
if (!response)
{
request->send(501);
return;
}
response->addHeader("Access-Control-Allow-Origin", "*");
request->send(response);
}

View File

@ -1,37 +1,41 @@
#include "WifiHandler.h"
#include "WifiHandler.h"
#include "GlobalVars.h"
void OpenIris::WiFiHandler::setupWifi(const char* ssid, const char* password){
Serial.println("Initializing connection to wifi");
void OpenIris::WiFiHandler::setupWifi(const char *ssid, const char *password)
{
Serial.println("Initializing connection to wifi");
WiFi.begin(ssid, password);
WiFi.begin(ssid, password);
Serial.print("connecting");
int time_spent_connecting = 0;
int connection_timeout = 6400;
int wifi_status = WiFi.status();
Serial.print("connecting");
int time_spent_connecting = 0;
int connection_timeout = 6400;
int wifi_status = WiFi.status();
while (time_spent_connecting < connection_timeout || wifi_status != WL_CONNECTED){
wifi_status = WiFi.status();
Serial.print(".");
stateManager.setState(OpenIris::State::ConnectingToWifi);
time_spent_connecting += 1600;
delay(1600);
}
while (time_spent_connecting < connection_timeout || wifi_status != WL_CONNECTED)
{
wifi_status = WiFi.status();
Serial.print(".");
stateManager.setState(OpenIris::State::ConnectingToWifi);
time_spent_connecting += 1600;
delay(1600);
}
if(wifi_status == WL_CONNECTED){
stateManager.setState(OpenIris::State::ConnectingToWifiSuccess);
delay(1600);
Serial.print("\n\rWiFi connected\n\r");
Serial.print("ESP will be streaming under 'http://");
Serial.print(WiFi.localIP());
Serial.print(":81/\r\n");
Serial.print("ESP will be accepting commands under 'http://");
Serial.print(WiFi.localIP());
Serial.print(":80/control\r\n");
}
else{
stateManager.setState(OpenIris::State::ConnectingToWifiError);
return;
}
if (wifi_status == WL_CONNECTED)
{
stateManager.setState(OpenIris::State::ConnectingToWifiSuccess);
delay(1600);
Serial.print("\n\rWiFi connected\n\r");
Serial.print("ESP will be streaming under 'http://");
Serial.print(WiFi.localIP());
Serial.print(":80/\r\n");
Serial.print("ESP will be accepting commands under 'http://");
Serial.print(WiFi.localIP());
Serial.print(":80/control\r\n");
}
else
{
stateManager.setState(OpenIris::State::ConnectingToWifiError);
return;
}
}

View File

@ -1,3 +1,44 @@
[[package]]
name = "black"
version = "22.3.0"
description = "The uncompromising code formatter."
category = "main"
optional = false
python-versions = ">=3.6.2"
[package.dependencies]
click = ">=8.0.0"
mypy-extensions = ">=0.4.3"
pathspec = ">=0.9.0"
platformdirs = ">=2"
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}
[package.extras]
colorama = ["colorama (>=0.4.3)"]
d = ["aiohttp (>=3.7.4)"]
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
uvloop = ["uvloop (>=0.15.2)"]
[[package]]
name = "click"
version = "8.1.2"
description = "Composable command line interface toolkit"
category = "main"
optional = false
python-versions = ">=3.7"
[package.dependencies]
colorama = {version = "*", markers = "platform_system == \"Windows\""}
[[package]]
name = "colorama"
version = "0.4.4"
description = "Cross-platform colored terminal text."
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]]
name = "ifaddr"
version = "0.1.7"
@ -6,6 +47,50 @@ category = "main"
optional = false
python-versions = "*"
[[package]]
name = "mypy-extensions"
version = "0.4.3"
description = "Experimental type system extensions for programs checked with the mypy typechecker."
category = "main"
optional = false
python-versions = "*"
[[package]]
name = "pathspec"
version = "0.9.0"
description = "Utility library for gitignore style pattern matching of file paths."
category = "main"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
[[package]]
name = "platformdirs"
version = "2.5.1"
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
category = "main"
optional = false
python-versions = ">=3.7"
[package.extras]
docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"]
test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"]
[[package]]
name = "tomli"
version = "2.0.1"
description = "A lil' TOML parser"
category = "main"
optional = false
python-versions = ">=3.7"
[[package]]
name = "typing-extensions"
version = "4.1.1"
description = "Backported and Experimental Type Hints for Python 3.6+"
category = "main"
optional = false
python-versions = ">=3.6"
[[package]]
name = "zeroconf"
version = "0.38.4"
@ -20,13 +105,66 @@ ifaddr = ">=0.1.7"
[metadata]
lock-version = "1.1"
python-versions = "^3.8"
content-hash = "944b5c3bc6e6b85421323bd76ae236e8fcd4a11a69220aff396ec91a557f7ba0"
content-hash = "330842ad1695c7c65610e653d11042bef1f3ae1b89884d9091e84c69b58bad3c"
[metadata.files]
black = [
{file = "black-22.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09"},
{file = "black-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb"},
{file = "black-22.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a"},
{file = "black-22.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968"},
{file = "black-22.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d"},
{file = "black-22.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce"},
{file = "black-22.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82"},
{file = "black-22.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b"},
{file = "black-22.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015"},
{file = "black-22.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b"},
{file = "black-22.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a"},
{file = "black-22.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163"},
{file = "black-22.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464"},
{file = "black-22.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0"},
{file = "black-22.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176"},
{file = "black-22.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0"},
{file = "black-22.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20"},
{file = "black-22.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a"},
{file = "black-22.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad"},
{file = "black-22.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21"},
{file = "black-22.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265"},
{file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"},
{file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"},
]
click = [
{file = "click-8.1.2-py3-none-any.whl", hash = "sha256:24e1a4a9ec5bf6299411369b208c1df2188d9eb8d916302fe6bf03faed227f1e"},
{file = "click-8.1.2.tar.gz", hash = "sha256:479707fe14d9ec9a0757618b7a100a0ae4c4e236fac5b7f80ca68028141a1a72"},
]
colorama = [
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
]
ifaddr = [
{file = "ifaddr-0.1.7-py2.py3-none-any.whl", hash = "sha256:d1f603952f0a71c9ab4e705754511e4e03b02565bc4cec7188ad6415ff534cd3"},
{file = "ifaddr-0.1.7.tar.gz", hash = "sha256:1f9e8a6ca6f16db5a37d3356f07b6e52344f6f9f7e806d618537731669eb1a94"},
]
mypy-extensions = [
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
]
pathspec = [
{file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"},
{file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
]
platformdirs = [
{file = "platformdirs-2.5.1-py3-none-any.whl", hash = "sha256:bcae7cab893c2d310a711b70b24efb93334febe65f8de776ee320b517471e227"},
{file = "platformdirs-2.5.1.tar.gz", hash = "sha256:7535e70dfa32e84d4b34996ea99c5e432fa29a708d0f4e394bbcb2a8faa4f16d"},
]
tomli = [
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
]
typing-extensions = [
{file = "typing_extensions-4.1.1-py3-none-any.whl", hash = "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2"},
{file = "typing_extensions-4.1.1.tar.gz", hash = "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42"},
]
zeroconf = [
{file = "zeroconf-0.38.4-py3-none-any.whl", hash = "sha256:f5dd86d12d06d1eec9fad05778d3c5787c2bcc03df4de4728b938df6bff70129"},
{file = "zeroconf-0.38.4.tar.gz", hash = "sha256:080c540ea4b8b9defa9f3ac05823c1725ea2c8aacda917bfc0193f6758b95aeb"},

View File

@ -8,6 +8,7 @@ license = "gnu gplv3"
[tool.poetry.dependencies]
python = "^3.8"
zeroconf = "^0.38.4"
black = "^22.3.0"
[tool.poetry.dev-dependencies]