🚀 Builds with new ESP32-Sveltekit template
This commit is contained in:
Vendored
+566
@@ -0,0 +1,566 @@
|
||||
//
|
||||
// !!! WARNING !!! AUTO-GENERATED FILE!
|
||||
// PLEASE DO NOT MODIFY IT AND USE "platformio.ini":
|
||||
// https://docs.platformio.org/page/projectconf/section_env_build.html#build-flags
|
||||
//
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "PlatformIO",
|
||||
"includePath": [
|
||||
"C:/data/repos/Hardware/Spot Micro - Leika/esp32/include",
|
||||
"C:/data/repos/Hardware/Spot Micro - Leika/esp32/src",
|
||||
"C:/data/repos/Hardware/Spot Micro - Leika/esp32/lib/ESP32-sveltekit",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/LittleFS/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/HTTPUpdate/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/Update/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/HTTPClient/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/DNSServer/src",
|
||||
"C:/data/repos/Hardware/Spot Micro - Leika/esp32/lib/PsychicHttp/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/FS/src",
|
||||
"C:/data/repos/Hardware/Spot Micro - Leika/esp32/.pio/libdeps/esp32dev/UrlEncode/src",
|
||||
"C:/data/repos/Hardware/Spot Micro - Leika/esp32/.pio/libdeps/esp32dev/ArduinoTrace",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/ESPmDNS/src",
|
||||
"C:/data/repos/Hardware/Spot Micro - Leika/esp32/.pio/libdeps/esp32dev/PsychicMqttClient/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/WiFiClientSecure/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/WiFi/src",
|
||||
"C:/data/repos/Hardware/Spot Micro - Leika/esp32/.pio/libdeps/esp32dev/ArduinoJson/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/newlib/platform_include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/esp_additions/freertos",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/port/xtensa/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/esp_additions",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/soc",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/soc/esp32",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/port/esp32",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/port/esp32/private_include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/heap/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/log/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/lwip/include/apps",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/lwip/include/apps/sntp",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/lwip/lwip/src/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/lwip/port/esp32/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/lwip/port/esp32/include/arch",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/esp32",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/esp32/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/esp32/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/platform_port/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_rom/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_rom/include/esp32",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_rom/esp32",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_common/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_system/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_system/port/soc",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_system/port/public_compat",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp32/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/esp32/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/driver/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/driver/esp32/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_pm/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_ringbuf/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/efuse/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/efuse/esp32/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/vfs/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_wifi/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_event/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_netif/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_eth/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/tcpip_adapter/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_phy/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_phy/esp32/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_ipc/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/app_trace/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_timer/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/mbedtls/port/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/mbedtls/mbedtls/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/mbedtls/esp_crt_bundle/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/app_update/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/spi_flash/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bootloader_support/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/nvs_flash/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/pthread/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_gdbstub/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_gdbstub/xtensa",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_gdbstub/esp32",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espcoredump/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espcoredump/include/port/xtensa",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/wpa_supplicant/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/wpa_supplicant/port/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/wpa_supplicant/esp_supplicant/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/ieee802154/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/console",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/asio/asio/asio/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/asio/port/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/common/osi/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/include/esp32/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/common/api/include/api",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/common/btc/profile/esp/blufi/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/common/btc/profile/esp/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/host/bluedroid/api/include/api",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_common/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_common/tinycrypt/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_core",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_core/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_core/storage",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/btc/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_models/common/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_models/client/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_models/server/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/api/core/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/api/models/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/api",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/cbor/port/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/unity/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/unity/unity/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/cmock/CMock/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/coap/port/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/coap/libcoap/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/nghttp/port/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/nghttp/nghttp2/lib/includes",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-tls",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-tls/esp-tls-crypto",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_adc_cal/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hid/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/tcp_transport/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_http_client/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_http_server/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_https_ota/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_https_server/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_lcd/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_lcd/interface",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/protobuf-c/protobuf-c",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/protocomm/include/common",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/protocomm/include/security",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/protocomm/include/transports",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/mdns/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_local_ctrl/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/sdmmc/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_serial_slave_link/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_websocket_client/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/expat/expat/expat/lib",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/expat/port/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/wear_levelling/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/fatfs/diskio",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/fatfs/vfs",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/fatfs/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freemodbus/freemodbus/common/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/idf_test/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/idf_test/include/esp32",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/jsmn/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/json/cJSON",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/libsodium/libsodium/src/libsodium/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/libsodium/port_include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/mqtt/esp-mqtt/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/openssl/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/perfmon/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/spiffs/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/ulp/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/wifi_provisioning/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/rmaker_common/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_diagnostics/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/rtc_store/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_insights/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/json_parser/upstream/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/json_parser/upstream",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/json_generator/upstream",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_schedule/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp_secure_cert_mgr/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_rainmaker/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/gpio_button/button/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/qrcode/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/ws2812_led",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_littlefs/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/tool",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/typedef",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/image",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/math",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/nn",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/layer",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/detect",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/model_zoo",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-sr/src/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-sr/esp-tts/esp_tts_chinese/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-sr/include/esp32",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp32-camera/driver/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp32-camera/conversions/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/dotprod/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/support/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/windows/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/windows/hann/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/windows/blackman/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/windows/blackman_harris/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/windows/blackman_nuttall/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/windows/nuttall/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/windows/flat_top/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/iir/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/fir/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/math/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/math/add/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/math/sub/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/math/mul/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/math/addc/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/math/mulc/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/math/sqrt/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/matrix/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/fft/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/dct/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/conv/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/common/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/kalman/ekf/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/kalman/ekf_imu13states/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/fb_gfx/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/dio_qspi/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/cores/esp32",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/variants/esp32",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/ArduinoOTA/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/AsyncUDP/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/BLE/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/BluetoothSerial/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/EEPROM/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/ESP32/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/Ethernet/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/FFat/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/HTTPUpdateServer/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/I2S/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/Insights/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/NetBIOS/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/Preferences/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/RainMaker/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/SD/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/SD_MMC/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/SPI/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/SPIFFS/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/SimpleBLE/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/Ticker/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/USB/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/WebServer/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/WiFiProv/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/Wire/src",
|
||||
""
|
||||
],
|
||||
"browse": {
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"path": [
|
||||
"C:/data/repos/Hardware/Spot Micro - Leika/esp32/include",
|
||||
"C:/data/repos/Hardware/Spot Micro - Leika/esp32/src",
|
||||
"C:/data/repos/Hardware/Spot Micro - Leika/esp32/lib/ESP32-sveltekit",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/LittleFS/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/HTTPUpdate/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/Update/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/HTTPClient/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/DNSServer/src",
|
||||
"C:/data/repos/Hardware/Spot Micro - Leika/esp32/lib/PsychicHttp/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/FS/src",
|
||||
"C:/data/repos/Hardware/Spot Micro - Leika/esp32/.pio/libdeps/esp32dev/UrlEncode/src",
|
||||
"C:/data/repos/Hardware/Spot Micro - Leika/esp32/.pio/libdeps/esp32dev/ArduinoTrace",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/ESPmDNS/src",
|
||||
"C:/data/repos/Hardware/Spot Micro - Leika/esp32/.pio/libdeps/esp32dev/PsychicMqttClient/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/WiFiClientSecure/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/WiFi/src",
|
||||
"C:/data/repos/Hardware/Spot Micro - Leika/esp32/.pio/libdeps/esp32dev/ArduinoJson/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/newlib/platform_include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/esp_additions/freertos",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/port/xtensa/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/esp_additions",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/soc",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/soc/esp32",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/port/esp32",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/port/esp32/private_include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/heap/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/log/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/lwip/include/apps",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/lwip/include/apps/sntp",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/lwip/lwip/src/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/lwip/port/esp32/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/lwip/port/esp32/include/arch",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/esp32",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/esp32/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/esp32/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/platform_port/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_rom/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_rom/include/esp32",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_rom/esp32",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_common/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_system/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_system/port/soc",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_system/port/public_compat",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp32/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/esp32/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/driver/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/driver/esp32/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_pm/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_ringbuf/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/efuse/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/efuse/esp32/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/vfs/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_wifi/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_event/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_netif/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_eth/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/tcpip_adapter/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_phy/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_phy/esp32/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_ipc/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/app_trace/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_timer/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/mbedtls/port/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/mbedtls/mbedtls/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/mbedtls/esp_crt_bundle/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/app_update/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/spi_flash/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bootloader_support/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/nvs_flash/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/pthread/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_gdbstub/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_gdbstub/xtensa",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_gdbstub/esp32",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espcoredump/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espcoredump/include/port/xtensa",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/wpa_supplicant/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/wpa_supplicant/port/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/wpa_supplicant/esp_supplicant/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/ieee802154/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/console",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/asio/asio/asio/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/asio/port/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/common/osi/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/include/esp32/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/common/api/include/api",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/common/btc/profile/esp/blufi/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/common/btc/profile/esp/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/host/bluedroid/api/include/api",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_common/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_common/tinycrypt/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_core",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_core/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_core/storage",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/btc/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_models/common/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_models/client/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_models/server/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/api/core/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/api/models/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/api",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/cbor/port/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/unity/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/unity/unity/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/cmock/CMock/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/coap/port/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/coap/libcoap/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/nghttp/port/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/nghttp/nghttp2/lib/includes",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-tls",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-tls/esp-tls-crypto",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_adc_cal/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hid/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/tcp_transport/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_http_client/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_http_server/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_https_ota/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_https_server/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_lcd/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_lcd/interface",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/protobuf-c/protobuf-c",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/protocomm/include/common",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/protocomm/include/security",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/protocomm/include/transports",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/mdns/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_local_ctrl/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/sdmmc/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_serial_slave_link/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_websocket_client/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/expat/expat/expat/lib",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/expat/port/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/wear_levelling/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/fatfs/diskio",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/fatfs/vfs",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/fatfs/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freemodbus/freemodbus/common/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/idf_test/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/idf_test/include/esp32",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/jsmn/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/json/cJSON",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/libsodium/libsodium/src/libsodium/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/libsodium/port_include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/mqtt/esp-mqtt/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/openssl/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/perfmon/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/spiffs/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/ulp/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/wifi_provisioning/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/rmaker_common/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_diagnostics/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/rtc_store/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_insights/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/json_parser/upstream/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/json_parser/upstream",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/json_generator/upstream",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_schedule/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp_secure_cert_mgr/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_rainmaker/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/gpio_button/button/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/qrcode/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/ws2812_led",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_littlefs/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/tool",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/typedef",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/image",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/math",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/nn",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/layer",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/detect",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/model_zoo",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-sr/src/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-sr/esp-tts/esp_tts_chinese/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-sr/include/esp32",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp32-camera/driver/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp32-camera/conversions/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/dotprod/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/support/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/windows/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/windows/hann/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/windows/blackman/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/windows/blackman_harris/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/windows/blackman_nuttall/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/windows/nuttall/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/windows/flat_top/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/iir/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/fir/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/math/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/math/add/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/math/sub/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/math/mul/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/math/addc/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/math/mulc/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/math/sqrt/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/matrix/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/fft/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/dct/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/conv/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/common/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/kalman/ekf/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espressif__esp-dsp/modules/kalman/ekf_imu13states/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/fb_gfx/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/dio_qspi/include",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/cores/esp32",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/variants/esp32",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/ArduinoOTA/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/AsyncUDP/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/BLE/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/BluetoothSerial/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/EEPROM/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/ESP32/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/Ethernet/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/FFat/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/HTTPUpdateServer/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/I2S/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/Insights/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/NetBIOS/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/Preferences/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/RainMaker/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/SD/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/SD_MMC/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/SPI/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/SPIFFS/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/SimpleBLE/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/Ticker/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/USB/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/WebServer/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/WiFiProv/src",
|
||||
"C:/Users/Rune/.platformio/packages/framework-arduinoespressif32/libraries/Wire/src",
|
||||
""
|
||||
]
|
||||
},
|
||||
"defines": [
|
||||
"PLATFORMIO=60114",
|
||||
"ARDUINO_ESP32_DEV",
|
||||
"APP_NAME=\"Spot-Micro\"",
|
||||
"APP_VERSION=\"0.0.1\"",
|
||||
"FACTORY_WIFI_SSID=\"\"",
|
||||
"FACTORY_WIFI_PASSWORD=\"\"",
|
||||
"FACTORY_WIFI_HOSTNAME=\"#{platform}-#{unique_id}\"",
|
||||
"FACTORY_AP_PROVISION_MODE=AP_MODE_DISCONNECTED",
|
||||
"FACTORY_AP_SSID=\"Spot-Micro-#{unique_id}\"",
|
||||
"FACTORY_AP_PASSWORD=\"esp-react\"",
|
||||
"FACTORY_AP_CHANNEL=1",
|
||||
"FACTORY_AP_SSID_HIDDEN=false",
|
||||
"FACTORY_AP_MAX_CLIENTS=4",
|
||||
"FACTORY_AP_LOCAL_IP=\"192.168.4.1\"",
|
||||
"FACTORY_AP_GATEWAY_IP=\"192.168.4.1\"",
|
||||
"FACTORY_AP_SUBNET_MASK=\"255.255.255.0\"",
|
||||
"FACTORY_ADMIN_USERNAME=\"admin\"",
|
||||
"FACTORY_ADMIN_PASSWORD=\"admin\"",
|
||||
"FACTORY_GUEST_USERNAME=\"guest\"",
|
||||
"FACTORY_GUEST_PASSWORD=\"guest\"",
|
||||
"FACTORY_NTP_ENABLED=true",
|
||||
"FACTORY_NTP_TIME_ZONE_LABEL=\"Europe/London\"",
|
||||
"FACTORY_NTP_TIME_ZONE_FORMAT=\"GMT0BST,M3.5.0/1,M10.5.0\"",
|
||||
"FACTORY_NTP_SERVER=\"time.google.com\"",
|
||||
"FACTORY_OTA_PORT=8266",
|
||||
"FACTORY_OTA_PASSWORD=\"spot-leika\"",
|
||||
"FACTORY_OTA_ENABLED=true",
|
||||
"FACTORY_MQTT_ENABLED=false",
|
||||
"FACTORY_MQTT_URI=\"test.mosquitto.org\"",
|
||||
"FACTORY_MQTT_PORT=1883",
|
||||
"FACTORY_MQTT_USERNAME=\"\"",
|
||||
"FACTORY_MQTT_PASSWORD=\"\"",
|
||||
"FACTORY_MQTT_CLIENT_ID=\"#{platform}-#{unique_id}\"",
|
||||
"FACTORY_MQTT_KEEP_ALIVE=60",
|
||||
"FACTORY_MQTT_CLEAN_SESSION=true",
|
||||
"FACTORY_MQTT_MAX_TOPIC_LENGTH=128",
|
||||
"FACTORY_JWT_SECRET=\"#{random}-#{random}\"",
|
||||
"USE_BATTERY=1",
|
||||
"USE_NTP=1",
|
||||
"USE_SECURITY=1",
|
||||
"USE_UPLOAD_FIRMWARE=1",
|
||||
"USE_DOWNLOAD_FIRMWARE=1",
|
||||
"USE_ANALYTICS=1",
|
||||
"BUILD_TARGET=\"esp32dev\"",
|
||||
"ESP32SVELTEKIT_RUNNING_CORE=0",
|
||||
"EMBED_WWW",
|
||||
"ENABLE_CORS",
|
||||
"SERIAL_INFO",
|
||||
"CORS_ORIGIN=\"*\"",
|
||||
"CORE_DEBUG_LEVEL=5",
|
||||
"register=",
|
||||
"LED_BUILTIN=2",
|
||||
"KEY_BUILTIN=0",
|
||||
"HAVE_CONFIG_H",
|
||||
"MBEDTLS_CONFIG_FILE=\"mbedtls/esp_config.h\"",
|
||||
"UNITY_INCLUDE_CONFIG_H",
|
||||
"WITH_POSIX",
|
||||
"_GNU_SOURCE",
|
||||
"IDF_VER=\"v4.4.4\"",
|
||||
"ESP_PLATFORM",
|
||||
"_POSIX_READER_WRITER_LOCKS",
|
||||
"ARDUINO_ARCH_ESP32",
|
||||
"ESP32",
|
||||
"F_CPU=240000000L",
|
||||
"ARDUINO=10812",
|
||||
"ARDUINO_VARIANT=\"esp32\"",
|
||||
"ARDUINO_BOARD=\"Espressif ESP32 Dev Module\"",
|
||||
"ARDUINO_PARTITION_min_spiffs",
|
||||
""
|
||||
],
|
||||
"cStandard": "gnu99",
|
||||
"cppStandard": "gnu++17",
|
||||
"compilerPath": "C:/Users/Rune/.platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-gcc.exe",
|
||||
"compilerArgs": [
|
||||
"-mlongcalls",
|
||||
""
|
||||
]
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
||||
Vendored
+44
@@ -0,0 +1,44 @@
|
||||
// AUTOMATICALLY GENERATED FILE. PLEASE DO NOT MODIFY IT MANUALLY
|
||||
//
|
||||
// PlatformIO Debugging Solution
|
||||
//
|
||||
// Documentation: https://docs.platformio.org/en/latest/plus/debugging.html
|
||||
// Configuration: https://docs.platformio.org/en/latest/projectconf/sections/env/options/debug/index.html
|
||||
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "platformio-debug",
|
||||
"request": "launch",
|
||||
"name": "PIO Debug",
|
||||
"executable": "C:/data/repos/Hardware/Spot Micro - Leika/esp32/.pio/build/esp32dev/firmware.elf",
|
||||
"projectEnvName": "esp32dev",
|
||||
"toolchainBinDir": "C:/Users/Rune/.platformio/packages/toolchain-xtensa-esp32/bin",
|
||||
"internalConsoleOptions": "openOnSessionStart",
|
||||
"preLaunchTask": {
|
||||
"type": "PlatformIO",
|
||||
"task": "Pre-Debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "platformio-debug",
|
||||
"request": "launch",
|
||||
"name": "PIO Debug (skip Pre-Debug)",
|
||||
"executable": "C:/data/repos/Hardware/Spot Micro - Leika/esp32/.pio/build/esp32dev/firmware.elf",
|
||||
"projectEnvName": "esp32dev",
|
||||
"toolchainBinDir": "C:/Users/Rune/.platformio/packages/toolchain-xtensa-esp32/bin",
|
||||
"internalConsoleOptions": "openOnSessionStart"
|
||||
},
|
||||
{
|
||||
"type": "platformio-debug",
|
||||
"request": "launch",
|
||||
"name": "PIO Debug (without uploading)",
|
||||
"executable": "C:/data/repos/Hardware/Spot Micro - Leika/esp32/.pio/build/esp32dev/firmware.elf",
|
||||
"projectEnvName": "esp32dev",
|
||||
"toolchainBinDir": "C:/Users/Rune/.platformio/packages/toolchain-xtensa-esp32/bin",
|
||||
"internalConsoleOptions": "openOnSessionStart",
|
||||
"loadMode": "manual"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
[build_settings]
|
||||
build_flags =
|
||||
-D BUILD_TARGET=\"$PIOENV\"
|
||||
-D ESP32SVELTEKIT_RUNNING_CORE=0
|
||||
-D EMBED_WWW
|
||||
-D ENABLE_CORS
|
||||
-D SERIAL_INFO
|
||||
-D CORS_ORIGIN=\"*\"
|
||||
+43
-40
@@ -6,49 +6,52 @@
|
||||
|
||||
[factory_settings]
|
||||
build_flags =
|
||||
; WiFi settings
|
||||
-D FACTORY_WIFI_SSID=\"\"
|
||||
-D FACTORY_WIFI_PASSWORD=\"\"
|
||||
-D FACTORY_WIFI_HOSTNAME=\"#{platform}-#{unique_id}\" ; supports placeholders
|
||||
-D APP_NAME=\"Spot-Micro\" ; [a-zA-Z0-9-_]
|
||||
-D APP_VERSION=\"0.0.1\"
|
||||
|
||||
; Access point settings
|
||||
-D FACTORY_AP_PROVISION_MODE=AP_MODE_DISCONNECTED
|
||||
-D FACTORY_AP_SSID=\"ESP8266-React-#{unique_id}\" ; 1-64 characters, supports placeholders
|
||||
-D FACTORY_AP_PASSWORD=\"esp-react\" ; 8-64 characters
|
||||
-D FACTORY_AP_CHANNEL=1
|
||||
-D FACTORY_AP_SSID_HIDDEN=false
|
||||
-D FACTORY_AP_MAX_CLIENTS=4
|
||||
-D FACTORY_AP_LOCAL_IP=\"192.168.4.1\"
|
||||
-D FACTORY_AP_GATEWAY_IP=\"192.168.4.1\"
|
||||
-D FACTORY_AP_SUBNET_MASK=\"255.255.255.0\"
|
||||
; WiFi settings
|
||||
-D FACTORY_WIFI_SSID=\"\"
|
||||
-D FACTORY_WIFI_PASSWORD=\"\"
|
||||
-D FACTORY_WIFI_HOSTNAME=\"#{platform}-#{unique_id}\" ; supports placeholders
|
||||
|
||||
; User credentials for admin and guest user
|
||||
-D FACTORY_ADMIN_USERNAME=\"admin\"
|
||||
-D FACTORY_ADMIN_PASSWORD=\"admin\"
|
||||
-D FACTORY_GUEST_USERNAME=\"guest\"
|
||||
-D FACTORY_GUEST_PASSWORD=\"guest\"
|
||||
; Access point settings
|
||||
-D FACTORY_AP_PROVISION_MODE=AP_MODE_DISCONNECTED
|
||||
-D FACTORY_AP_SSID=\"Spot-Micro-#{unique_id}\" ; 1-64 characters, supports placeholders
|
||||
-D FACTORY_AP_PASSWORD=\"esp-react\" ; 8-64 characters
|
||||
-D FACTORY_AP_CHANNEL=1
|
||||
-D FACTORY_AP_SSID_HIDDEN=false
|
||||
-D FACTORY_AP_MAX_CLIENTS=4
|
||||
-D FACTORY_AP_LOCAL_IP=\"192.168.4.1\"
|
||||
-D FACTORY_AP_GATEWAY_IP=\"192.168.4.1\"
|
||||
-D FACTORY_AP_SUBNET_MASK=\"255.255.255.0\"
|
||||
|
||||
; NTP settings
|
||||
-D FACTORY_NTP_ENABLED=true
|
||||
-D FACTORY_NTP_TIME_ZONE_LABEL=\"Europe/London\"
|
||||
-D FACTORY_NTP_TIME_ZONE_FORMAT=\"GMT0BST,M3.5.0/1,M10.5.0\"
|
||||
-D FACTORY_NTP_SERVER=\"time.google.com\"
|
||||
; User credentials for admin and guest user
|
||||
-D FACTORY_ADMIN_USERNAME=\"admin\"
|
||||
-D FACTORY_ADMIN_PASSWORD=\"admin\"
|
||||
-D FACTORY_GUEST_USERNAME=\"guest\"
|
||||
-D FACTORY_GUEST_PASSWORD=\"guest\"
|
||||
|
||||
; OTA settings
|
||||
-D FACTORY_OTA_PORT=8266
|
||||
-D FACTORY_OTA_PASSWORD=\"esp-react\"
|
||||
-D FACTORY_OTA_ENABLED=true
|
||||
; NTP settings
|
||||
-D FACTORY_NTP_ENABLED=true
|
||||
-D FACTORY_NTP_TIME_ZONE_LABEL=\"Europe/London\"
|
||||
-D FACTORY_NTP_TIME_ZONE_FORMAT=\"GMT0BST,M3.5.0/1,M10.5.0\"
|
||||
-D FACTORY_NTP_SERVER=\"time.google.com\"
|
||||
|
||||
; MQTT settings
|
||||
-D FACTORY_MQTT_ENABLED=false
|
||||
-D FACTORY_MQTT_HOST=\"test.mosquitto.org\"
|
||||
-D FACTORY_MQTT_PORT=1883
|
||||
-D FACTORY_MQTT_USERNAME=\"\" ; supports placeholders
|
||||
-D FACTORY_MQTT_PASSWORD=\"\"
|
||||
-D FACTORY_MQTT_CLIENT_ID=\"#{platform}-#{unique_id}\" ; supports placeholders
|
||||
-D FACTORY_MQTT_KEEP_ALIVE=60
|
||||
-D FACTORY_MQTT_CLEAN_SESSION=true
|
||||
-D FACTORY_MQTT_MAX_TOPIC_LENGTH=128
|
||||
; OTA settings
|
||||
-D FACTORY_OTA_PORT=8266
|
||||
-D FACTORY_OTA_PASSWORD=\"spot-leika\"
|
||||
-D FACTORY_OTA_ENABLED=true
|
||||
|
||||
; JWT Secret
|
||||
-D FACTORY_JWT_SECRET=\"#{random}-#{random}\" ; supports placeholders
|
||||
; MQTT settings
|
||||
-D FACTORY_MQTT_ENABLED=false
|
||||
-D FACTORY_MQTT_URI=\"test.mosquitto.org\"
|
||||
-D FACTORY_MQTT_PORT=1883
|
||||
-D FACTORY_MQTT_USERNAME=\"\" ; supports placeholders
|
||||
-D FACTORY_MQTT_PASSWORD=\"\"
|
||||
-D FACTORY_MQTT_CLIENT_ID=\"#{platform}-#{unique_id}\" ; supports placeholders
|
||||
-D FACTORY_MQTT_KEEP_ALIVE=60
|
||||
-D FACTORY_MQTT_CLEAN_SESSION=true
|
||||
-D FACTORY_MQTT_MAX_TOPIC_LENGTH=128
|
||||
|
||||
; JWT Secret
|
||||
-D FACTORY_JWT_SECRET=\"#{random}-#{random}\" ; supports placeholders
|
||||
@@ -1,6 +1,5 @@
|
||||
[features]
|
||||
build_flags =
|
||||
-D USE_CAMERA=1
|
||||
-D USE_BATTERY=1
|
||||
-D USE_NTP=1
|
||||
-D USE_SECURITY=1
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <esp_camera.h>
|
||||
|
||||
typedef struct {
|
||||
camera_fb_t * fb;
|
||||
size_t index;
|
||||
} camera_frame_t;
|
||||
|
||||
#define PART_BOUNDARY "123456789000000000000987654321"
|
||||
|
||||
class AsyncJpegStreamResponse: public AsyncAbstractResponse {
|
||||
private:
|
||||
camera_frame_t _frame;
|
||||
size_t _index;
|
||||
size_t _jpg_buf_len;
|
||||
uint8_t * _jpg_buf;
|
||||
uint64_t lastAsyncRequest;
|
||||
public:
|
||||
AsyncJpegStreamResponse();
|
||||
~AsyncJpegStreamResponse();
|
||||
bool _sourceValid() const {
|
||||
return true;
|
||||
}
|
||||
virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override;
|
||||
size_t _content(uint8_t *buffer, size_t maxLen, size_t index);
|
||||
};
|
||||
|
||||
void streamJpg(AsyncWebServerRequest *request);
|
||||
@@ -1,39 +0,0 @@
|
||||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the usual convention is to give header files names that end with `.h'.
|
||||
It is most portable to use only letters, digits, dashes, and underscores in
|
||||
header file names, and at most one dot.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
||||
@@ -1,3 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
esp_err_t InitializeCamera();
|
||||
@@ -1,297 +0,0 @@
|
||||
#if defined(CAMERA_MODEL_WROVER_KIT)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 21
|
||||
#define SIOD_GPIO_NUM 26
|
||||
#define SIOC_GPIO_NUM 27
|
||||
|
||||
#define Y9_GPIO_NUM 35
|
||||
#define Y8_GPIO_NUM 34
|
||||
#define Y7_GPIO_NUM 39
|
||||
#define Y6_GPIO_NUM 36
|
||||
#define Y5_GPIO_NUM 19
|
||||
#define Y4_GPIO_NUM 18
|
||||
#define Y3_GPIO_NUM 5
|
||||
#define Y2_GPIO_NUM 4
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 23
|
||||
#define PCLK_GPIO_NUM 22
|
||||
|
||||
#elif defined(CAMERA_MODEL_ESP_EYE)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 4
|
||||
#define SIOD_GPIO_NUM 18
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 36
|
||||
#define Y8_GPIO_NUM 37
|
||||
#define Y7_GPIO_NUM 38
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 35
|
||||
#define Y4_GPIO_NUM 14
|
||||
#define Y3_GPIO_NUM 13
|
||||
#define Y2_GPIO_NUM 34
|
||||
#define VSYNC_GPIO_NUM 5
|
||||
#define HREF_GPIO_NUM 27
|
||||
#define PCLK_GPIO_NUM 25
|
||||
|
||||
#define LED_GPIO_NUM 22
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_PSRAM)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 25
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 32
|
||||
#define VSYNC_GPIO_NUM 22
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_V2_PSRAM)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 22
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 32
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_WIDE)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 22
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 32
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#define LED_GPIO_NUM 2
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_ESP32CAM)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 25
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 17
|
||||
#define VSYNC_GPIO_NUM 22
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_UNITCAM)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 25
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 32
|
||||
#define VSYNC_GPIO_NUM 22
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_AI_THINKER)
|
||||
#define PWDN_GPIO_NUM 32
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 0
|
||||
#define SIOD_GPIO_NUM 26
|
||||
#define SIOC_GPIO_NUM 27
|
||||
|
||||
#define Y9_GPIO_NUM 35
|
||||
#define Y8_GPIO_NUM 34
|
||||
#define Y7_GPIO_NUM 39
|
||||
#define Y6_GPIO_NUM 36
|
||||
#define Y5_GPIO_NUM 21
|
||||
#define Y4_GPIO_NUM 19
|
||||
#define Y3_GPIO_NUM 18
|
||||
#define Y2_GPIO_NUM 5
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 23
|
||||
#define PCLK_GPIO_NUM 22
|
||||
|
||||
// 4 for flash led or 33 for normal led
|
||||
#define LED_GPIO_NUM 4
|
||||
|
||||
#elif defined(CAMERA_MODEL_TTGO_T_JOURNAL)
|
||||
#define PWDN_GPIO_NUM 0
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 25
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 17
|
||||
#define VSYNC_GPIO_NUM 22
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_XIAO_ESP32S3)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 10
|
||||
#define SIOD_GPIO_NUM 40
|
||||
#define SIOC_GPIO_NUM 39
|
||||
|
||||
#define Y9_GPIO_NUM 48
|
||||
#define Y8_GPIO_NUM 11
|
||||
#define Y7_GPIO_NUM 12
|
||||
#define Y6_GPIO_NUM 14
|
||||
#define Y5_GPIO_NUM 16
|
||||
#define Y4_GPIO_NUM 18
|
||||
#define Y3_GPIO_NUM 17
|
||||
#define Y2_GPIO_NUM 15
|
||||
#define VSYNC_GPIO_NUM 38
|
||||
#define HREF_GPIO_NUM 47
|
||||
#define PCLK_GPIO_NUM 13
|
||||
|
||||
#elif defined(CAMERA_MODEL_ESP32_CAM_BOARD)
|
||||
// The 18 pin header on the board has Y5 and Y3 swapped
|
||||
#define USE_BOARD_HEADER 0
|
||||
#define PWDN_GPIO_NUM 32
|
||||
#define RESET_GPIO_NUM 33
|
||||
#define XCLK_GPIO_NUM 4
|
||||
#define SIOD_GPIO_NUM 18
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 36
|
||||
#define Y8_GPIO_NUM 19
|
||||
#define Y7_GPIO_NUM 21
|
||||
#define Y6_GPIO_NUM 39
|
||||
#if USE_BOARD_HEADER
|
||||
#define Y5_GPIO_NUM 13
|
||||
#else
|
||||
#define Y5_GPIO_NUM 35
|
||||
#endif
|
||||
#define Y4_GPIO_NUM 14
|
||||
#if USE_BOARD_HEADER
|
||||
#define Y3_GPIO_NUM 35
|
||||
#else
|
||||
#define Y3_GPIO_NUM 13
|
||||
#endif
|
||||
#define Y2_GPIO_NUM 34
|
||||
#define VSYNC_GPIO_NUM 5
|
||||
#define HREF_GPIO_NUM 27
|
||||
#define PCLK_GPIO_NUM 25
|
||||
|
||||
#elif defined(CAMERA_MODEL_ESP32S3_CAM_LCD)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 40
|
||||
#define SIOD_GPIO_NUM 17
|
||||
#define SIOC_GPIO_NUM 18
|
||||
|
||||
#define Y9_GPIO_NUM 39
|
||||
#define Y8_GPIO_NUM 41
|
||||
#define Y7_GPIO_NUM 42
|
||||
#define Y6_GPIO_NUM 12
|
||||
#define Y5_GPIO_NUM 3
|
||||
#define Y4_GPIO_NUM 14
|
||||
#define Y3_GPIO_NUM 47
|
||||
#define Y2_GPIO_NUM 13
|
||||
#define VSYNC_GPIO_NUM 21
|
||||
#define HREF_GPIO_NUM 38
|
||||
#define PCLK_GPIO_NUM 11
|
||||
|
||||
#elif defined(CAMERA_MODEL_ESP32S2_CAM_BOARD)
|
||||
// The 18 pin header on the board has Y5 and Y3 swapped
|
||||
#define USE_BOARD_HEADER 0
|
||||
#define PWDN_GPIO_NUM 1
|
||||
#define RESET_GPIO_NUM 2
|
||||
#define XCLK_GPIO_NUM 42
|
||||
#define SIOD_GPIO_NUM 41
|
||||
#define SIOC_GPIO_NUM 18
|
||||
|
||||
#define Y9_GPIO_NUM 16
|
||||
#define Y8_GPIO_NUM 39
|
||||
#define Y7_GPIO_NUM 40
|
||||
#define Y6_GPIO_NUM 15
|
||||
#if USE_BOARD_HEADER
|
||||
#define Y5_GPIO_NUM 12
|
||||
#else
|
||||
#define Y5_GPIO_NUM 13
|
||||
#endif
|
||||
#define Y4_GPIO_NUM 5
|
||||
#if USE_BOARD_HEADER
|
||||
#define Y3_GPIO_NUM 13
|
||||
#else
|
||||
#define Y3_GPIO_NUM 12
|
||||
#endif
|
||||
#define Y2_GPIO_NUM 14
|
||||
#define VSYNC_GPIO_NUM 38
|
||||
#define HREF_GPIO_NUM 4
|
||||
#define PCLK_GPIO_NUM 3
|
||||
|
||||
#elif defined(CAMERA_MODEL_ESP32S3_EYE)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 15
|
||||
#define SIOD_GPIO_NUM 4
|
||||
#define SIOC_GPIO_NUM 5
|
||||
|
||||
#define Y2_GPIO_NUM 11
|
||||
#define Y3_GPIO_NUM 9
|
||||
#define Y4_GPIO_NUM 8
|
||||
#define Y5_GPIO_NUM 10
|
||||
#define Y6_GPIO_NUM 12
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y8_GPIO_NUM 17
|
||||
#define Y9_GPIO_NUM 16
|
||||
|
||||
#define VSYNC_GPIO_NUM 6
|
||||
#define HREF_GPIO_NUM 7
|
||||
#define PCLK_GPIO_NUM 13
|
||||
|
||||
#else
|
||||
#error "Camera model not selected"
|
||||
#endif
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* User settings
|
||||
*/
|
||||
#define HOSTNAME "Leika"
|
||||
#define SSID ""
|
||||
#define PASS ""
|
||||
|
||||
|
||||
/*
|
||||
* Server settings
|
||||
*/
|
||||
#define HTTP_PORT 80
|
||||
#define WEBSOCKET_PATH "/"
|
||||
#define EVENTSOURCE_PATH "/events"
|
||||
#define USE_CAPTIVE_PORTAL false
|
||||
|
||||
|
||||
/*
|
||||
* Camera module
|
||||
*/
|
||||
#define CAMERA_MODEL_AI_THINKER
|
||||
// #define CAMERA_MODEL_WROVER_KIT
|
||||
// #define CAMERA_MODEL_ESP_EYE
|
||||
// #define CAMERA_MODEL_M5STACK_PSRAM
|
||||
// #define CAMERA_MODEL_M5STACK_V2_PSRAM
|
||||
// #define CAMERA_MODEL_M5STACK_WIDE
|
||||
// #define CAMERA_MODEL_M5STACK_ESP32CAM
|
||||
// #define CAMERA_MODEL_TTGO_T_JOURNAL
|
||||
// #define CAMERA_MODEL_ARDUCAM_ESP32S_UNO
|
||||
|
||||
|
||||
/*
|
||||
* OLED Settings
|
||||
*/
|
||||
#define SCREEN_WIDTH 128
|
||||
#define SCREEN_HEIGHT 64
|
||||
#define SCREEN_RESET -1
|
||||
|
||||
|
||||
/*
|
||||
* I2C software connection
|
||||
*/
|
||||
#define SDA 14
|
||||
#define SCL 15
|
||||
|
||||
|
||||
/*
|
||||
* Serial settings
|
||||
*/
|
||||
#define BAUDRATE 115200
|
||||
#define SERIAL_DEBUG_OUTPUT true
|
||||
|
||||
|
||||
/*
|
||||
* Ultra sonic sensors
|
||||
*/
|
||||
#define USS_LEFT 12
|
||||
#define USS_RIGHT 13
|
||||
#define USS_MAX_DISTANCE 200
|
||||
|
||||
/*
|
||||
* Button settings
|
||||
*/
|
||||
#define BUTTON 16
|
||||
#define BUTTON_LED 2
|
||||
|
||||
/*
|
||||
* PWM controller settings
|
||||
*/
|
||||
#define SERVO_OSCILLATOR_FREQUENCY 27000000
|
||||
#define SERVO_FREQ 50
|
||||
@@ -1,151 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <types.h>
|
||||
#include <jsonserializer.h>
|
||||
|
||||
/*
|
||||
* I2C software connection
|
||||
*/
|
||||
#define SDA 14
|
||||
#define SCL 15
|
||||
|
||||
/*
|
||||
* Serial settings
|
||||
*/
|
||||
#define BAUDRATE 115200
|
||||
#define SERIAL_DEBUG_OUTPUT true
|
||||
|
||||
/*
|
||||
* PWM controller settings
|
||||
*/
|
||||
#define SERVO_OSCILLATOR_FREQUENCY 27000000
|
||||
#define SERVO_FREQ 50
|
||||
|
||||
/*
|
||||
* Button settings
|
||||
*/
|
||||
#define BUTTON 4
|
||||
#define BUTTON_LED 2
|
||||
|
||||
/*
|
||||
* Ultra sonic sensors
|
||||
*/
|
||||
#define USS_LEFT 12
|
||||
#define USS_RIGHT 13
|
||||
#define USS_MAX_DISTANCE 200
|
||||
|
||||
/*
|
||||
* Changeable default data
|
||||
*/
|
||||
#define DEVICE_CONFIG_FILE "/device.cfg"
|
||||
#define DEFAULT_NTP_SERVER "0.pool.ntp.org"
|
||||
|
||||
class DeviceConfig : public IJSONSerializable
|
||||
{
|
||||
// Add variables for additional settings to this list
|
||||
String ntpServer;
|
||||
bool useMetric;
|
||||
|
||||
std::vector<SettingSpec> settingSpecs;
|
||||
size_t writerIndex;
|
||||
|
||||
void SaveToJSON();
|
||||
|
||||
template <typename T>
|
||||
void SetAndSave(T& target, const T& source)
|
||||
{
|
||||
if (target == source)
|
||||
return;
|
||||
|
||||
target = source;
|
||||
|
||||
SaveToJSON();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void SetIfPresentIn(const JsonObjectConst& jsonObject, T& target, const char *tag)
|
||||
{
|
||||
if (jsonObject.containsKey(tag))
|
||||
target = jsonObject[tag].as<T>();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
using ValidateResponse = std::pair<bool, String>;
|
||||
|
||||
// Add additional setting Tags to this list
|
||||
static constexpr const char * NTPServerTag = NAME_OF(ntpServer);
|
||||
static constexpr const char * UseMetricTag = NAME_OF(useMetric);
|
||||
|
||||
DeviceConfig();
|
||||
|
||||
virtual bool SerializeToJSON(JsonObject& jsonObject) override
|
||||
{
|
||||
return SerializeToJSON(jsonObject, true);
|
||||
}
|
||||
|
||||
bool SerializeToJSON(JsonObject& jsonObject, bool includeSensitive)
|
||||
{
|
||||
AllocatedJsonDocument jsonDoc(1024);
|
||||
|
||||
// Add serialization logic for additionl settings to this code
|
||||
jsonDoc[NTPServerTag] = ntpServer;
|
||||
jsonDoc[UseMetricTag] = useMetric;
|
||||
|
||||
return jsonObject.set(jsonDoc.as<JsonObjectConst>());
|
||||
}
|
||||
|
||||
virtual bool DeserializeFromJSON(const JsonObjectConst& jsonObject) override
|
||||
{
|
||||
return DeserializeFromJSON(jsonObject, false);
|
||||
}
|
||||
|
||||
bool DeserializeFromJSON(const JsonObjectConst& jsonObject, bool skipWrite)
|
||||
{
|
||||
// Add deserialization logic for additional settings to this code
|
||||
SetIfPresentIn(jsonObject, ntpServer, NTPServerTag);
|
||||
SetIfPresentIn(jsonObject, useMetric, UseMetricTag);
|
||||
|
||||
if (ntpServer.isEmpty())
|
||||
ntpServer = DEFAULT_NTP_SERVER;
|
||||
|
||||
if (!skipWrite)
|
||||
SaveToJSON();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RemovePersisted()
|
||||
{
|
||||
RemoveJSONFile(DEVICE_CONFIG_FILE);
|
||||
}
|
||||
|
||||
virtual const std::vector<SettingSpec>& GetSettingSpecs() const
|
||||
{
|
||||
return settingSpecs;
|
||||
}
|
||||
|
||||
const String &GetNTPServer() const
|
||||
{
|
||||
return ntpServer;
|
||||
}
|
||||
|
||||
void SetNTPServer(const String &newNTPServer)
|
||||
{
|
||||
SetAndSave(ntpServer, newNTPServer);
|
||||
}
|
||||
|
||||
bool UseMetric() const
|
||||
{
|
||||
return useMetric;
|
||||
}
|
||||
|
||||
void SetUseCelsius(bool newUseMetric)
|
||||
{
|
||||
SetAndSave(useMetric, newUseMetric);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
extern DRAM_ATTR std::unique_ptr<DeviceConfig> g_ptrDeviceConfig;
|
||||
@@ -1,31 +0,0 @@
|
||||
#define USE_PSRAM true
|
||||
|
||||
#define USE_WIFI true
|
||||
|
||||
#define WAIT_FOR_WIFI false
|
||||
|
||||
#define USE_WEBSERVER true
|
||||
|
||||
#define USE_WEBSERVER_SSL false
|
||||
|
||||
#define USE_WEBSOCKET true
|
||||
|
||||
#define USE_OAT false
|
||||
|
||||
#define USE_NTP false
|
||||
|
||||
#define USE_MDNS true
|
||||
|
||||
#define USE_DNS_SERVER false
|
||||
|
||||
#define USE_REMOTE_SERIAL false
|
||||
|
||||
#define USE_LOW_POWER false
|
||||
|
||||
#define USE_CAMERA true
|
||||
|
||||
#define USE_MPU true
|
||||
|
||||
#define USE_POWER_BUTTON true
|
||||
|
||||
#define USE_USS true
|
||||
@@ -1,85 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <SPIFFS.h>
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_ADS1X15.h>
|
||||
#include <NewPing.h>
|
||||
|
||||
// Disable brownout problems
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/soc.h"
|
||||
|
||||
/*
|
||||
* Macros
|
||||
*/
|
||||
#define NAME_OF(x) #x
|
||||
|
||||
/*
|
||||
* Feature flags
|
||||
*/
|
||||
|
||||
#include <featureflags.h>
|
||||
|
||||
#if USE_WIFI
|
||||
#include <WiFi.h>
|
||||
#endif
|
||||
|
||||
#if USE_WIFI && USE_WEBSERVER
|
||||
#if USE_WEBSERVER_SSL
|
||||
#define ASYNC_TCP_SSL_ENABLED 1
|
||||
#include <ESPAsyncTCP.h>
|
||||
#endif
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#endif
|
||||
|
||||
#if USE_OAT
|
||||
#include <ArduinoOTA.h>
|
||||
#endif
|
||||
|
||||
#if USE_DNS_SERVER
|
||||
#include <DNSServer.h>
|
||||
#endif
|
||||
|
||||
#if USE_MDNS
|
||||
#include <ESPmDNS.h>
|
||||
#endif
|
||||
|
||||
#define STACK_SIZE (ESP_TASK_MAIN_STACK) // Stack size for each new thread
|
||||
|
||||
/*
|
||||
* Thread priority
|
||||
*/
|
||||
#define NET_PRIORITY tskIDLE_PRIORITY+5
|
||||
#define MOVEMENT_PRIORITY tskIDLE_PRIORITY+3
|
||||
#define JSONWRITER_PRIORITY tskIDLE_PRIORITY+2
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Thread core
|
||||
*/
|
||||
#define NET_CORE 1
|
||||
#define MOVEMENT_CORE 0
|
||||
#define JSONWRITER_CORE 0
|
||||
|
||||
|
||||
/*
|
||||
* Main include
|
||||
*/
|
||||
#include <taskmanager.h>
|
||||
#include <movement.h>
|
||||
#include <secrets.h>
|
||||
#include <servo.h>
|
||||
|
||||
#if USE_CAMERA
|
||||
|
||||
#include <camera.h>
|
||||
#endif
|
||||
|
||||
#if USE_WIFI && USE_WEBSERVER
|
||||
#include <webserver.h>
|
||||
#endif
|
||||
|
||||
#if USE_WIFI
|
||||
#include <network.h>
|
||||
#endif
|
||||
@@ -1,4 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define JSON_BUFFER_BASE_SIZE 2048
|
||||
#define JSON_BUFFER_INCREMENT 2048
|
||||
@@ -1,80 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <ArduinoJson.h>
|
||||
#include <jsonbase.h>
|
||||
|
||||
struct IJSONSerializable
|
||||
{
|
||||
virtual bool SerializeToJSON(JsonObject& jsonObject) = 0;
|
||||
virtual bool DeserializeFromJSON(const JsonObjectConst& jsonObject) { return false; }
|
||||
};
|
||||
|
||||
template <class E>
|
||||
constexpr auto to_value(E e) noexcept
|
||||
{
|
||||
return static_cast<std::underlying_type_t<E>>(e);
|
||||
}
|
||||
|
||||
#if USE_PSRAM
|
||||
struct JsonPsramAllocator
|
||||
{
|
||||
void* allocate(size_t size) {
|
||||
return ps_malloc(size);
|
||||
}
|
||||
|
||||
void deallocate(void* pointer) {
|
||||
free(pointer);
|
||||
}
|
||||
|
||||
void* reallocate(void* ptr, size_t new_size) {
|
||||
return ps_realloc(ptr, new_size);
|
||||
}
|
||||
};
|
||||
|
||||
typedef BasicJsonDocument<JsonPsramAllocator> AllocatedJsonDocument;
|
||||
|
||||
#else
|
||||
typedef DynamicJsonDocument AllocatedJsonDocument;
|
||||
#endif
|
||||
|
||||
bool LoadJSONFile(const char *fileName, size_t& bufferSize, std::unique_ptr<AllocatedJsonDocument>& pJsonDoc);
|
||||
bool SaveToJSONFile(const char *fileName, size_t& bufferSize, IJSONSerializable& object);
|
||||
bool RemoveJSONFile(const char *fileName);
|
||||
|
||||
#define JSON_WRITER_DELAY 3000
|
||||
|
||||
class JSONWriter
|
||||
{
|
||||
// We allow the main JSON Writer task entry point function to access private members
|
||||
friend void IRAM_ATTR JSONWriterTaskEntry(void *);
|
||||
|
||||
private:
|
||||
|
||||
// Writer function and flag combo
|
||||
struct WriterEntry
|
||||
{
|
||||
std::atomic_bool flag = false;
|
||||
std::function<void()> writer;
|
||||
|
||||
WriterEntry(std::function<void()> writer) :
|
||||
writer(writer)
|
||||
{}
|
||||
|
||||
WriterEntry(WriterEntry&& entry) : WriterEntry(entry.writer)
|
||||
{}
|
||||
};
|
||||
|
||||
std::vector<WriterEntry> writers;
|
||||
std::atomic_ulong latestFlagMs;
|
||||
|
||||
public:
|
||||
|
||||
// Add a writer to the collection. Returns the index of the added writer, for use with FlagWriter()
|
||||
size_t RegisterWriter(std::function<void()> writer);
|
||||
|
||||
// Flag a writer for invocation and wake up the task that calls them
|
||||
void FlagWriter(size_t index);
|
||||
};
|
||||
|
||||
extern DRAM_ATTR std::unique_ptr<JSONWriter> g_ptrJSONWriter;
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <globals.h>
|
||||
|
||||
float getHeading();
|
||||
|
||||
float getTemp();
|
||||
|
||||
float getAngleX();
|
||||
|
||||
float getAngleY();
|
||||
|
||||
float getAngleZ();
|
||||
|
||||
void IRAM_ATTR MovementHandlingLoopEntry(void *);
|
||||
@@ -1,5 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <globals.h>
|
||||
|
||||
void IRAM_ATTR NetworkHandlingLoopEntry(void *);
|
||||
@@ -1,24 +0,0 @@
|
||||
// NOTE: do NOT enter your network details in this file (secrets.example.h)!
|
||||
// Instead, copy this file to secrets.h, and set the below defines in that file!
|
||||
|
||||
#define HOSTNAME "leika" // Relevant if wifi is enabled
|
||||
#define SSID "" // Relevant if wifi is enabled
|
||||
#define PASS "" // Relevant if wifi is enabled
|
||||
|
||||
#define HTTP_PORT 80 // Relevant if webserver is enabled
|
||||
#define WEBSOCKET_PATH "/" // Relevant if ws is enabled
|
||||
|
||||
#define CAMERA_MODEL_AI_THINKER // Relevant if camera is enabled
|
||||
// #define CAMERA_MODEL_WROVER_KIT
|
||||
// #define CAMERA_MODEL_ESP_EYE
|
||||
// #define CAMERA_MODEL_M5STACK_PSRAM
|
||||
// #define CAMERA_MODEL_M5STACK_V2_PSRAM
|
||||
// #define CAMERA_MODEL_M5STACK_WIDE
|
||||
// #define CAMERA_MODEL_M5STACK_ESP32CAM
|
||||
// #define CAMERA_MODEL_M5STACK_UNITCAM
|
||||
// #define CAMERA_MODEL_TTGO_T_JOURNAL
|
||||
// #define CAMERA_MODEL_XIAO_ESP32S3
|
||||
// #define CAMERA_MODEL_ESP32_CAM_BOARD
|
||||
// #define CAMERA_MODEL_ESP32S3_CAM_LCD
|
||||
// #define CAMERA_MODEL_ESP32S2_CAM_BOARD
|
||||
// #define CAMERA_MODEL_ESP32S3_EYE
|
||||
@@ -1,114 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <Adafruit_PWMServoDriver.h>
|
||||
#include <globals.h>
|
||||
#include <webserver.h>
|
||||
|
||||
#if USE_WIFI && USE_WEBSERVER
|
||||
extern DRAM_ATTR CWebServer g_WebServer;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
float omega;
|
||||
float phi;
|
||||
float psi;
|
||||
float xm;
|
||||
float ym;
|
||||
float zm;
|
||||
bool set;
|
||||
} position_t;
|
||||
|
||||
class Servo : public Adafruit_PWMServoDriver {
|
||||
public:
|
||||
|
||||
Servo() : Adafruit_PWMServoDriver() {}
|
||||
|
||||
void SetAngles(int16_t* angle) {
|
||||
for(size_t i = 0; i < 12; i++)
|
||||
servo_angles[i] = angle[i];
|
||||
updateServos();
|
||||
}
|
||||
|
||||
void SetAngle(uint8_t id, int8_t angle) {
|
||||
servo_angles[id] = angle;
|
||||
updateServos();
|
||||
}
|
||||
|
||||
void updateServos() {
|
||||
for(uint8_t i = 0; i < 12; i++){
|
||||
int8_t angle = servo_angles[i];
|
||||
uint16_t pulse = (uint16_t) (0.5 + servo_min[i] + (((angle * servo_invert[i]) + 90) * servo_conversion[i]));
|
||||
setPWM(i, 0, pulse);
|
||||
}
|
||||
broadcastAngles();
|
||||
}
|
||||
|
||||
void setBody(float phi, float theta, float psi, float x, float y, float z) {
|
||||
goal_position.phi = (phi - 128) / 2;
|
||||
goal_position.omega = (theta - 128) / 2;
|
||||
goal_position.psi = (psi - 128) / 2;
|
||||
goal_position.xm = (x - 128) / 2;
|
||||
goal_position.ym = (y - 128) / 2;
|
||||
goal_position.zm = (z - 128) / 2;
|
||||
updateAngles();
|
||||
}
|
||||
|
||||
void setBodyAngle(float phi, float theta, float psi) {
|
||||
goal_position.phi = phi;
|
||||
goal_position.omega = theta;
|
||||
goal_position.psi = psi;
|
||||
updateAngles();
|
||||
}
|
||||
|
||||
void setBodyPosition(float x, float y, float z) {
|
||||
goal_position.xm = x;
|
||||
goal_position.ym = y;
|
||||
goal_position.zm = z;
|
||||
updateAngles();
|
||||
}
|
||||
|
||||
void updateAngles() {
|
||||
servo_angles[0] = goal_position.phi;
|
||||
servo_angles[1] = goal_position.omega;
|
||||
servo_angles[2] = goal_position.psi;
|
||||
servo_angles[3] = goal_position.xm;
|
||||
servo_angles[4] = goal_position.ym;
|
||||
servo_angles[5] = goal_position.zm;
|
||||
updateServos();
|
||||
broadcastAngles();
|
||||
}
|
||||
|
||||
void deactivate() {
|
||||
isActive = false;
|
||||
sleep();
|
||||
}
|
||||
|
||||
void activate() {
|
||||
isActive = true;
|
||||
sleep();
|
||||
}
|
||||
|
||||
void toggleState() {
|
||||
isActive ? sleep() : wakeup();
|
||||
isActive = !isActive;
|
||||
}
|
||||
|
||||
bool isActive {true};
|
||||
|
||||
private:
|
||||
void broadcastAngles() {
|
||||
uint8_t* buf = (uint8_t*)&servo_angles;
|
||||
g_WebServer.broadcast(buf, 12);
|
||||
}
|
||||
|
||||
const int16_t servo_min[12] {92,101,129,92,118,125,110,101,125,92,101,125};
|
||||
const int8_t servo_invert[12] = {-1,1,1, -1,-1,-1, 1,1,1, 1,-1,-1};
|
||||
const float servo_conversion[12] {2.2,2.1055555,1.96923,2.2,2.1055555,1.96923,2.2,2.1055555,1.96923,2.2,2.1055555,1.96923};
|
||||
|
||||
position_t spot_position = {.omega=0,.phi=0,.psi=0,.xm=-40,.ym=-170, .zm=0, .set=1};
|
||||
position_t goal_position = {0,};
|
||||
int16_t servo_angles[12]{0,};
|
||||
};
|
||||
|
||||
extern DRAM_ATTR std::unique_ptr<Servo> g_ptrServo;
|
||||
@@ -1,215 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <esp_task_wdt.h>
|
||||
|
||||
// Stack size for the taskmgr's idle threads
|
||||
#define IDLE_STACK_SIZE 2048
|
||||
#define DEFAULT_STACK_SIZE 2048+512
|
||||
|
||||
class IdleTask
|
||||
{
|
||||
private:
|
||||
|
||||
float _idleRatio = 0;
|
||||
unsigned long _lastMeasurement;
|
||||
|
||||
const int kMillisPerLoop = 1;
|
||||
const int kMillisPerCalc = 1000;
|
||||
|
||||
unsigned long counter = 0;
|
||||
|
||||
public:
|
||||
|
||||
void ProcessIdleTime()
|
||||
{
|
||||
_lastMeasurement = millis();
|
||||
counter = 0;
|
||||
|
||||
// We need to whack the watchdog so we delay in smalle bites until we've used up all the time
|
||||
|
||||
while (true)
|
||||
{
|
||||
int delta = millis() - _lastMeasurement;
|
||||
if (delta >= kMillisPerCalc)
|
||||
{
|
||||
//Serial.printf("Core %u Spent %lu in delay during a window of %d for a ratio of %f\n",
|
||||
// xPortGetCoreID(), counter, delta, (float)counter/delta);
|
||||
_idleRatio = ((float) counter / delta);
|
||||
_lastMeasurement = millis();
|
||||
counter = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
esp_task_wdt_reset();
|
||||
delayMicroseconds(kMillisPerLoop*1000);
|
||||
counter += kMillisPerLoop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If idle time is spent elsewhere, it can be credited to this task. Shouldn't add up to more time than actual though!
|
||||
|
||||
void CountBonusIdleMillis(uint millis)
|
||||
{
|
||||
counter += millis;
|
||||
}
|
||||
|
||||
IdleTask() : _lastMeasurement(millis())
|
||||
{
|
||||
}
|
||||
|
||||
// GetCPUUsage
|
||||
//
|
||||
// Returns 100 less the amount of idle time that we were able to squander.
|
||||
|
||||
float GetCPUUsage() const
|
||||
{
|
||||
// If the measurement failed to even get a chance to run, this core is maxed and there was no idle time
|
||||
|
||||
if (millis() - _lastMeasurement > kMillisPerCalc)
|
||||
return 100.0f;
|
||||
|
||||
// Otherwise, whatever cycles we were able to burn in the idle loop counts as "would have been idle" time
|
||||
return 100.0f-100*_idleRatio;
|
||||
}
|
||||
|
||||
// Stub entry point for calling into it without a THIS pointer
|
||||
|
||||
static void IdleTaskEntry(void * that)
|
||||
{
|
||||
IdleTask * pTask = (IdleTask *)that;
|
||||
pTask->ProcessIdleTime();
|
||||
}
|
||||
};
|
||||
|
||||
// TaskManager
|
||||
//
|
||||
// TaskManager runs two tasks at just over idle priority that do nothing but try to burn CPU, and they
|
||||
// keep track of how much they can burn. It's assumed that everything else runs at a higher priority
|
||||
// and thus they "starve" the idle tasks when doing work.
|
||||
|
||||
class TaskManager
|
||||
{
|
||||
TaskHandle_t _hIdle0 = nullptr;
|
||||
TaskHandle_t _hIdle1 = nullptr;
|
||||
|
||||
IdleTask _taskIdle0;
|
||||
IdleTask _taskIdle1;
|
||||
|
||||
public:
|
||||
|
||||
float GetCPUUsagePercent(int iCore = -1) const
|
||||
{
|
||||
if (iCore < 0)
|
||||
return (_taskIdle0.GetCPUUsage() + _taskIdle1.GetCPUUsage()) / 2;
|
||||
else if (iCore == 0)
|
||||
return _taskIdle0.GetCPUUsage();
|
||||
else if (iCore == 1)
|
||||
return _taskIdle1.GetCPUUsage();
|
||||
else
|
||||
throw new std::runtime_error("Invalid core passed to GetCPUUsagePercentCPU");
|
||||
}
|
||||
|
||||
TaskManager() {}
|
||||
|
||||
void begin()
|
||||
{
|
||||
Serial.printf("Replacing Idle Tasks with TaskManager...\n");
|
||||
// The idle tasks get created with a priority just ABOVE idle so that they steal idle time but nothing else. They then
|
||||
// measure how much time is "wasted" at that lower priority and deem it to have been free CPU
|
||||
|
||||
xTaskCreatePinnedToCore(_taskIdle0.IdleTaskEntry, "Idle0", IDLE_STACK_SIZE, &_taskIdle0, tskIDLE_PRIORITY + 1, &_hIdle0, 0);
|
||||
xTaskCreatePinnedToCore(_taskIdle1.IdleTaskEntry, "Idle1", IDLE_STACK_SIZE, &_taskIdle1, tskIDLE_PRIORITY + 1, &_hIdle1, 1);
|
||||
|
||||
// We need to turn off the watchdogs because our idle measurement tasks burn all of the idle time just
|
||||
// to see how much there is (it's how they measure free CPU). Thus, we starve the system's normal idle tasks
|
||||
// and have to feed the watchdog on our own.
|
||||
|
||||
esp_task_wdt_delete(xTaskGetIdleTaskHandleForCPU(0));
|
||||
esp_task_wdt_delete(xTaskGetIdleTaskHandleForCPU(1));
|
||||
esp_task_wdt_add(_hIdle0);
|
||||
esp_task_wdt_add(_hIdle1);
|
||||
}
|
||||
};
|
||||
|
||||
void IRAM_ATTR NetworkHandlingLoopEntry(void *);
|
||||
void IRAM_ATTR JSONWriterTaskEntry(void *);
|
||||
void IRAM_ATTR MovementHandlingLoopEntry(void *);
|
||||
|
||||
#define DELETE_TASK(handle) if (handle != nullptr) vTaskDelete(handle)
|
||||
|
||||
class ESPTaskManager : public TaskManager
|
||||
{
|
||||
public:
|
||||
|
||||
private:
|
||||
TaskHandle_t _taskNetwork = nullptr;
|
||||
TaskHandle_t _taskMovement = nullptr;
|
||||
TaskHandle_t _taskJSONWriter = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
~ESPTaskManager()
|
||||
{
|
||||
DELETE_TASK(_taskNetwork);
|
||||
DELETE_TASK(_taskMovement);
|
||||
DELETE_TASK(_taskJSONWriter);
|
||||
}
|
||||
|
||||
void StartThreads(){
|
||||
StartNetworkThread();
|
||||
StartMovementThread();
|
||||
StartJSONWriterThread();
|
||||
}
|
||||
|
||||
void StartNetworkThread()
|
||||
{
|
||||
#if USE_WIFI
|
||||
log_i( ">> Launching Network Thread. Mem: %u, LargestBlk: %u, PSRAM Free: %u/%u, ", ESP.getFreeHeap(),ESP.getMaxAllocHeap(), ESP.getFreePsram(), ESP.getPsramSize());
|
||||
xTaskCreatePinnedToCore(NetworkHandlingLoopEntry, "NetworkHandlingLoop", STACK_SIZE, nullptr, NET_PRIORITY, &_taskNetwork, NET_CORE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void StartMovementThread()
|
||||
{
|
||||
log_i(">> Launching Movement Thread");
|
||||
xTaskCreatePinnedToCore(MovementHandlingLoopEntry, "MovementHandlingLoop", STACK_SIZE, nullptr, MOVEMENT_PRIORITY, &_taskMovement, MOVEMENT_CORE);
|
||||
}
|
||||
|
||||
void StartJSONWriterThread()
|
||||
{
|
||||
log_i(">> Launching JSON Writer Thread");
|
||||
xTaskCreatePinnedToCore(JSONWriterTaskEntry, "JSON Writer Loop", STACK_SIZE, nullptr, JSONWRITER_PRIORITY, &_taskJSONWriter, JSONWRITER_CORE);
|
||||
}
|
||||
|
||||
void NotifyJSONWriterThread()
|
||||
{
|
||||
if (_taskJSONWriter == nullptr)
|
||||
return;
|
||||
|
||||
log_w(">> Notifying JSON Writer Thread");
|
||||
// Wake up the writer invoker task if it's sleeping, or request another write cycle if it isn't
|
||||
xTaskNotifyGive(_taskJSONWriter);
|
||||
}
|
||||
|
||||
void NotifyNetworkThread()
|
||||
{
|
||||
if (_taskNetwork == nullptr)
|
||||
return;
|
||||
|
||||
//debugW(">> Notifying Network Thread");
|
||||
// Wake up the network task if it's sleeping, or request another read cycle if it isn't
|
||||
xTaskNotifyGive(_taskNetwork);
|
||||
}
|
||||
|
||||
void NotifyMovementThread()
|
||||
{
|
||||
if (_taskMovement == nullptr)
|
||||
return;
|
||||
|
||||
// Wake up the movement task if it's sleeping, or request another read cycle if it isn't
|
||||
xTaskNotifyGive(_taskMovement);
|
||||
}
|
||||
};
|
||||
|
||||
extern ESPTaskManager g_TaskManager;
|
||||
@@ -1,56 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <WString.h>
|
||||
|
||||
struct EmbeddedFile
|
||||
{
|
||||
// Embedded file size in bytes
|
||||
const size_t length;
|
||||
// Contents as bytes
|
||||
const uint8_t *const contents;
|
||||
|
||||
EmbeddedFile(const uint8_t start[], const uint8_t end[]) :
|
||||
length(end - start),
|
||||
contents(start)
|
||||
{}
|
||||
};
|
||||
|
||||
struct SettingSpec
|
||||
{
|
||||
// Note that if this enum is expanded, ToName() must be also!
|
||||
enum class SettingType : int
|
||||
{
|
||||
Integer,
|
||||
PositiveBigInteger,
|
||||
Float,
|
||||
Boolean,
|
||||
String,
|
||||
Palette
|
||||
};
|
||||
|
||||
String Name;
|
||||
String FriendlyName;
|
||||
String Description;
|
||||
SettingType Type;
|
||||
|
||||
SettingSpec(const String& name, const String& friendlyName, const String& description, SettingType type)
|
||||
: Name(name),
|
||||
FriendlyName(friendlyName),
|
||||
Description(description),
|
||||
Type(type)
|
||||
{}
|
||||
|
||||
SettingSpec(const String& name, const String& friendlyName, SettingType type) : SettingSpec(name, friendlyName, "", type)
|
||||
{}
|
||||
|
||||
SettingSpec()
|
||||
{}
|
||||
|
||||
String static ToName(SettingType type)
|
||||
{
|
||||
String names[] = { "Integer", "PositiveBigInteger", "Float", "Boolean", "String", "Palette" };
|
||||
return names[(int)type];
|
||||
}
|
||||
};
|
||||
@@ -1,219 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <deviceconfig.h>
|
||||
#include <AsyncJson.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <HTTPClient.h>
|
||||
#include <Update.h>
|
||||
#include <SPIFFS.h>
|
||||
#include <servo.h>
|
||||
#include <AsyncJpegStream.h>
|
||||
|
||||
#define HTTP_CODE_OK 200
|
||||
#define HTTP_CODE_NOT_FOUND 404
|
||||
|
||||
class CWebServer {
|
||||
private:
|
||||
// Template for param to value converter function, used by PushPostParamIfPresent()
|
||||
template<typename Tv>
|
||||
using ParamValueGetter = std::function<Tv(AsyncWebParameter *param)>;
|
||||
|
||||
// Template for value setting forwarding function, used by PushPostParamIfPresent()
|
||||
template<typename Tv>
|
||||
using ValueSetter = std::function<bool(Tv)>;
|
||||
|
||||
// Value validating function type, as used by DeviceConfig (and possible others)
|
||||
using ValueValidator = std::function<DeviceConfig::ValidateResponse(const String&)>;
|
||||
|
||||
struct StaticStatistics {
|
||||
uint32_t HeapSize;
|
||||
size_t DmaHeapSize;
|
||||
uint32_t PsramSize;
|
||||
const char *ChipModel;
|
||||
uint8_t ChipCores;
|
||||
uint32_t CpuFreqMHz;
|
||||
uint32_t SketchSize;
|
||||
uint32_t FreeSketchSpace;
|
||||
uint32_t FlashChipSize;
|
||||
};
|
||||
|
||||
static std::vector<SettingSpec> deviceSettingSpecs;
|
||||
static const std::map<String, ValueValidator> settingValidators;
|
||||
|
||||
AsyncWebServer _server;
|
||||
StaticStatistics _staticStats;
|
||||
#if USE_WEBSOCKET
|
||||
AsyncWebSocket _ws;
|
||||
#endif
|
||||
|
||||
// Helper functions/templates
|
||||
|
||||
// Convert param value to a specific type and forward it to a setter function that expects that type as an argument
|
||||
template<typename Tv>
|
||||
static bool PushPostParamIfPresent(AsyncWebServerRequest * pRequest, const String ¶mName, ValueSetter<Tv> setter, ParamValueGetter<Tv> getter)
|
||||
{
|
||||
if (!pRequest->hasParam(paramName, true, false))
|
||||
return false;
|
||||
|
||||
log_v("found %s", paramName.c_str());
|
||||
|
||||
AsyncWebParameter *param = pRequest->getParam(paramName, true, false);
|
||||
|
||||
// Extract the value and pass it off to the setter
|
||||
return setter(getter(param));
|
||||
}
|
||||
|
||||
// Generic param value forwarder. The type argument must be implicitly convertable from String!
|
||||
// Some specializations of this are included in the CPP file
|
||||
template<typename Tv>
|
||||
static bool PushPostParamIfPresent(AsyncWebServerRequest * pRequest, const String ¶mName, ValueSetter<Tv> setter)
|
||||
{
|
||||
return PushPostParamIfPresent<Tv>(pRequest, paramName, setter, [](AsyncWebParameter * param) { return param->value(); });
|
||||
}
|
||||
|
||||
// AddCORSHeaderAndSend(OK)Response
|
||||
//
|
||||
// Sends a response with CORS headers added
|
||||
template<typename Tr>
|
||||
static void AddCORSHeaderAndSendResponse(AsyncWebServerRequest * pRequest, Tr * pResponse)
|
||||
{
|
||||
// pResponse->addHeader("Server", HOSTNAME);
|
||||
// pResponse->addHeader("Access-Control-Allow-Origin", "*");
|
||||
pRequest->send(pResponse);
|
||||
}
|
||||
|
||||
// Version for empty response, normally used to finish up things that don't return anything, like "NextEffect"
|
||||
static void AddCORSHeaderAndSendOKResponse(AsyncWebServerRequest * pRequest)
|
||||
{
|
||||
AddCORSHeaderAndSendResponse(pRequest, pRequest->beginResponse(HTTP_CODE_OK));
|
||||
}
|
||||
|
||||
// Straightforward support functions
|
||||
|
||||
static bool IsPostParamTrue(AsyncWebServerRequest * pRequest, const String & paramName);
|
||||
static const std::vector<SettingSpec> & LoadDeviceSettingSpecs();
|
||||
static void SendSettingSpecsResponse(AsyncWebServerRequest * pRequest, const std::vector<SettingSpec> & settingSpecs);
|
||||
static void SetSettingsIfPresent(AsyncWebServerRequest * pRequest);
|
||||
#if USE_OAT
|
||||
static void UpdateFirmware(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final);
|
||||
static void UpdateFileSystemImage(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final);
|
||||
static void HandleUpdate(AsyncWebServerRequest* request, String filename, size_t index, uint8_t* data, size_t len, bool final, size_t upload_size, uint8_t upload_index);
|
||||
#endif
|
||||
|
||||
// Endpoint member functions
|
||||
static void GetSettingSpecs(AsyncWebServerRequest * pRequest);
|
||||
static void GetSettings(AsyncWebServerRequest * pRequest);
|
||||
static void SetSettings(AsyncWebServerRequest * pRequest);
|
||||
static void SaveFile(AsyncWebServerRequest* request, String filename, size_t index, uint8_t* data, size_t len, bool final);
|
||||
#if USE_OAT
|
||||
static void UpdateRequestHandler(AsyncWebServerRequest * pRequest);
|
||||
#endif
|
||||
static void Reset(AsyncWebServerRequest * pRequest);
|
||||
static void GzipSpa(AsyncWebServerRequest * pRequest);
|
||||
static void HandleWsMessage(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len);
|
||||
|
||||
// Not static because it uses member _staticStats
|
||||
void GetStatistics(AsyncWebServerRequest * pRequest);
|
||||
|
||||
public:
|
||||
|
||||
CWebServer()
|
||||
: _server(HTTP_PORT)
|
||||
#if USE_WEBSOCKET
|
||||
, _ws(WEBSOCKET_PATH)
|
||||
#endif
|
||||
{}
|
||||
|
||||
void begin() {
|
||||
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");
|
||||
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Methods", "GET, POST, PUT");
|
||||
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Headers", "Content-Type");
|
||||
DefaultHeaders::Instance().addHeader("Server", HOSTNAME);
|
||||
|
||||
_staticStats.HeapSize = ESP.getHeapSize();
|
||||
_staticStats.DmaHeapSize = heap_caps_get_total_size(MALLOC_CAP_DMA);
|
||||
_staticStats.PsramSize = ESP.getPsramSize();
|
||||
_staticStats.ChipModel = ESP.getChipModel();
|
||||
_staticStats.ChipCores = ESP.getChipCores();
|
||||
_staticStats.CpuFreqMHz = ESP.getCpuFreqMHz();
|
||||
_staticStats.SketchSize = ESP.getSketchSize();
|
||||
_staticStats.FreeSketchSpace = ESP.getFreeSketchSpace();
|
||||
_staticStats.FlashChipSize = ESP.getFlashChipSize();
|
||||
|
||||
_server.onFileUpload(SaveFile);
|
||||
|
||||
#if USE_WEBSOCKET
|
||||
_ws.onEvent(HandleWsMessage);
|
||||
_server.addHandler(&_ws);
|
||||
#endif
|
||||
|
||||
_server.on("/api/statistics", HTTP_GET, [this](AsyncWebServerRequest * pRequest) { this->GetStatistics(pRequest); });
|
||||
_server.on("/api/getStatistics", HTTP_GET, [this](AsyncWebServerRequest * pRequest) { this->GetStatistics(pRequest); });
|
||||
|
||||
_server.on("/api/settings/specs", HTTP_GET, [](AsyncWebServerRequest * pRequest) { GetSettingSpecs(pRequest); });
|
||||
_server.on("/api/settings", HTTP_GET, [](AsyncWebServerRequest * pRequest) { GetSettings(pRequest); });
|
||||
_server.on("/api/settings", HTTP_POST, [](AsyncWebServerRequest * pRequest) { SetSettings(pRequest); });
|
||||
|
||||
#if USE_OAT
|
||||
_server.on("/api/update/filesystem", HTTP_POST, UpdateRequestHandler, UpdateFirmware);
|
||||
_server.on("/api/update/firmware", HTTP_POST, UpdateRequestHandler, UpdateFileSystemImage);
|
||||
#endif
|
||||
|
||||
_server.on("/api/stream", HTTP_GET, streamJpg);
|
||||
|
||||
_server.on("/api/reset", HTTP_POST, [](AsyncWebServerRequest * pRequest) { Reset(pRequest); });
|
||||
|
||||
_server.serveStatic("/", SPIFFS, "/").setCacheControl("max-age=31536000");
|
||||
|
||||
_server.onNotFound([](AsyncWebServerRequest *pRequest) { GzipSpa(pRequest); });
|
||||
|
||||
#if USE_WEBSERVER_SSL
|
||||
_server.beginSecure("/server.cer", "/server.key", NULL);
|
||||
|
||||
_server.onSslFileRequest([](void * arg, const char *filename, uint8_t **buf) -> int {
|
||||
Serial.printf("SSL File: %s\n", filename);
|
||||
File file = SPIFFS.open(filename, "r");
|
||||
if(file){
|
||||
size_t size = file.size();
|
||||
uint8_t * nbuf = (uint8_t*)malloc(size);
|
||||
if(nbuf){
|
||||
size = file.read(nbuf, size);
|
||||
file.close();
|
||||
*buf = nbuf;
|
||||
return size;
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
*buf = 0;
|
||||
return 0;
|
||||
}, NULL);
|
||||
#else
|
||||
_server.begin();
|
||||
#endif
|
||||
|
||||
log_i("HTTP server started");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
#if USE_WEBSOCKET
|
||||
_ws.cleanupClients();
|
||||
#endif
|
||||
}
|
||||
|
||||
void broadcast(uint8_t* content, size_t length) {
|
||||
_ws.binaryAll(content, length);
|
||||
}
|
||||
|
||||
void broadcastJson(char* content, size_t length) {
|
||||
_ws.textAll(content, length);
|
||||
}
|
||||
};
|
||||
|
||||
// Set value in lambda using a forwarding function. Always returns true
|
||||
#define SET_VALUE(functionCall) [](auto value) { functionCall; return true; }
|
||||
|
||||
// Set value in lambda using a forwarding function. Reports success based on function's return value,
|
||||
// which must be implicitly convertable to bool
|
||||
#define CONFIRM_VALUE(functionCall) [](auto value)->bool { return functionCall; }
|
||||
+44
-19
@@ -9,11 +9,15 @@
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[platformio]
|
||||
description = Spot Micro Robot
|
||||
data_dir = data
|
||||
extra_configs =
|
||||
factory_settings.ini
|
||||
features.ini
|
||||
build_settings.ini
|
||||
default_envs = esp32dev
|
||||
|
||||
[base]
|
||||
[env]
|
||||
platform = espressif32
|
||||
framework = arduino
|
||||
monitor_speed = 115200
|
||||
@@ -24,30 +28,51 @@ monitor_filters =
|
||||
build_flags =
|
||||
${factory_settings.build_flags}
|
||||
${features.build_flags}
|
||||
${build_settings.build_flags}
|
||||
-D CORE_DEBUG_LEVEL=5
|
||||
-D register=
|
||||
-std=gnu++17
|
||||
build_unflags = -std=gnu++11
|
||||
test_ignore = test_embedded
|
||||
board_build.filesystem = littlefs
|
||||
lib_deps =
|
||||
https://github.com/me-no-dev/ESPAsyncWebServer.git
|
||||
bblanchon/ArduinoJson@^6.21.2
|
||||
thomasfredericks/Bounce2@ ^2.7.0
|
||||
teckel12/NewPing@^1.9.7
|
||||
adafruit/Adafruit SSD1306@^2.5.7
|
||||
adafruit/Adafruit GFX Library@^1.11.5
|
||||
adafruit/Adafruit BusIO@^1.9.3
|
||||
adafruit/Adafruit PWM Servo Driver Library@^2.4.1
|
||||
adafruit/Adafruit ADS1X15@^2.4.0
|
||||
adafruit/Adafruit HMC5883 Unified@^1.2.1
|
||||
adafruit/Adafruit Unified Sensor@^1.1.11
|
||||
plageoj/UrlEncode@ ^1.0.1
|
||||
rfetick/MPU6050_light@^1.1.0
|
||||
SPI
|
||||
board_build.partitions = config/no_oat.csv
|
||||
https://github.com/theelims/PsychicMqttClient.git
|
||||
;hoeken/PsychicHttp
|
||||
; https://github.com/me-no-dev/ESPAsyncWebServer.git
|
||||
; thomasfredericks/Bounce2@ ^2.7.0
|
||||
; teckel12/NewPing@^1.9.7
|
||||
; adafruit/Adafruit SSD1306@^2.5.7
|
||||
; adafruit/Adafruit GFX Library@^1.11.5
|
||||
; adafruit/Adafruit BusIO@^1.9.3
|
||||
; adafruit/Adafruit PWM Servo Driver Library@^2.4.1
|
||||
; adafruit/Adafruit ADS1X15@^2.4.0
|
||||
; adafruit/Adafruit HMC5883 Unified@^1.2.1
|
||||
; adafruit/Adafruit Unified Sensor@^1.1.11
|
||||
; plageoj/UrlEncode@ ^1.0.1
|
||||
; rfetick/MPU6050_light@^1.1.0
|
||||
; SPI
|
||||
; board_build.partitions = config/no_oat.csv
|
||||
extra_scripts =
|
||||
pre:scripts/build_app.py
|
||||
pre:scripts/generate_cert_bundle.py
|
||||
scripts/rename_fw.py
|
||||
board_build.embed_files = src/certs/x509_crt_bundle.bin
|
||||
board_ssl_cert_source = adafruit
|
||||
|
||||
[env:esp32cam]
|
||||
extends = base
|
||||
monitor_rts = 0
|
||||
monitor_dtr = 0
|
||||
board = esp32cam
|
||||
board = esp32cam
|
||||
board_build.partitions = min_spiffs.csv
|
||||
build_flags=
|
||||
-D USE_CAMERA
|
||||
${env.build_flags}
|
||||
-D LED_BUILTIN=4
|
||||
-D KEY_BUILTIN=0
|
||||
|
||||
[env:esp32dev]
|
||||
board = esp32dev
|
||||
board_build.partitions = min_spiffs.csv
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-D LED_BUILTIN=2
|
||||
-D KEY_BUILTIN=0
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
# ESP32 SvelteKit --
|
||||
#
|
||||
# A simple, secure and extensible framework for IoT projects for ESP32 platforms
|
||||
# with responsive Sveltekit front-end built with TailwindCSS and DaisyUI.
|
||||
# https://github.com/theelims/ESP32-sveltekit
|
||||
#
|
||||
# Copyright (C) 2018 - 2023 rjwats
|
||||
# Copyright (C) 2023 theelims
|
||||
# Copyright (C) 2023 Maxtrium B.V. [ code available under dual license ]
|
||||
#
|
||||
# All Rights Reserved. This software may be modified and distributed under
|
||||
# the terms of the LGPL v3 license. See the LICENSE file for details.
|
||||
|
||||
from pathlib import Path
|
||||
from shutil import copyfileobj
|
||||
import os
|
||||
import gzip
|
||||
import mimetypes
|
||||
import glob
|
||||
from datetime import datetime
|
||||
|
||||
Import("env")
|
||||
|
||||
output_file = env["PROJECT_DIR"] + "/lib/ESP32-sveltekit/WWWData.h"
|
||||
source_www_dir = env["PROJECT_DIR"] + "/../app2/src"
|
||||
build_www_dir = env["PROJECT_DIR"] + "/../app2/build"
|
||||
www_dir = "www"
|
||||
|
||||
def find_latest_timestamp_for_app():
|
||||
list_of_files = glob.glob(source_www_dir+'/**/*', recursive=True)
|
||||
latest_file = max(list_of_files, key=os.path.getmtime)
|
||||
return os.path.getmtime(latest_file)
|
||||
|
||||
def should_regenerate_output_file():
|
||||
if not flag_exists("EMBED_WWW") or not os.path.exists(output_file):
|
||||
return True
|
||||
last_source_change = find_latest_timestamp_for_app()
|
||||
last_build = os.path.getmtime(output_file)
|
||||
|
||||
print(f'Newest interface file: {datetime.fromtimestamp(last_source_change):%Y-%m-%d %H:%M:%S}, WWW Outputfile: {datetime.fromtimestamp(last_build):%Y-%m-%d %H:%M:%S}')
|
||||
|
||||
if (last_build < last_source_change):
|
||||
print("Svelte source files are updated. Need to regenerate.")
|
||||
return True
|
||||
print("Current outputfile is O.K. No need to regenerate.")
|
||||
return False
|
||||
|
||||
|
||||
def gzip_file(file):
|
||||
with open(file, 'rb') as f_in:
|
||||
with gzip.open(file + '.gz', 'wb') as f_out:
|
||||
copyfileobj(f_in, f_out)
|
||||
os.remove(file)
|
||||
|
||||
def is_compressed_filetype(filetype):
|
||||
compressed_types = ['zip', 'gz', 'rar', '7z', 'jpg', 'jpeg', 'png', 'mp4', 'mp3']
|
||||
return filetype.lower() in compressed_types
|
||||
|
||||
def flag_exists(flag):
|
||||
buildFlags = env.ParseFlags(env["BUILD_FLAGS"])
|
||||
for define in buildFlags.get("CPPDEFINES"):
|
||||
if (define == flag or (isinstance(define, list) and define[0] == flag)):
|
||||
return True
|
||||
|
||||
def build_progmem():
|
||||
mimetypes.init()
|
||||
with open(output_file, "w") as progmem:
|
||||
progmem.write("#include <functional>\n")
|
||||
progmem.write("#include <Arduino.h>\n\n")
|
||||
|
||||
assetMap = {}
|
||||
|
||||
# Iterate over all files in the build directory
|
||||
for idx, path in enumerate(Path(www_dir).rglob("*.*")):
|
||||
asset_path = path.relative_to(www_dir).as_posix()
|
||||
print(f"Converting {asset_path}")
|
||||
|
||||
asset_var = f'WEB_ASSET_DATA_{idx}'
|
||||
filetype = asset_path.split('.')[-1]
|
||||
asset_mime, _ = mimetypes.guess_type(asset_path)
|
||||
asset_mime = asset_mime if asset_mime else f'application/octet-stream'
|
||||
|
||||
progmem.write('// ' + str(asset_path) + '\n')
|
||||
progmem.write('const uint8_t ' + asset_var + '[] = {\n ')
|
||||
|
||||
# Open path as binary file, compress and read into byte array
|
||||
size = 0
|
||||
with open(path, "rb") as f:
|
||||
file_data = f.read()
|
||||
if not is_compressed_filetype(filetype):
|
||||
file_data = gzip.compress(file_data)
|
||||
for byte in file_data:
|
||||
if not (size % 16):
|
||||
progmem.write('\n\t')
|
||||
|
||||
progmem.write(f"0x{byte:02X},")
|
||||
size += 1
|
||||
|
||||
progmem.write('\n};\n\n')
|
||||
assetMap[asset_path] = { "name": asset_var, "mime": asset_mime, "size": size }
|
||||
|
||||
progmem.write('typedef std::function<void(const String& uri, const String& contentType, const uint8_t * content, size_t len)> RouteRegistrationHandler;\n\n')
|
||||
progmem.write('class WWWData {\n')
|
||||
progmem.write('\tpublic:\n')
|
||||
progmem.write('\t\tstatic void registerRoutes(RouteRegistrationHandler handler) {\n')
|
||||
|
||||
for asset_path, asset in assetMap.items():
|
||||
progmem.write(f'\t\t\thandler("/{asset_path}", "{asset["mime"]}", {asset["name"]}, {asset["size"]});\n')
|
||||
|
||||
progmem.write('\t\t}\n')
|
||||
progmem.write('};\n\n')
|
||||
|
||||
def build_webapp():
|
||||
os.chdir("../app2")
|
||||
print("Building app with pnpm")
|
||||
env.Execute("pnpm install")
|
||||
env.Execute("pnpm run build")
|
||||
os.chdir("../esp32")
|
||||
|
||||
def embed_webapp():
|
||||
if flag_exists("EMBED_WWW"):
|
||||
print("Converting interface to PROGMEM")
|
||||
build_progmem()
|
||||
return
|
||||
|
||||
print("running: build_interface.py")
|
||||
if (should_regenerate_output_file()):
|
||||
build_webapp()
|
||||
embed_webapp()
|
||||
@@ -0,0 +1,209 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# modified ESP32 x509 certificate bundle generation utility to run with platformio
|
||||
#
|
||||
# Converts PEM and DER certificates to a custom bundle format which stores just the
|
||||
# subject name and public key to reduce space
|
||||
#
|
||||
# The bundle will have the format: number of certificates; crt 1 subject name length; crt 1 public key length;
|
||||
# crt 1 subject name; crt 1 public key; crt 2...
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
from __future__ import with_statement
|
||||
|
||||
from pathlib import Path
|
||||
import os
|
||||
import struct
|
||||
import sys
|
||||
import requests
|
||||
from io import open
|
||||
|
||||
Import("env")
|
||||
|
||||
try:
|
||||
from cryptography import x509
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
except ImportError:
|
||||
env.Execute("$PYTHONEXE -m pip install cryptography")
|
||||
|
||||
|
||||
ca_bundle_bin_file = 'x509_crt_bundle.bin'
|
||||
mozilla_cacert_url = 'https://curl.se/ca/cacert.pem'
|
||||
adafruit_cacert_url = 'https://raw.githubusercontent.com/adafruit/certificates/main/data/roots.pem'
|
||||
certs_dir = Path("./ssl_certs")
|
||||
binary_dir = Path("./src/certs")
|
||||
|
||||
quiet = False
|
||||
|
||||
def download_cacert_file(source):
|
||||
if source == "mozilla":
|
||||
response = requests.get(mozilla_cacert_url)
|
||||
elif source == "adafruit":
|
||||
response = requests.get(adafruit_cacert_url)
|
||||
else:
|
||||
raise InputError('Invalid certificate source')
|
||||
|
||||
if response.status_code == 200:
|
||||
|
||||
# Ensure the directory exists, create it if necessary
|
||||
os.makedirs(certs_dir, exist_ok=True)
|
||||
|
||||
# Generate the full path to the output file
|
||||
output_file = os.path.join(certs_dir, "cacert.pem")
|
||||
|
||||
# Write the certificate bundle to the output file with utf-8 encoding
|
||||
with open(output_file, "w", encoding="utf-8") as f:
|
||||
f.write(response.text)
|
||||
|
||||
status('Certificate bundle downloaded to: %s' % output_file)
|
||||
else:
|
||||
status('Failed to fetch the certificate bundle.')
|
||||
|
||||
def status(msg):
|
||||
""" Print status message to stderr """
|
||||
if not quiet:
|
||||
critical(msg)
|
||||
|
||||
|
||||
def critical(msg):
|
||||
""" Print critical message to stderr """
|
||||
sys.stderr.write('SSL Cert Store: ')
|
||||
sys.stderr.write(msg)
|
||||
sys.stderr.write('\n')
|
||||
|
||||
|
||||
class CertificateBundle:
|
||||
def __init__(self):
|
||||
self.certificates = []
|
||||
self.compressed_crts = []
|
||||
|
||||
if os.path.isfile(ca_bundle_bin_file):
|
||||
os.remove(ca_bundle_bin_file)
|
||||
|
||||
def add_from_path(self, crts_path):
|
||||
|
||||
found = False
|
||||
for file_path in os.listdir(crts_path):
|
||||
found |= self.add_from_file(os.path.join(crts_path, file_path))
|
||||
|
||||
if found is False:
|
||||
raise InputError('No valid x509 certificates found in %s' % crts_path)
|
||||
|
||||
def add_from_file(self, file_path):
|
||||
try:
|
||||
if file_path.endswith('.pem'):
|
||||
status('Parsing certificates from %s' % file_path)
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
crt_str = f.read()
|
||||
self.add_from_pem(crt_str)
|
||||
return True
|
||||
|
||||
elif file_path.endswith('.der'):
|
||||
status('Parsing certificates from %s' % file_path)
|
||||
with open(file_path, 'rb') as f:
|
||||
crt_str = f.read()
|
||||
self.add_from_der(crt_str)
|
||||
return True
|
||||
|
||||
except ValueError:
|
||||
critical('Invalid certificate in %s' % file_path)
|
||||
raise InputError('Invalid certificate')
|
||||
|
||||
return False
|
||||
|
||||
def add_from_pem(self, crt_str):
|
||||
""" A single PEM file may have multiple certificates """
|
||||
|
||||
crt = ''
|
||||
count = 0
|
||||
start = False
|
||||
|
||||
for strg in crt_str.splitlines(True):
|
||||
if strg == '-----BEGIN CERTIFICATE-----\n' and start is False:
|
||||
crt = ''
|
||||
start = True
|
||||
elif strg == '-----END CERTIFICATE-----\n' and start is True:
|
||||
crt += strg + '\n'
|
||||
start = False
|
||||
self.certificates.append(x509.load_pem_x509_certificate(crt.encode(), default_backend()))
|
||||
count += 1
|
||||
if start is True:
|
||||
crt += strg
|
||||
|
||||
if count == 0:
|
||||
raise InputError('No certificate found')
|
||||
|
||||
status('Successfully added %d certificates' % count)
|
||||
|
||||
def add_from_der(self, crt_str):
|
||||
self.certificates.append(x509.load_der_x509_certificate(crt_str, default_backend()))
|
||||
status('Successfully added 1 certificate')
|
||||
|
||||
def create_bundle(self):
|
||||
# Sort certificates in order to do binary search when looking up certificates
|
||||
self.certificates = sorted(self.certificates, key=lambda cert: cert.subject.public_bytes(default_backend()))
|
||||
|
||||
bundle = struct.pack('>H', len(self.certificates))
|
||||
|
||||
for crt in self.certificates:
|
||||
""" Read the public key as DER format """
|
||||
pub_key = crt.public_key()
|
||||
pub_key_der = pub_key.public_bytes(serialization.Encoding.DER, serialization.PublicFormat.SubjectPublicKeyInfo)
|
||||
|
||||
""" Read the subject name as DER format """
|
||||
sub_name_der = crt.subject.public_bytes(default_backend())
|
||||
|
||||
name_len = len(sub_name_der)
|
||||
key_len = len(pub_key_der)
|
||||
len_data = struct.pack('>HH', name_len, key_len)
|
||||
|
||||
bundle += len_data
|
||||
bundle += sub_name_der
|
||||
bundle += pub_key_der
|
||||
|
||||
return bundle
|
||||
|
||||
class InputError(RuntimeError):
|
||||
def __init__(self, e):
|
||||
super(InputError, self).__init__(e)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
bundle = CertificateBundle()
|
||||
|
||||
try:
|
||||
cert_source = env.GetProjectOption("board_ssl_cert_source")
|
||||
|
||||
if (cert_source == "mozilla" or cert_source == "adafruit"):
|
||||
download_cacert_file(cert_source)
|
||||
bundle.add_from_file(os.path.join(certs_dir, "cacert.pem"))
|
||||
elif (cert_source == "folder"):
|
||||
bundle.add_from_path(certs_dir)
|
||||
except ValueError:
|
||||
critical('Invalid configuration option: use \'board_ssl_cert_source\' parameter in platformio.ini' )
|
||||
raise InputError('Invalid certificate')
|
||||
|
||||
status('Successfully added %d certificates in total' % len(bundle.certificates))
|
||||
|
||||
crt_bundle = bundle.create_bundle()
|
||||
|
||||
# Ensure the directory exists, create it if necessary
|
||||
os.makedirs(binary_dir, exist_ok=True)
|
||||
|
||||
output_file = os.path.join(binary_dir, ca_bundle_bin_file)
|
||||
|
||||
with open(output_file, 'wb') as f:
|
||||
f.write(crt_bundle)
|
||||
|
||||
status('Successfully created %s' % output_file)
|
||||
|
||||
|
||||
try:
|
||||
main()
|
||||
except InputError as e:
|
||||
print(e)
|
||||
sys.exit(2)
|
||||
@@ -0,0 +1,89 @@
|
||||
"""
|
||||
EMS-ESP - https://github.com/emsesp/EMS-ESP
|
||||
Copyright 2020-2023 Paul Derbyshire
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
|
||||
import shutil
|
||||
import re
|
||||
import os
|
||||
Import("env")
|
||||
import hashlib
|
||||
|
||||
|
||||
OUTPUT_DIR = "build{}".format(os.path.sep)
|
||||
|
||||
def readFlag(flag):
|
||||
buildFlags = env.ParseFlags(env["BUILD_FLAGS"])
|
||||
# print(buildFlags.get("CPPDEFINES"))
|
||||
for define in buildFlags.get("CPPDEFINES"):
|
||||
if (define == flag or (isinstance(define, list) and define[0] == flag)):
|
||||
# print("Found "+flag+" = "+define[1])
|
||||
# strip quotes ("") from define[1]
|
||||
cleanedFlag = re.sub(r'^"|"$', '', define[1])
|
||||
return cleanedFlag
|
||||
return None
|
||||
|
||||
|
||||
def bin_copy(source, target, env):
|
||||
|
||||
# get the build info
|
||||
app_version = readFlag("APP_VERSION")
|
||||
app_name = readFlag("APP_NAME")
|
||||
build_target = env.get('PIOENV')
|
||||
|
||||
# print information's
|
||||
print("App Version: " + app_version)
|
||||
print("App Name: " + app_name)
|
||||
print("Build Target: " + build_target)
|
||||
|
||||
# convert . to - so Windows doesn't complain
|
||||
variant = app_name + "_" + build_target + "_" + app_version.replace(".", "-")
|
||||
|
||||
# check if output directories exist and create if necessary
|
||||
if not os.path.isdir(OUTPUT_DIR):
|
||||
os.mkdir(OUTPUT_DIR)
|
||||
|
||||
for d in ['firmware']:
|
||||
if not os.path.isdir("{}{}".format(OUTPUT_DIR, d)):
|
||||
os.mkdir("{}{}".format(OUTPUT_DIR, d))
|
||||
|
||||
# create string with location and file names based on variant
|
||||
bin_file = "{}firmware{}{}.bin".format(OUTPUT_DIR, os.path.sep, variant)
|
||||
md5_file = "{}firmware{}{}.md5".format(OUTPUT_DIR, os.path.sep, variant)
|
||||
|
||||
# check if new target files exist and remove if necessary
|
||||
for f in [bin_file]:
|
||||
if os.path.isfile(f):
|
||||
os.remove(f)
|
||||
|
||||
# check if new target files exist and remove if necessary
|
||||
for f in [md5_file]:
|
||||
if os.path.isfile(f):
|
||||
os.remove(f)
|
||||
|
||||
print("Renaming file to "+bin_file)
|
||||
|
||||
# copy firmware.bin to firmware/<variant>.bin
|
||||
shutil.copy(str(target[0]), bin_file)
|
||||
|
||||
with open(bin_file,"rb") as f:
|
||||
result = hashlib.md5(f.read())
|
||||
print("Calculating MD5: "+result.hexdigest())
|
||||
file1 = open(md5_file, 'w')
|
||||
file1.write(result.hexdigest())
|
||||
file1.close()
|
||||
|
||||
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", [bin_copy])
|
||||
env.AddPostAction("$BUILD_DIR/${PROGNAME}.md5", [bin_copy])
|
||||
@@ -1,128 +0,0 @@
|
||||
#include <AsyncJpegStream.h>
|
||||
|
||||
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";
|
||||
|
||||
AsyncJpegStreamResponse::AsyncJpegStreamResponse(){
|
||||
_callback = nullptr;
|
||||
_code = 200;
|
||||
_contentLength = 0;
|
||||
_contentType = 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::~AsyncJpegStreamResponse(){
|
||||
if(_frame.fb){
|
||||
if(_frame.fb->format != PIXFORMAT_JPEG){
|
||||
free(_jpg_buf);
|
||||
}
|
||||
esp_camera_fb_return(_frame.fb);
|
||||
}
|
||||
}
|
||||
|
||||
/*bool AsyncJpegStreamResponse::_sourceValid() {
|
||||
return true;
|
||||
}*/
|
||||
|
||||
size_t AsyncJpegStreamResponse::_fillBuffer(uint8_t *buf, size_t maxLen) {
|
||||
size_t ret = _content(buf, maxLen, _index);
|
||||
if(ret != RESPONSE_TRY_AGAIN){
|
||||
_index += ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t AsyncJpegStreamResponse::_content(uint8_t *buffer, size_t maxLen, size_t index){
|
||||
if(!_frame.fb || _frame.index == _jpg_buf_len) {
|
||||
if(index && _frame.fb){
|
||||
uint64_t end = (uint64_t)micros();
|
||||
int fp = (end - lastAsyncRequest) / 1000;
|
||||
log_printf("Size: %uKB, Time: %ums (%.1ffps)\n", _jpg_buf_len/1024, 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(STREAM_BOUNDARY) + strlen(STREAM_PART) + strlen(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(STREAM_BOUNDARY);
|
||||
memcpy(buffer, STREAM_BOUNDARY, blen);
|
||||
buffer += blen;
|
||||
}
|
||||
//send header
|
||||
size_t hlen = sprintf((char *)buffer, STREAM_PART, 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;
|
||||
}
|
||||
|
||||
|
||||
void streamJpg(AsyncWebServerRequest *request){
|
||||
AsyncJpegStreamResponse *response = new AsyncJpegStreamResponse();
|
||||
if(!response){
|
||||
request->send(501);
|
||||
return;
|
||||
}
|
||||
request->send(response);
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
#include <servo.h>
|
||||
#include <camera_pins.h>
|
||||
#include <esp_camera.h>
|
||||
|
||||
esp_err_t InitializeCamera(){
|
||||
camera_config_t camera_config;
|
||||
camera_config.ledc_channel = LEDC_CHANNEL_0;
|
||||
camera_config.ledc_timer = LEDC_TIMER_0;
|
||||
camera_config.pin_d0 = Y2_GPIO_NUM;
|
||||
camera_config.pin_d1 = Y3_GPIO_NUM;
|
||||
camera_config.pin_d2 = Y4_GPIO_NUM;
|
||||
camera_config.pin_d3 = Y5_GPIO_NUM;
|
||||
camera_config.pin_d4 = Y6_GPIO_NUM;
|
||||
camera_config.pin_d5 = Y7_GPIO_NUM;
|
||||
camera_config.pin_d6 = Y8_GPIO_NUM;
|
||||
camera_config.pin_d7 = Y9_GPIO_NUM;
|
||||
camera_config.pin_xclk = XCLK_GPIO_NUM;
|
||||
camera_config.pin_pclk = PCLK_GPIO_NUM;
|
||||
camera_config.pin_vsync = VSYNC_GPIO_NUM;
|
||||
camera_config.pin_href = HREF_GPIO_NUM;
|
||||
camera_config.pin_sscb_sda = SIOD_GPIO_NUM;
|
||||
camera_config.pin_sscb_scl = SIOC_GPIO_NUM;
|
||||
camera_config.pin_pwdn = PWDN_GPIO_NUM;
|
||||
camera_config.pin_reset = RESET_GPIO_NUM;
|
||||
camera_config.xclk_freq_hz = 20000000;
|
||||
camera_config.pixel_format = PIXFORMAT_JPEG;
|
||||
|
||||
if(psramFound()){
|
||||
camera_config.frame_size = FRAMESIZE_SVGA;
|
||||
camera_config.jpeg_quality = 10;
|
||||
camera_config.fb_count = 2;
|
||||
} else {
|
||||
camera_config.frame_size = FRAMESIZE_SVGA;
|
||||
camera_config.jpeg_quality = 12;
|
||||
camera_config.fb_count = 1;
|
||||
}
|
||||
|
||||
log_i("Initializing camera");
|
||||
esp_err_t err = esp_camera_init(&camera_config);
|
||||
if (err != ESP_OK) log_e("Camera probe failed with error 0x%x", err);
|
||||
|
||||
return err;
|
||||
}
|
||||
Binary file not shown.
@@ -1,55 +0,0 @@
|
||||
#include <HTTPClient.h>
|
||||
#include <UrlEncode.h>
|
||||
#include <globals.h>
|
||||
#include <deviceconfig.h>
|
||||
#include <secrets.h>
|
||||
|
||||
DRAM_ATTR std::unique_ptr<DeviceConfig> g_ptrDeviceConfig;
|
||||
|
||||
DRAM_ATTR size_t g_DeviceConfigJSONBufferSize = 0;
|
||||
|
||||
void DeviceConfig::SaveToJSON()
|
||||
{
|
||||
g_ptrJSONWriter->FlagWriter(writerIndex);
|
||||
}
|
||||
|
||||
DeviceConfig::DeviceConfig()
|
||||
{
|
||||
// Add SettingSpec for additional settings to this list
|
||||
settingSpecs.emplace_back(
|
||||
NAME_OF(ntpServer),
|
||||
"NTP server address",
|
||||
"The hostname or IP address of the NTP server to be used for time synchronization.",
|
||||
SettingSpec::SettingType::String
|
||||
);
|
||||
settingSpecs.emplace_back(
|
||||
NAME_OF(useMetric),
|
||||
"Use metric system",
|
||||
"A boolean that indicates if unit should be shown in metric ('true'/1) or imperial ('false'/0) format.",
|
||||
SettingSpec::SettingType::Boolean
|
||||
);
|
||||
|
||||
log_i("about to write");
|
||||
writerIndex = g_ptrJSONWriter->RegisterWriter(
|
||||
[this]() { SaveToJSONFile(DEVICE_CONFIG_FILE, g_DeviceConfigJSONBufferSize, *this); }
|
||||
);
|
||||
|
||||
std::unique_ptr<AllocatedJsonDocument> pJsonDoc(nullptr);
|
||||
|
||||
if (LoadJSONFile(DEVICE_CONFIG_FILE, g_DeviceConfigJSONBufferSize, pJsonDoc))
|
||||
{
|
||||
log_i("Loading DeviceConfig from JSON");
|
||||
|
||||
DeserializeFromJSON(pJsonDoc->as<JsonObjectConst>(), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_w("DeviceConfig could not be loaded from JSON, using defaults");
|
||||
|
||||
// Set default for additional settings in this code
|
||||
ntpServer = DEFAULT_NTP_SERVER;
|
||||
|
||||
SaveToJSON();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,177 +0,0 @@
|
||||
#include <globals.h>
|
||||
#include <SPIFFS.h>
|
||||
#include <jsonserializer.h>
|
||||
#include <taskmanager.h>
|
||||
|
||||
DRAM_ATTR std::unique_ptr<JSONWriter> g_ptrJSONWriter = nullptr;
|
||||
|
||||
bool LoadJSONFile(const char *fileName, size_t& bufferSize, std::unique_ptr<AllocatedJsonDocument>& pJsonDoc)
|
||||
{
|
||||
bool jsonReadSuccessful = false;
|
||||
|
||||
File file = SPIFFS.open(fileName);
|
||||
|
||||
if (file)
|
||||
{
|
||||
if (file.size() > 0)
|
||||
{
|
||||
log_i("Attempting to read JSON file %s", fileName);
|
||||
|
||||
if (bufferSize == 0)
|
||||
bufferSize = std::max((size_t)JSON_BUFFER_BASE_SIZE, file.size());
|
||||
|
||||
// Loop is here to deal with out of memory conditions
|
||||
while(true)
|
||||
{
|
||||
pJsonDoc.reset(new AllocatedJsonDocument(bufferSize));
|
||||
|
||||
DeserializationError error = deserializeJson(*pJsonDoc, file);
|
||||
|
||||
if (error == DeserializationError::NoMemory)
|
||||
{
|
||||
pJsonDoc.reset(nullptr);
|
||||
file.seek(0);
|
||||
bufferSize += JSON_BUFFER_INCREMENT;
|
||||
|
||||
log_w("Out of memory reading JSON from file %s - increasing buffer to %zu bytes", fileName, bufferSize);
|
||||
}
|
||||
else if (error == DeserializationError::Ok)
|
||||
{
|
||||
jsonReadSuccessful = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_w("Error with code %d occurred while deserializing JSON from file %s", to_value(error.code()), fileName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
return jsonReadSuccessful;
|
||||
}
|
||||
|
||||
void SerializeWithBufferSize(std::unique_ptr<AllocatedJsonDocument>& pJsonDoc, size_t& bufferSize, std::function<bool(JsonObject&)> serializationFunction)
|
||||
{
|
||||
// Loop is here to deal with out of memory conditions
|
||||
while(true)
|
||||
{
|
||||
pJsonDoc.reset(new AllocatedJsonDocument(bufferSize));
|
||||
JsonObject jsonObject = pJsonDoc->to<JsonObject>();
|
||||
|
||||
if (serializationFunction(jsonObject))
|
||||
break;
|
||||
|
||||
pJsonDoc.reset(nullptr);
|
||||
bufferSize += JSON_BUFFER_INCREMENT;
|
||||
|
||||
log_w("Out of memory serializing object - increasing buffer to %zu bytes", bufferSize);
|
||||
}
|
||||
}
|
||||
|
||||
bool SaveToJSONFile(const char *fileName, size_t& bufferSize, IJSONSerializable& object)
|
||||
{
|
||||
if (bufferSize == 0)
|
||||
bufferSize = JSON_BUFFER_BASE_SIZE;
|
||||
|
||||
std::unique_ptr<AllocatedJsonDocument> pJsonDoc(nullptr);
|
||||
|
||||
SerializeWithBufferSize(pJsonDoc, bufferSize, [&object](JsonObject& jsonObject) { return object.SerializeToJSON(jsonObject); });
|
||||
|
||||
SPIFFS.remove(fileName);
|
||||
|
||||
File file = SPIFFS.open(fileName, FILE_WRITE);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
log_e("Unable to open file %s to write JSON!", fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t bytesWritten = serializeJson(*pJsonDoc, file);
|
||||
log_i("Number of bytes written to JSON file %s: %d", fileName, bytesWritten);
|
||||
|
||||
file.flush();
|
||||
file.close();
|
||||
|
||||
if (bytesWritten == 0)
|
||||
{
|
||||
log_e("Unable to write JSON to file %s!", fileName);
|
||||
SPIFFS.remove(fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
file = SPIFFS.open(fileName);
|
||||
if (file)
|
||||
{
|
||||
while (file.available())
|
||||
Serial.write(file.read());
|
||||
|
||||
file.close();
|
||||
}
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RemoveJSONFile(const char *fileName)
|
||||
{
|
||||
return SPIFFS.remove(fileName);
|
||||
}
|
||||
|
||||
size_t JSONWriter::RegisterWriter(std::function<void()> writer)
|
||||
{
|
||||
// Add the writer with its flag unset
|
||||
writers.emplace_back(writer);
|
||||
return writers.size() - 1;
|
||||
}
|
||||
|
||||
void JSONWriter::FlagWriter(size_t index)
|
||||
{
|
||||
// Check if we received a valid writer index
|
||||
if (index >= writers.size())
|
||||
return;
|
||||
|
||||
writers[index].flag = true;
|
||||
latestFlagMs = millis();
|
||||
|
||||
g_TaskManager.NotifyJSONWriterThread();
|
||||
}
|
||||
|
||||
// JSONWriterTaskEntry
|
||||
//
|
||||
// Invoke functions that write serialized JSON objects to SPIFFS at request, with some delay
|
||||
void IRAM_ATTR JSONWriterTaskEntry(void *)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
TickType_t notifyWait = portMAX_DELAY;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
// Wait until we're woken up by a writer being flagged, or until we've reached the hold point
|
||||
ulTaskNotifyTake(pdTRUE, notifyWait);
|
||||
|
||||
if (!g_ptrJSONWriter)
|
||||
continue;
|
||||
|
||||
unsigned long holdUntil = g_ptrJSONWriter->latestFlagMs + JSON_WRITER_DELAY;
|
||||
unsigned long now = millis();
|
||||
if (now >= holdUntil)
|
||||
break;
|
||||
|
||||
notifyWait = pdMS_TO_TICKS(holdUntil - now);
|
||||
}
|
||||
|
||||
for (auto &entry : g_ptrJSONWriter->writers)
|
||||
{
|
||||
// Unset flag before we do the actual write. This makes that we don't miss another flag raise if it happens while writing
|
||||
if (entry.flag.exchange(false))
|
||||
entry.writer();
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-23
@@ -1,32 +1,18 @@
|
||||
#include <globals.h>
|
||||
#include <deviceconfig.h>
|
||||
#include <ESP32SvelteKit.h>
|
||||
#include <PsychicHttpServer.h>
|
||||
|
||||
#define SERIAL_BAUD_RATE 115200
|
||||
|
||||
ESPTaskManager g_TaskManager;
|
||||
#if USE_WIFI && USE_WEBSERVER
|
||||
DRAM_ATTR CWebServer g_WebServer;
|
||||
#endif
|
||||
PsychicHttpServer server;
|
||||
|
||||
ESP32SvelteKit esp32sveltekit(&server, 120);
|
||||
|
||||
void setup() {
|
||||
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
|
||||
Serial.begin(BAUDRATE);
|
||||
log_i("Booting");
|
||||
SPIFFS.begin();
|
||||
Wire.begin(SDA, SCL);
|
||||
InitializeCamera();
|
||||
g_TaskManager.begin();
|
||||
g_TaskManager.StartThreads();
|
||||
Serial.begin(SERIAL_BAUD_RATE);
|
||||
|
||||
g_ptrJSONWriter = std::make_unique<JSONWriter>();
|
||||
g_ptrDeviceConfig = std::make_unique<DeviceConfig>();
|
||||
g_ptrServo = std::make_unique<Servo>();
|
||||
|
||||
g_ptrServo->begin();
|
||||
g_ptrServo->setOscillatorFrequency(SERVO_OSCILLATOR_FREQUENCY);
|
||||
g_ptrServo->setPWMFreq(SERVO_FREQ);
|
||||
g_ptrServo->updateServos();
|
||||
esp32sveltekit.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
delay(200);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
#include <featureflags.h>
|
||||
#if USE_MPU
|
||||
#include <MPU6050_light.h>
|
||||
#include <Adafruit_Sensor.h>
|
||||
#include <Adafruit_HMC5883_U.h>
|
||||
#endif
|
||||
|
||||
#if USE_POWER_BUTTON
|
||||
#include <Bounce2.h>
|
||||
#endif
|
||||
|
||||
#if USE_POWER_BUTTON
|
||||
Bounce2::Button PowerButton;
|
||||
#endif
|
||||
|
||||
#if USE_MPU
|
||||
DRAM_ATTR MPU6050 g_imu(Wire);
|
||||
DRAM_ATTR Adafruit_HMC5883_Unified g_mag = Adafruit_HMC5883_Unified(12345);
|
||||
#endif
|
||||
|
||||
void beginMag() {
|
||||
if(!g_mag.begin()) log_w("Failed to initialize HMC5883L");
|
||||
}
|
||||
|
||||
void beginImu() {
|
||||
byte status = g_imu.begin();
|
||||
if(status != 0) log_w("MPU initialize failed");
|
||||
delay(100);
|
||||
g_imu.calcOffsets(true,true);
|
||||
}
|
||||
|
||||
float getHeading() {
|
||||
sensors_event_t event;
|
||||
g_mag.getEvent(&event);
|
||||
|
||||
float heading = atan2(event.magnetic.y, event.magnetic.x);
|
||||
float declinationAngle = 0.22;
|
||||
heading += declinationAngle;
|
||||
if(heading < 0) heading += 2*PI;
|
||||
if(heading > 2*PI) heading -= 2*PI;
|
||||
return heading * 180/M_PI;
|
||||
}
|
||||
|
||||
float getTemp() {
|
||||
return g_imu.getTemp();
|
||||
}
|
||||
|
||||
float getAngleX() {
|
||||
return g_imu.getAngleX();
|
||||
}
|
||||
|
||||
float getAngleY() {
|
||||
return g_imu.getAngleX();
|
||||
}
|
||||
|
||||
float getAngleZ() {
|
||||
return g_imu.getAngleZ();
|
||||
}
|
||||
|
||||
void IRAM_ATTR MovementHandlingLoopEntry(void *) {
|
||||
TickType_t notifyWait = 0;
|
||||
beginMag();
|
||||
beginImu();
|
||||
|
||||
for (;;) {
|
||||
g_imu.update();
|
||||
ulTaskNotifyTake(pdTRUE, notifyWait);
|
||||
|
||||
// #if USE_POWER_BUTTON
|
||||
// PowerButton.update();
|
||||
// if (PowerButton.pressed()) {
|
||||
// log_i("Power Button Pressed");
|
||||
// g_ptrServo->toggleState();
|
||||
// }
|
||||
// #endif
|
||||
|
||||
notifyWait = pdMS_TO_TICKS(100);
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
#include <globals.h>
|
||||
#include <deviceconfig.h>
|
||||
|
||||
#if USE_WIFI && USE_WEBSERVER
|
||||
extern DRAM_ATTR CWebServer g_WebServer;
|
||||
#endif
|
||||
|
||||
#if USE_WIFI
|
||||
|
||||
bool ConnectToWiFi(uint cRetries) {
|
||||
static bool bPreviousConnection = false;
|
||||
|
||||
if (WiFi.isConnected()) return true;
|
||||
|
||||
log_i("Connection to wifi");
|
||||
WiFi.disconnect();
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.setHostname(HOSTNAME);
|
||||
|
||||
for (uint iPass = 0; iPass < cRetries; iPass++) {
|
||||
log_i("Pass %u of %u: Connecting to Wifi SSID: \"%s\" - ESP32 Free Memory: %u, PSRAM:%u, PSRAM Free: %u\n",
|
||||
iPass + 1, cRetries, SSID, ESP.getFreeHeap(), ESP.getPsramSize(), ESP.getFreePsram());
|
||||
|
||||
WiFi.begin(SSID, PASS);
|
||||
delay(4000 + iPass * 1000);
|
||||
|
||||
if (WiFi.isConnected()) {
|
||||
log_i("Connected to AP with BSSID: %s\n", WiFi.BSSIDstr().c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Additional Services onwwards reliant on network so close if not up.
|
||||
if (false == WiFi.isConnected()) {
|
||||
log_i("Giving up on WiFi\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
log_i("Received IP: %s", WiFi.localIP().toString().c_str());
|
||||
|
||||
// If we were connected before, network-dependent services will have been started already
|
||||
if (bPreviousConnection)
|
||||
return true;
|
||||
|
||||
#if USE_OTA
|
||||
//debugI("Publishing OTA...");
|
||||
SetupOTA(String(cszHostname));
|
||||
#endif
|
||||
|
||||
#if USE_NTP
|
||||
//debugI("Setting Clock...");
|
||||
//NTPTimeClient::UpdateClockFromWeb(&g_Udp);
|
||||
#endif
|
||||
|
||||
#if USE_WEBSERVER
|
||||
g_WebServer.begin();
|
||||
#endif
|
||||
|
||||
#if USE_MDNS
|
||||
if(MDNS.begin(HOSTNAME)){
|
||||
MDNS.addService("http", "tcp", HTTP_PORT);
|
||||
}
|
||||
#endif
|
||||
|
||||
bPreviousConnection = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void IRAM_ATTR NetworkHandlingLoopEntry(void *) {
|
||||
unsigned long lastWifiCheck = 0;
|
||||
unsigned long checkWiFiEveryMs = 1000;
|
||||
|
||||
TickType_t notifyWait = 0;
|
||||
|
||||
for (;;) {
|
||||
ulTaskNotifyTake(pdTRUE, notifyWait);
|
||||
|
||||
if ( millis() - lastWifiCheck > checkWiFiEveryMs) {
|
||||
if (WiFi.isConnected() == false && ConnectToWiFi(5) == false) {
|
||||
log_e("Cannot Connect to Wifi!");
|
||||
#if WAIT_FOR_WIFI
|
||||
log_e("Rebooting in 5 seconds due to no Wifi available.");
|
||||
delay(5000);
|
||||
throw new std::runtime_error("Rebooting due to no Wifi available.");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#if USE_WEBSERVER
|
||||
g_WebServer.loop();
|
||||
#endif
|
||||
|
||||
notifyWait = pdMS_TO_TICKS(1000);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ENABLE_WIFI
|
||||
@@ -1,3 +0,0 @@
|
||||
#include <servo.h>
|
||||
|
||||
DRAM_ATTR std::unique_ptr<Servo> g_ptrServo;
|
||||
@@ -1,346 +0,0 @@
|
||||
#include "globals.h"
|
||||
#include "webserver.h"
|
||||
|
||||
// Maps settings for which a validator is available to the invocation thereof
|
||||
const std::map<String, CWebServer::ValueValidator> CWebServer::settingValidators
|
||||
{};
|
||||
|
||||
std::vector<SettingSpec> CWebServer::deviceSettingSpecs{};
|
||||
|
||||
// Member function template specialzations
|
||||
|
||||
// Push param that represents a bool. Values considered true are text "true" and any whole number not equal to 0
|
||||
template<>
|
||||
bool CWebServer::PushPostParamIfPresent<bool>(AsyncWebServerRequest * pRequest, const String ¶mName, ValueSetter<bool> setter)
|
||||
{
|
||||
return PushPostParamIfPresent<bool>(pRequest, paramName, setter, [](AsyncWebParameter * param) constexpr
|
||||
{
|
||||
const String& value = param->value();
|
||||
return value == "true" || strtol(value.c_str(), NULL, 10);
|
||||
});
|
||||
}
|
||||
|
||||
// Push param that represents a size_t
|
||||
template<>
|
||||
bool CWebServer::PushPostParamIfPresent<size_t>(AsyncWebServerRequest * pRequest, const String ¶mName, ValueSetter<size_t> setter)
|
||||
{
|
||||
return PushPostParamIfPresent<size_t>(pRequest, paramName, setter, [](AsyncWebParameter * param) constexpr
|
||||
{
|
||||
return strtoul(param->value().c_str(), NULL, 10);
|
||||
});
|
||||
}
|
||||
|
||||
// Add CORS header to and send JSON response
|
||||
template<>
|
||||
void CWebServer::AddCORSHeaderAndSendResponse<AsyncJsonResponse>(AsyncWebServerRequest * pRequest, AsyncJsonResponse * pResponse)
|
||||
{
|
||||
pResponse->setLength();
|
||||
AddCORSHeaderAndSendResponse<AsyncWebServerResponse>(pRequest, pResponse);
|
||||
}
|
||||
|
||||
// Member function implementations
|
||||
|
||||
bool CWebServer::IsPostParamTrue(AsyncWebServerRequest * pRequest, const String & paramName)
|
||||
{
|
||||
bool returnValue = false;
|
||||
|
||||
PushPostParamIfPresent<bool>(pRequest, paramName, [&returnValue](auto value) { returnValue = value; return true; });
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
void CWebServer::GetStatistics(AsyncWebServerRequest * pRequest)
|
||||
{
|
||||
log_v("GetStatistics");
|
||||
|
||||
auto response = new AsyncJsonResponse(false, JSON_BUFFER_BASE_SIZE);
|
||||
auto j = response->getRoot();
|
||||
|
||||
j["HEAP_SIZE"] = _staticStats.HeapSize;
|
||||
j["HEAP_FREE"] = ESP.getFreeHeap();
|
||||
j["HEAP_MIN"] = ESP.getMinFreeHeap();
|
||||
|
||||
j["DMA_SIZE"] = _staticStats.DmaHeapSize;
|
||||
j["DMA_FREE"] = heap_caps_get_free_size(MALLOC_CAP_DMA);
|
||||
j["DMA_MIN"] = heap_caps_get_largest_free_block(MALLOC_CAP_DMA);
|
||||
|
||||
j["PSRAM_SIZE"] = _staticStats.PsramSize;
|
||||
j["PSRAM_FREE"] = ESP.getFreePsram();
|
||||
j["PSRAM_MIN"] = ESP.getMinFreePsram();
|
||||
|
||||
j["CHIP_MODEL"] = _staticStats.ChipModel;
|
||||
j["CHIP_CORES"] = _staticStats.ChipCores;
|
||||
j["CHIP_SPEED"] = _staticStats.CpuFreqMHz;
|
||||
j["PROG_SIZE"] = _staticStats.SketchSize;
|
||||
|
||||
j["CODE_SIZE"] = _staticStats.SketchSize;
|
||||
j["CODE_FREE"] = _staticStats.FreeSketchSpace;
|
||||
j["FLASH_SIZE"] = _staticStats.FlashChipSize;
|
||||
|
||||
j["CPU_USED"] = g_TaskManager.GetCPUUsagePercent();
|
||||
j["CPU_USED_CORE0"] = g_TaskManager.GetCPUUsagePercent(0);
|
||||
j["CPU_USED_CORE1"] = g_TaskManager.GetCPUUsagePercent(1);
|
||||
|
||||
AddCORSHeaderAndSendResponse(pRequest, response);
|
||||
}
|
||||
|
||||
void CWebServer::SendSettingSpecsResponse(AsyncWebServerRequest * pRequest, const std::vector<SettingSpec> & settingSpecs)
|
||||
{
|
||||
static size_t jsonBufferSize = JSON_BUFFER_BASE_SIZE;
|
||||
bool bufferOverflow;
|
||||
|
||||
do
|
||||
{
|
||||
bufferOverflow = false;
|
||||
auto response = std::make_unique<AsyncJsonResponse>(false, jsonBufferSize);
|
||||
auto jsonArray = response->getRoot().to<JsonArray>();
|
||||
|
||||
for (auto& spec : settingSpecs)
|
||||
{
|
||||
auto specObject = jsonArray.createNestedObject();
|
||||
|
||||
StaticJsonDocument<384> jsonDoc;
|
||||
|
||||
jsonDoc["name"] = spec.Name;
|
||||
jsonDoc["friendlyName"] = spec.FriendlyName;
|
||||
jsonDoc["description"] = spec.Description;
|
||||
jsonDoc["type"] = to_value(spec.Type);
|
||||
jsonDoc["typeName"] = spec.ToName(spec.Type);
|
||||
|
||||
if (!specObject.set(jsonDoc.as<JsonObjectConst>()))
|
||||
{
|
||||
bufferOverflow = true;
|
||||
jsonBufferSize += JSON_BUFFER_INCREMENT;
|
||||
log_v("JSON response buffer overflow! Increased buffer to %zu bytes", jsonBufferSize);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bufferOverflow)
|
||||
AddCORSHeaderAndSendResponse(pRequest, response.release());
|
||||
|
||||
} while (bufferOverflow);
|
||||
}
|
||||
|
||||
const std::vector<SettingSpec> & CWebServer::LoadDeviceSettingSpecs()
|
||||
{
|
||||
if (deviceSettingSpecs.size() == 0)
|
||||
{
|
||||
auto deviceConfigSpecs = g_ptrDeviceConfig->GetSettingSpecs();
|
||||
deviceSettingSpecs.insert(deviceSettingSpecs.end(), deviceConfigSpecs.begin(), deviceConfigSpecs.end());
|
||||
}
|
||||
|
||||
return deviceSettingSpecs;
|
||||
}
|
||||
|
||||
void CWebServer::GetSettingSpecs(AsyncWebServerRequest * pRequest)
|
||||
{
|
||||
SendSettingSpecsResponse(pRequest, LoadDeviceSettingSpecs());
|
||||
}
|
||||
|
||||
// Responds with current config, excluding any sensitive values
|
||||
void CWebServer::GetSettings(AsyncWebServerRequest * pRequest)
|
||||
{
|
||||
log_v("GetSettings");
|
||||
|
||||
auto response = new AsyncJsonResponse(false, JSON_BUFFER_BASE_SIZE);
|
||||
response->addHeader("Server","NightDriverStrip");
|
||||
auto root = response->getRoot();
|
||||
JsonObject jsonObject = root.to<JsonObject>();
|
||||
|
||||
// We get the serialized JSON for the device config, without any sensitive values
|
||||
g_ptrDeviceConfig->SerializeToJSON(jsonObject, false);
|
||||
|
||||
AddCORSHeaderAndSendResponse(pRequest, response);
|
||||
}
|
||||
|
||||
// Support function that silently sets whatever settings are included in the request passed.
|
||||
// Composing a response is left to the invoker!
|
||||
void CWebServer::SetSettingsIfPresent(AsyncWebServerRequest * pRequest)
|
||||
{
|
||||
PushPostParamIfPresent<String>(pRequest, DeviceConfig::NTPServerTag, SET_VALUE(g_ptrDeviceConfig->SetNTPServer(value)));
|
||||
}
|
||||
|
||||
// Set settings and return resulting config
|
||||
void CWebServer::SetSettings(AsyncWebServerRequest * pRequest)
|
||||
{
|
||||
log_v("SetSettings");
|
||||
|
||||
SetSettingsIfPresent(pRequest);
|
||||
|
||||
// We return the current config in response
|
||||
GetSettings(pRequest);
|
||||
}
|
||||
|
||||
// Save the posted file to SPIFFS
|
||||
void CWebServer::SaveFile(AsyncWebServerRequest* request, String filename, size_t index, uint8_t* data, size_t len, bool final)
|
||||
{
|
||||
log_v("SaveFile");
|
||||
}
|
||||
|
||||
#if USE_OAT
|
||||
// Update the current firmware
|
||||
void CWebServer::UpdateFileSystemImage(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final)
|
||||
{
|
||||
log_v("UpdateFileSystemImage");
|
||||
|
||||
HandleUpdate(request, filename, index, data, len, final, (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000, U_FLASH);
|
||||
}
|
||||
|
||||
// Update the current firmware
|
||||
void CWebServer::UpdateFirmware(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final)
|
||||
{
|
||||
log_v("UpdateFirmware");
|
||||
|
||||
HandleUpdate(request, filename, index, data, len, final, UPDATE_SIZE_UNKNOWN, U_SPIFFS);
|
||||
}
|
||||
|
||||
// Handles updating the filesystem image or firmware
|
||||
void CWebServer::HandleUpdate(AsyncWebServerRequest* request, String filename, size_t index, uint8_t* data, size_t len, bool final, size_t upload_size, uint8_t upload_index) {
|
||||
if (!index) {
|
||||
log_i("Update Start: %s\n", filename.c_str());
|
||||
log_i("Uploading: %d", upload_index);
|
||||
if (!Update.begin(upload_size, upload_index)) {
|
||||
Update.printError(Serial);
|
||||
}
|
||||
}
|
||||
if (!Update.hasError()) {
|
||||
if (Update.write(data, len) != len) {
|
||||
Update.printError(Serial);
|
||||
}
|
||||
}
|
||||
if (final) {
|
||||
if (Update.end(true)) {
|
||||
log_i("Update Success: %uB\n", index + len);
|
||||
}
|
||||
else {
|
||||
Update.printError(Serial);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ensures the request gets send to the client
|
||||
void CWebServer::UpdateRequestHandler(AsyncWebServerRequest* request){
|
||||
bool success = !Update.hasError();
|
||||
AsyncWebServerResponse* response = request->beginResponse(200, "text/plain", success ? "OK" : "FAIL");
|
||||
response->addHeader("Connection", "close");
|
||||
request->send(response);
|
||||
|
||||
if (success) {
|
||||
delay(250);
|
||||
ESP.restart();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Reset effect config, device config and/or the board itself
|
||||
void CWebServer::Reset(AsyncWebServerRequest * pRequest)
|
||||
{
|
||||
if (IsPostParamTrue(pRequest, "deviceConfig"))
|
||||
{
|
||||
log_i("Removing DeviceConfig");
|
||||
g_ptrDeviceConfig->RemovePersisted();
|
||||
}
|
||||
|
||||
bool boardResetRequested = IsPostParamTrue(pRequest, "board");
|
||||
|
||||
AddCORSHeaderAndSendOKResponse(pRequest);
|
||||
|
||||
if (boardResetRequested)
|
||||
{
|
||||
log_w("Resetting device at API request!");
|
||||
delay(1000); // Give the response a second to be sent
|
||||
throw new std::runtime_error("Resetting device at API request");
|
||||
}
|
||||
}
|
||||
|
||||
String dir(void) {
|
||||
String x = "<table>";
|
||||
File root = SPIFFS.open("/");
|
||||
if(!root) {
|
||||
return "Failed to open directory";
|
||||
}
|
||||
if(!root.isDirectory()) {
|
||||
return "Not a directory";
|
||||
}
|
||||
File file = root.openNextFile();
|
||||
while(file) {
|
||||
x += "<tr><td>"+String(file.name());
|
||||
if(file.isDirectory()){
|
||||
x += "<td>DIR";
|
||||
} else {
|
||||
x += "<td style='text-align:right'>"+String(file.size());
|
||||
}
|
||||
file = root.openNextFile();
|
||||
}
|
||||
x += "<tr><td>Occupied space<td style='text-align:right'>"+String(SPIFFS.usedBytes());
|
||||
x += "<tr><td>Total space<td style='text-align:right'>"+String(SPIFFS.totalBytes());
|
||||
return x+"</table>";
|
||||
}
|
||||
|
||||
// Send Gzip SPA
|
||||
void CWebServer::GzipSpa(AsyncWebServerRequest * pRequest)
|
||||
{
|
||||
if(!SPIFFS.exists("/index.html.gz")){
|
||||
log_e("Gzipped SPA not found");
|
||||
pRequest->send(404, "text/html", dir());
|
||||
return;
|
||||
}
|
||||
|
||||
AsyncWebServerResponse *response = pRequest->beginResponse(SPIFFS, "/index.html.gz", "text/html", false);
|
||||
response->addHeader("Content-Encoding", "gzip");
|
||||
response->addHeader("Cache-Control"," max-age=86400");
|
||||
AddCORSHeaderAndSendResponse(pRequest, response);
|
||||
}
|
||||
|
||||
enum Action {
|
||||
SERVO_UPDATE,
|
||||
};
|
||||
|
||||
void handleWebSocketJson(uint8_t* data) {
|
||||
const uint8_t size = JSON_OBJECT_SIZE(1);
|
||||
StaticJsonDocument<100> json;
|
||||
DeserializationError err = deserializeJson(json, data);
|
||||
if (err) {
|
||||
Serial.print(F("deserializeJson() failed with code "));
|
||||
Serial.println(err.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
const uint8_t action = json["action"];
|
||||
|
||||
if(action == 0) {
|
||||
const uint8_t servoIndex = json["servo"];
|
||||
const int16_t pwm = json["pwm"];
|
||||
log_i("Moving servo:%u to pwm%u", servoIndex, pwm);
|
||||
g_ptrServo->setPWM(servoIndex, 0, pwm);
|
||||
}
|
||||
}
|
||||
|
||||
void handleWebSocketBuffer(uint8_t* data) {
|
||||
if(data[0] == 0) g_ptrServo->setBody(data[1], data[2], data[3], data[4], data[5], data[6]);
|
||||
else if(data[0] == 1) {
|
||||
log_i("About to update all servos");
|
||||
int16_t* angles = (int16_t*)data+1;
|
||||
|
||||
g_ptrServo->SetAngles(angles);
|
||||
}
|
||||
}
|
||||
|
||||
void handleWebSocketMessage(void* arg, uint8_t* data, size_t len, AsyncWebSocket* server, AsyncWebSocketClient* client) {
|
||||
AwsFrameInfo* info = (AwsFrameInfo*)arg;
|
||||
if(info->final && info->index == 0 && info->len == len){
|
||||
if(info->opcode == WS_TEXT) handleWebSocketJson(data);
|
||||
else handleWebSocketBuffer(data);
|
||||
}
|
||||
}
|
||||
|
||||
// Reset effect config, device config and/or the board itself
|
||||
void CWebServer::HandleWsMessage(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len)
|
||||
{
|
||||
//if (type == WS_EVT_CONNECT) handleNewConnection(server, client);
|
||||
/*else*/ if (type == WS_EVT_DISCONNECT) log_i("ws[%s][%u] disconnect\n", server->url(), client->id());
|
||||
else if (type == WS_EVT_ERROR) log_i("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data);
|
||||
else if (type == WS_EVT_PONG) log_i("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len) ? (char*)data : "");
|
||||
else if (type == WS_EVT_DATA) handleWebSocketMessage(arg, data, len, server, client);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
|
||||
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
||||
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
|
||||
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
|
||||
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
|
||||
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
|
||||
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
|
||||
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
|
||||
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
|
||||
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
|
||||
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
|
||||
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
|
||||
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
|
||||
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
|
||||
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
|
||||
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
|
||||
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
|
||||
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
|
||||
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
|
||||
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
|
||||
-----END CERTIFICATE-----
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user