diff --git a/client/ESPcam/.idea/misc.xml b/client/ESPcam/.idea/misc.xml index 6e1c9f37b93d78b6c09407d34dc9e55175665cd7..79b3c94830bab93d40d0770f2765540fe24ed423 100644 --- a/client/ESPcam/.idea/misc.xml +++ b/client/ESPcam/.idea/misc.xml @@ -1,6 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> <project version="4"> - <component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$"> - <contentRoot DIR="$PROJECT_DIR$/.." /> - </component> + <component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" /> </project> \ No newline at end of file diff --git a/client/ESPcam/CMakeLists.txt b/client/ESPcam/CMakeLists.txt deleted file mode 100644 index 09129ea1d8cb31d661b5f0903019ed910e3d1483..0000000000000000000000000000000000000000 --- a/client/ESPcam/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -# !!! WARNING !!! AUTO-GENERATED FILE, PLEASE DO NOT MODIFY IT AND USE -# https://docs.platformio.org/page/projectconf/section_env_build.html#build-flags -# -# If you need to override existing CMake configuration or add extra, -# please create `CMakeListsUser.txt` in the root of project. -# The `CMakeListsUser.txt` will not be overwritten by PlatformIO. - -cmake_minimum_required(VERSION 3.13) -set(CMAKE_SYSTEM_NAME Generic) -set(CMAKE_C_COMPILER_WORKS 1) -set(CMAKE_CXX_COMPILER_WORKS 1) - -project("ESPcam" C CXX) - -include(CMakeListsPrivate.txt) - -if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/CMakeListsUser.txt) -include(CMakeListsUser.txt) -endif() - -add_custom_target( - Production ALL - COMMAND platformio -c clion run "$<$<NOT:$<CONFIG:All>>:-e${CMAKE_BUILD_TYPE}>" - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} -) - -add_custom_target( - Debug ALL - COMMAND platformio -c clion debug "$<$<NOT:$<CONFIG:All>>:-e${CMAKE_BUILD_TYPE}>" - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} -) - -add_executable(Z_DUMMY_TARGET ${SRC_LIST}) diff --git a/client/ESPcam/CMakeListsPrivate.txt b/client/ESPcam/CMakeListsPrivate.txt deleted file mode 100644 index 2c27268f2f0e34564668c2926a94775303a907e8..0000000000000000000000000000000000000000 --- a/client/ESPcam/CMakeListsPrivate.txt +++ /dev/null @@ -1,305 +0,0 @@ -# !!! WARNING !!! AUTO-GENERATED FILE, PLEASE DO NOT MODIFY IT AND USE -# https://docs.platformio.org/page/projectconf/section_env_build.html#build-flags -# -# If you need to override existing CMake configuration or add extra, -# please create `CMakeListsUser.txt` in the root of project. -# The `CMakeListsUser.txt` will not be overwritten by PlatformIO. - - - -set(CMAKE_CONFIGURATION_TYPES "esp32cam" CACHE STRING "Build Types reflect PlatformIO Environments" FORCE) - -# Convert "Home Directory" that may contain unescaped backslashes on Windows - - -SET(CMAKE_C_COMPILER "$ENV{HOME}/.platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-gcc") -SET(CMAKE_CXX_COMPILER "$ENV{HOME}/.platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-g++") -SET(CMAKE_CXX_FLAGS "-std=gnu++17 -Wno-frame-address -fexceptions -fno-rtti -mfix-esp32-psram-cache-issue -mlongcalls -ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -Os -freorder-blocks -Wwrite-strings -fstack-protector -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -MMD") -SET(CMAKE_C_FLAGS "-Wno-frame-address -std=gnu99 -Wno-old-style-declaration -mfix-esp32-psram-cache-issue -mlongcalls -ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -Os -freorder-blocks -Wwrite-strings -fstack-protector -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -MMD") - -SET(CMAKE_C_STANDARD 99) -set(CMAKE_CXX_STANDARD 17) - -if (CMAKE_BUILD_TYPE MATCHES "esp32cam") - add_definitions(-DPLATFORMIO=60105) - add_definitions(-DARDUINO_ESP32_DEV) - add_definitions(-DBOARD_HAS_PSRAM) - add_definitions(-DCORE_DEBUG_LEVEL=5) - add_definitions(-DHAVE_CONFIG_H) - add_definitions(-DMBEDTLS_CONFIG_FILE=\"mbedtls/esp_config.h\") - add_definitions(-DUNITY_INCLUDE_CONFIG_H) - add_definitions(-DWITH_POSIX) - add_definitions(-D_GNU_SOURCE) - add_definitions(-DIDF_VER=\"v4.4.2\") - add_definitions(-DESP_PLATFORM) - add_definitions(-D_POSIX_READER_WRITER_LOCKS) - add_definitions(-DARDUINO_ARCH_ESP32) - add_definitions(-DESP32) - add_definitions(-DF_CPU=240000000L) - add_definitions(-DARDUINO=10812) - add_definitions(-DARDUINO_VARIANT=\"esp32\") - add_definitions(-DARDUINO_BOARD=\"AI\ Thinker\ ESP32-CAM\") - add_definitions(-DARDUINO_PARTITION_default) - - include_directories("${CMAKE_CURRENT_LIST_DIR}/include") - include_directories("${CMAKE_CURRENT_LIST_DIR}/src") - include_directories("$ENV{HOME}/GitRepos/sensor-system/client/libs/sht85") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/SD_MMC/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/FS/src") - include_directories("$ENV{HOME}/GitRepos/sensor-system/client/libs/espnow/src") - include_directories("$ENV{HOME}/GitRepos/sensor-system/client/libs/includes") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/WiFi/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/Preferences/src") - include_directories("$ENV{HOME}/GitRepos/sensor-system/client/libs/caching/src") - include_directories("$ENV{HOME}/GitRepos/sensor-system/client/libs/time/src") - include_directories("${CMAKE_CURRENT_LIST_DIR}/.pio/libdeps/esp32cam/ArduinoJson/src") - include_directories("${CMAKE_CURRENT_LIST_DIR}/.pio/libdeps/esp32cam/ESP32Time") - include_directories("${CMAKE_CURRENT_LIST_DIR}/.pio/libdeps/esp32cam/RTClib/src") - include_directories("${CMAKE_CURRENT_LIST_DIR}/.pio/libdeps/esp32cam/Adafruit BusIO") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/SPI/src") - include_directories("${CMAKE_CURRENT_LIST_DIR}/.pio/libdeps/esp32cam/arduino-sht") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/Wire/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/newlib/platform_include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/esp_additions/freertos") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/port/xtensa/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/esp_additions") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/soc") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/soc/esp32") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/port/esp32") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/port/esp32/private_include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/heap/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/log/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/lwip/include/apps") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/lwip/include/apps/sntp") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/lwip/lwip/src/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/lwip/port/esp32/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/lwip/port/esp32/include/arch") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/esp32") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/esp32/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/esp32/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/platform_port/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_rom/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_rom/include/esp32") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_rom/esp32") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_common/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_system/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_system/port/soc") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_system/port/public_compat") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp32/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/esp32/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/driver/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/driver/esp32/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_pm/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_ringbuf/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/efuse/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/efuse/esp32/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/vfs/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_wifi/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_event/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_netif/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_eth/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/tcpip_adapter/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_phy/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_phy/esp32/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_ipc/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/app_trace/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_timer/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/mbedtls/port/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/mbedtls/mbedtls/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/mbedtls/esp_crt_bundle/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/app_update/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/spi_flash/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bootloader_support/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/nvs_flash/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/pthread/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_gdbstub/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_gdbstub/xtensa") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_gdbstub/esp32") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espcoredump/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/espcoredump/include/port/xtensa") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/wpa_supplicant/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/wpa_supplicant/port/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/wpa_supplicant/esp_supplicant/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/ieee802154/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/console") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/asio/asio/asio/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/asio/port/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/common/osi/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/include/esp32/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/common/api/include/api") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/common/btc/profile/esp/blufi/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/common/btc/profile/esp/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/host/bluedroid/api/include/api") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_common/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_common/tinycrypt/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_core") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_core/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_core/storage") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/btc/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_models/common/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_models/client/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/mesh_models/server/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/api/core/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/api/models/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/bt/esp_ble_mesh/api") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/cbor/port/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/unity/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/unity/unity/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/cmock/CMock/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/coap/port/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/coap/libcoap/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/nghttp/port/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/nghttp/nghttp2/lib/includes") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-tls") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-tls/esp-tls-crypto") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_adc_cal/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hid/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/tcp_transport/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_http_client/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_http_server/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_https_ota/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_https_server/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_lcd/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_lcd/interface") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/protobuf-c/protobuf-c") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/protocomm/include/common") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/protocomm/include/security") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/protocomm/include/transports") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/mdns/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_local_ctrl/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/sdmmc/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_serial_slave_link/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_websocket_client/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/expat/expat/expat/lib") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/expat/port/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/wear_levelling/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/fatfs/diskio") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/fatfs/vfs") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/fatfs/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freemodbus/common/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/idf_test/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/idf_test/include/esp32") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/jsmn/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/json/cJSON") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/libsodium/libsodium/src/libsodium/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/libsodium/port_include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/mqtt/esp-mqtt/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/openssl/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/perfmon/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/spiffs/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/ulp/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/wifi_provisioning/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/rmaker_common/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/json_parser/upstream/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/json_parser/upstream") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/json_generator/upstream") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_schedule/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_rainmaker/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/gpio_button/button/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/qrcode/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/ws2812_led") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/dotprod/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/support/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/windows/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/windows/hann/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/windows/blackman/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/windows/blackman_harris/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/windows/blackman_nuttall/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/windows/nuttall/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/windows/flat_top/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/iir/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/fir/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/math/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/math/add/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/math/sub/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/math/mul/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/math/addc/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/math/mulc/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/math/sqrt/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/matrix/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/fft/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/dct/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/conv/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/common/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/kalman/ekf/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dsp/modules/kalman/ekf_imu13states/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_littlefs/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/tool") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/typedef") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/image") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/math") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/nn") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/layer") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/detect") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-dl/include/model_zoo") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-sr/src/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-sr/esp-tts/esp_tts_chinese/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp-sr/include/esp32") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp32-camera/driver/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp32-camera/conversions/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/fb_gfx/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/dio_qspi/include") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/cores/esp32") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/variants/esp32") - include_directories("$ENV{HOME}/GitRepos/sensor-system/client/libs/.idea") - include_directories("$ENV{HOME}/GitRepos/sensor-system/client/libs/LC7090203F") - include_directories("$ENV{HOME}/GitRepos/sensor-system/client/libs/SentecSensors") - include_directories("$ENV{HOME}/GitRepos/sensor-system/client/libs/deep_sleep") - include_directories("$ENV{HOME}/GitRepos/sensor-system/client/libs/dr26_analogue") - include_directories("$ENV{HOME}/GitRepos/sensor-system/client/libs/drs26_digital") - include_directories("$ENV{HOME}/GitRepos/sensor-system/client/libs/ina219") - include_directories("$ENV{HOME}/GitRepos/sensor-system/client/libs/mock_sensor") - include_directories("$ENV{HOME}/GitRepos/sensor-system/client/libs/rs485") - include_directories("$ENV{HOME}/GitRepos/sensor-system/client/libs/scd30") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/ArduinoOTA/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/AsyncUDP/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/BLE/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/BluetoothSerial/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/DNSServer/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/EEPROM/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/ESP32/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/ESPmDNS/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/Ethernet/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/FFat/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/HTTPClient/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/HTTPUpdate/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/HTTPUpdateServer/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/I2S/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/LittleFS/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/NetBIOS/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/RainMaker/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/SD/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/SPIFFS/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/SimpleBLE/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/Ticker/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/USB/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/Update/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/WebServer/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/WiFiClientSecure/src") - include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/WiFiProv/src") - include_directories("$ENV{HOME}/.platformio/packages/toolchain-xtensa-esp32/xtensa-esp32-elf/include/c++/8.4.0") - include_directories("$ENV{HOME}/.platformio/packages/toolchain-xtensa-esp32/xtensa-esp32-elf/include/c++/8.4.0/xtensa-esp32-elf") - include_directories("$ENV{HOME}/.platformio/packages/toolchain-xtensa-esp32/lib/gcc/xtensa-esp32-elf/8.4.0/include-fixed") - include_directories("$ENV{HOME}/.platformio/packages/toolchain-xtensa-esp32/lib/gcc/xtensa-esp32-elf/8.4.0/include") - include_directories("$ENV{HOME}/.platformio/packages/toolchain-xtensa-esp32/xtensa-esp32-elf/include") - - FILE(GLOB_RECURSE EXTRA_LIB_SOURCES - ${CMAKE_CURRENT_LIST_DIR}/.pio/libdeps/esp32cam/*.* - $ENV{HOME}/GitRepos/sensor-system/client/libs/*.* - ) -endif() - - -FILE(GLOB_RECURSE SRC_LIST - ${CMAKE_CURRENT_LIST_DIR}/src/*.* - ${CMAKE_CURRENT_LIST_DIR}/lib/*.* - ${CMAKE_CURRENT_LIST_DIR}/test/*.* -) - -list(APPEND SRC_LIST ${EXTRA_LIB_SOURCES}) diff --git a/client/ESPcam/platformio.ini b/client/ESPcam/platformio.ini index 835183a1a921563ea8720791c13a22e3cdafd9dd..6a98c59f1074e53cfe8f80b9c0efe782cd5f6ceb 100644 --- a/client/ESPcam/platformio.ini +++ b/client/ESPcam/platformio.ini @@ -14,6 +14,7 @@ board = esp32cam framework = arduino monitor_speed = 115200 lib_ldf_mode = deep +monitor_port = /dev/ttyACM1 lib_extra_dirs = ../libs ../../shared-libs diff --git a/client/client_central_mast/src/main.cpp b/client/client_central_mast/src/main.cpp index c1cdd98da0cee65b8520472999c78d70ec7d442a..310ce035e0d930161b79110cc86968c281851b24 100644 --- a/client/client_central_mast/src/main.cpp +++ b/client/client_central_mast/src/main.cpp @@ -1,134 +1,118 @@ #include "Arduino.h" #include "ESPNow.hpp" #include "NoDataAvailableException.hpp" +#include "SentecRainGaugeSensor.h" #include "rs485.hpp" -#include <list> #include <ina219.hpp> static const char *TAG = "MAIN"; #define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */ -#define TIME_TO_SLEEP 5 * 1 /* Time ESP32 will go to sleep (in seconds) */ +#define TIME_TO_SLEEP 0 * 1 /* Time ESP32 will go to sleep (in seconds) */ -Forte_RS485 rs485; +ForteRS485 rs485; ForteINA219 ina219; +SEM404 rainGaugeSensor = SEM404(2, 19); float getBatteryVoltage() { - //************ Measuring Battery Voltage *********** - // reference voltage of microcontroller 3.3v for esp32 - const float reference_vcc = 3.3; - // value of R2 resistor [kOhm] - const float bat_res_gnd = 20; - // value of R1 resistor [kOhm] - const float bat_res_vcc = 68; - // max ADC value - const int adc = 4095; - float sample = 0; - // Get 100 analog read to prevent unusefully read - for (int i = 0; i < 100; i++) { - sample = - sample + analogRead(35); // read the voltage from the divider circuit - delay(2); - } - sample = sample / 100; - float battery_voltage = - (sample / 4095 * reference_vcc * (bat_res_vcc + bat_res_gnd) - / bat_res_gnd); - ESP_LOGI(TAG, "Battery Voltage: %4.2f V", battery_voltage); - ESP_LOGD(TAG, "ADC mean Value: %4.2f", sample); - return battery_voltage; -} - -// FIXME: put this in ESPNow.hpp and let stupid Markus Rampp know how you did it. After years of Python he moved past -// the idea of types and declarations -void send_msgs(const std::__cxx11::list<Message> msgs) { - for (const Message &msg: msgs) { - - if (msg.send() != ESP_OK) { - RtcMemory::store_data(msg.getMessageAsMinifiedJsonString()); + //************ Measuring Battery Voltage *********** + // reference voltage of microcontroller 3.3v for esp32 + const float reference_vcc = 3.3; + // value of R2 resistor [kOhm] + const float bat_res_gnd = 20; + // value of R1 resistor [kOhm] + const float bat_res_vcc = 68; + // max ADC value + const int adc = 4095; + float sample = 0; + // Get 100 analog read to prevent unusefully read + for (int i = 0; i < 100; i++) { + sample = sample + analogRead(35); // read the voltage from the divider circuit + delay(2); } - unsigned long ts = millis(); - // it takes ~110ms for receiving an acknowledgement by the host in perfect conditions - uint16_t message_timeout = 2000; - while (!was_msg_received()) { - if ((millis() - ts) > message_timeout) { - RtcMemory::store_data(msg.getMessageAsMinifiedJsonString()); - ESP_LOGE(TAG, "Timeout: Host not available\n"); - break; - } - } - ESP_LOGD(TAG, "Time until acknowledgement: %ld", millis() - ts); - } + sample = sample / 100; + float battery_voltage = (sample / 4095 * reference_vcc * (bat_res_vcc + bat_res_gnd) / bat_res_gnd); + ESP_LOGI(TAG, "Battery Voltage: %4.2f V", battery_voltage); + ESP_LOGD(TAG, "ADC mean Value: %4.2f", sample); + return battery_voltage; } void setup() { - // whole loop should be around ~3000 ms - Serial.begin(115200); - rs485.setup(); - - getBatteryVoltage(); - - - ina219.setup(); - ina219.setPinSetup({21, 22}); - - // ~2100ms - try { - auto messages = rs485.buildMessages(); - // split into arrays of 6 messages TODO: Make this cleaner with default constructor - std::array<Message, 6> messages_1 = - {Message::nullMessage(), Message::nullMessage(), Message::nullMessage(), - Message::nullMessage(), Message::nullMessage(), - Message::nullMessage()}; - std::array<Message, 6> messages_2 = - {Message::nullMessage(), Message::nullMessage(), Message::nullMessage(), - Message::nullMessage(), Message::nullMessage(), - Message::nullMessage()}; - - auto ina219_messages = ina219.buildMessages(); - - std::array<Message, 6> ina_array = - {Message::nullMessage(), Message::nullMessage(), Message::nullMessage(), - Message::nullMessage(), Message::nullMessage(), - Message::nullMessage()}; - - // log ina messages - for (const auto &msg: ina219_messages) { - ESP_LOGI(TAG, - "INA219 Message: %s", - msg.getMessageAsMinifiedJsonString().c_str()); - } - - - int i = 0; - for (const auto &msg: messages) { - if (i < 6) { - messages_1[i] = msg; - } else { - messages_2[i - 6] = msg; - } - i++; + // whole loop should be around ~3000 ms + Serial.begin(115200); + rs485.setup(); + + getBatteryVoltage(); + + ina219.setPinSetup({21, 22}); + ina219.setup(); + + try { + ForteRS485::powerOnRS485Sensors(); + auto messages = rainGaugeSensor.buildMessages(); + ForteRS485::powerOffRS485Sensors(); + // split into arrays of 6 messages TODO: Make this cleaner with default constructor + std::array<Message, 6> messages_1 = {Message::nullMessage(), Message::nullMessage(), Message::nullMessage(), + Message::nullMessage(), Message::nullMessage(), Message::nullMessage()}; + + auto ina219_messages = ina219.buildMessages(); + + std::array<Message, 6> ina_array = {Message::nullMessage(), Message::nullMessage(), Message::nullMessage(), + Message::nullMessage(), Message::nullMessage(), Message::nullMessage()}; + + // log ina messages + for (const auto &msg : ina219_messages) { + ESP_LOGI(TAG, "INA219 Message: %s", msg.getMessageAsMinifiedJsonString().c_str()); + } + + int i = 0; + for (const auto &msg : messages) { + if (i < 6) { + messages_1[i] = msg; + } + i++; + } + + espnow_setup(); + + // demo of how to reset the rain gauge +#ifdef RESET_RAIN_GAUGE + if (messages_1.front().getClientDataPackage().getMeasurementData().getValue() > 20) { + ForteRS485::powerOnRS485Sensors(); + if (rainGaugeSensor.resetPrecipitation() == ErrorType::SEM404_COULD_NOT_RESET_PRECIPITATION) { + ESP_LOGE(TAG, "Could not reset precipitation"); + auto precipitationErrorMessage = Message( + Measurement(ERROR_VALUE, rainGaugeSensor.address, NO_I2C_ADDRESS, MeasurementType::PRECIPITATION, + ErrorType::SEM404_COULD_NOT_RESET_PRECIPITATION), + rainGaugeSensor.getSensorInformation(), Time::getInstance().getEpochSeconds()); + std::array<Message, 6> messages_error = {precipitationErrorMessage, Message::nullMessage(), + Message::nullMessage(), Message::nullMessage(), + Message::nullMessage(), Message::nullMessage()}; + Message::sendMessages(messages_error); + } + ForteRS485::powerOffRS485Sensors(); + } +#endif + + i = 0; + for (const auto &msg : ina219_messages) { + ina_array[i] = msg; + i++; + } + + Message::sendMessages(messages_1); + // Message::sendMessages(ina_array); + + } catch (const NoDataAvailableException &e) { + std::cerr << e.what() << '\n'; } - i = 0; - for (const auto &msg: ina219_messages) { - ina_array[i] = msg; - i++; - } - - espnow_setup(); - Message::sendMessages(messages_1); - Message::sendMessages(messages_2); - Message::sendMessages(ina_array); - - } catch (const NoDataAvailableException &e) { - std::cerr << e.what() << '\n'; - } + rs485.teardown(); - ESP_LOGD(TAG, "Going to sleep for %d seconds", TIME_TO_SLEEP); + ESP_LOGD(TAG, "Going to sleep for %d seconds", TIME_TO_SLEEP); - esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); - esp_deep_sleep_start(); + esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); + esp_deep_sleep_start(); } void loop() {} diff --git a/client/client_satellite/platformio.ini b/client/client_satellite/platformio.ini index 1a9a18984b3f34f3cba2b6d992ddf9eb49f61e74..09b747efce058c0311c30e7a0a2468ced411e15a 100644 --- a/client/client_satellite/platformio.ini +++ b/client/client_satellite/platformio.ini @@ -4,6 +4,8 @@ board = esp32dev framework = arduino monitor_speed = 115200 lib_ldf_mode = deep +upload_port = /dev/ttyUSB0 +monitor_port = /dev/ttyUSB0 lib_extra_dirs = ../libs ../../shared-libs diff --git a/client/client_satellite/src/main.cpp b/client/client_satellite/src/main.cpp index 7f729b96215a8e83b8860a8b902c071aac17f50f..770e9204dfdea6fcf01e18dc592d5722b0902315 100644 --- a/client/client_satellite/src/main.cpp +++ b/client/client_satellite/src/main.cpp @@ -4,14 +4,16 @@ #include "dr26.hpp" #include "f_deep_sleep.hpp" #include <Arduino.h> +#include <SentecRainGaugeSensor.h> #include <list> +#include <rs485.hpp> // Execution time: // FIXME: Boot: needs to be optimised. should be around 300 ms, can be <100ms // https://github.com/makermoekoe/Picoclick-C3#speed-up-boot-process // Part [ms] // Boot: 300 -// First setup: 150 +// First setup: 150 // Data aquisition: 500 (4 Dendrometers) // ESPNow setup: 220 // Sending 580 @@ -26,105 +28,118 @@ static const char *TAG = "MAIN"; LC709203F battery_monitor; +#define RS485Serial Serial2 +#define RE_DE_PIN 19 // Line to pull high or low to receive or send data from RS485 + +#define RXPin 14 // Serial Receive pin +#define TXPin 15 // Serial Transmit pin + +#define POWER_SWITCH_PIN_12V 12 +#define POWER_SWITCH_PIN_5V 13 + +ForteRS485 rs485; +SEM404 rainGaugeSensor{2, RE_DE_PIN}; + ForteDR26 dr26_channel0; ForteDR26 dr26_channel3; ForteDR26 dr26_channel1; ForteDR26 dr26_channel2; -void send_msgs(const std::__cxx11::list<Message> msgs) -{ - for (const Message &msg : msgs) { - - if (msg.send() != ESP_OK) { - RtcMemory::store_data(msg.getMessageAsMinifiedJsonString()); - } - unsigned long ts = millis(); - // it takes ~110ms for receiving an acknowledgement by the host in perfect conditions - uint16_t message_timeout = 2000; - while (!was_msg_received()) { - if ((millis() - ts) > message_timeout) { - RtcMemory::store_data(msg.getMessageAsMinifiedJsonString()); - ESP_LOGE(TAG, "Timeout: Host not available\n"); - break; - } - } - ESP_LOGD(TAG, "Time until acknowledgement: %ld", millis() - ts); - } -} // one loop takes ~2200 ms -void setup() -{ - unsigned long ts = millis(); - Serial.begin(115200); - // Set the GPIO which conrtols the step up to OUTPUT - gpio_set_direction(GPIO_NUM_32, GPIO_MODE_OUTPUT); - - // blinking led for debug - // gpio_set_direction(GPIO_NUM_17, GPIO_MODE_OUTPUT); - // gpio_set_level(GPIO_NUM_17, 1); - - battery_monitor.begin(); - - DeepSleep::print_wakeup_reason(); - DeepSleep::bootCount++; - ESP_LOGD(TAG, "Boot number: %d", DeepSleep::bootCount); - // battery protection: go to deep sleep for unlimited time when voltage less than 3.2V - if (battery_monitor.cellVoltage_mV() < 3200) { - battery_monitor.setPowerMode(LC709203F_POWER_SLEEP); - esp_deep_sleep_start(); - } - - gpio_set_level(GPIO_NUM_32, 1); - // delay(100); - dr26_channel1.setup(); - dr26_channel0.setChannel(0); - dr26_channel1.setChannel(1); - dr26_channel2.setChannel(2); - dr26_channel3.setChannel(3); - - ESP_LOGD(TAG, "Setup took %ld ms", millis() - ts); - - try { - // FIXME: put me into seperate trys? No data will be sent when 1 exception occurs - - ts = millis(); - auto messages0 = dr26_channel0.buildMessages(); - auto messages1 = dr26_channel1.buildMessages(); - auto messages2 = dr26_channel2.buildMessages(); - auto messages3 = dr26_channel3.buildMessages(); - auto messages4 = battery_monitor.buildMessages(); - // roughly takes 500ms, ~120ms for each adc channel, barely anything for battery monitor - ESP_LOGD(TAG, "Reading data and building messages took %ld ms", millis() - ts); - gpio_set_level(GPIO_NUM_32, 0); - - // FIXME: put this outside the try loop? - ts = millis(); - espnow_setup(); - ESP_LOGD(TAG, "EPSNow setup took %ld ms", millis() - ts); - ts = millis(); - send_msgs(messages0); - send_msgs(messages1); - send_msgs(messages2); - send_msgs(messages3); - send_msgs(messages4); - // roughly takes 3s in ideal conditions - ESP_LOGD(TAG, "Sending messages took %ld ms", millis() - ts); - - } catch (const NoDataAvailableException &e) { - std::cerr << e.what() << '\n'; - } - // just to be safe in case exception happens above - gpio_set_level(GPIO_NUM_32, 0); - // keep it in deep sleep - gpio_hold_en((gpio_num_t)GPIO_NUM_32); - - battery_monitor.setPowerMode(LC709203F_POWER_SLEEP); - // battery protection: go to deep sleep for unlimited time when voltage less than 3.2V - if (battery_monitor.cellVoltage_mV() > 3200) { - DeepSleep::deep_sleep(10 * 60); - } else { - esp_deep_sleep_start(); - } +void setup() { + unsigned long ts = millis(); + Serial.begin(115200); + rs485.setup(); + // Set the GPIO which conrtols the step up to OUTPUT + gpio_set_direction(GPIO_NUM_32, GPIO_MODE_OUTPUT); + + // blinking led for debug + // gpio_set_direction(GPIO_NUM_17, GPIO_MODE_OUTPUT); + // gpio_set_level(GPIO_NUM_17, 1); + + battery_monitor.begin(); + + DeepSleep::print_wakeup_reason(); + DeepSleep::bootCount++; + ESP_LOGD(TAG, "Boot number: %d", DeepSleep::bootCount); + // battery protection: go to deep sleep for unlimited time when voltage less than 3.2V + if (battery_monitor.cellVoltage_mV() < 3200) { + battery_monitor.setPowerMode(LC709203F_POWER_SLEEP); + esp_deep_sleep_start(); + } + + gpio_set_level(GPIO_NUM_32, 1); + // delay(100); + dr26_channel1.setup(); + dr26_channel0.setChannel(0); + dr26_channel1.setChannel(1); + dr26_channel2.setChannel(2); + dr26_channel3.setChannel(3); + + ESP_LOGD(TAG, "Setup took %ld ms", millis() - ts); + + try { + // FIXME: put me into seperate trys? No data will be sent when 1 exception occurs + + ts = millis(); + // auto messages0 = dr26_channel0.buildMessages(); + // auto messages1 = dr26_channel1.buildMessages(); + // auto messages2 = dr26_channel2.buildMessages(); + // auto messages3 = dr26_channel3.buildMessages(); + // auto messages4 = battery_monitor.buildMessages(); + ForteRS485::powerOnRS485Sensors(); + auto rainMessage = rainGaugeSensor.buildMessages(); + ForteRS485::powerOffRS485Sensors(); + // roughly takes 500ms, ~120ms for each adc channel, barely anything for battery monitor + ESP_LOGD(TAG, "Reading data and building messages took %ld ms", millis() - ts); + gpio_set_level(GPIO_NUM_32, 0); + + // std::array<Message, 6> messages = + // {messages0.front(), messages1.front(), messages2.front(), + // messages3.front(), messages4.front(), rainMessage.front()}; + std::array<Message, 6> messages = {Message::nullMessage(), Message::nullMessage(), Message::nullMessage(), + Message::nullMessage(), Message::nullMessage(), rainMessage.front()}; + + ts = millis(); + espnow_setup(); + ESP_LOGD(TAG, "EPSNow setup took %ld ms", millis() - ts); + + if (messages.back().getClientDataPackage().getMeasurementData().getValue() > 20) { + ForteRS485::powerOnRS485Sensors(); + if (rainGaugeSensor.resetPrecipitation() == ErrorType::SEM404_COULD_NOT_RESET_PRECIPITATION) { + ESP_LOGE(TAG, "Could not reset precipitation"); + auto precipitationErrorMessage = Message( + Measurement(ERROR_VALUE, rainGaugeSensor.address, NO_I2C_ADDRESS, MeasurementType::PRECIPITATION, + ErrorType::SEM404_COULD_NOT_RESET_PRECIPITATION), + rainGaugeSensor.getSensorInformation(), Time::getInstance().getEpochSeconds()); + std::array<Message, 6> messages_error = {precipitationErrorMessage, Message::nullMessage(), + Message::nullMessage(), Message::nullMessage(), + Message::nullMessage(), Message::nullMessage()}; + Message::sendMessages(messages_error); + } + ForteRS485::powerOffRS485Sensors(); + } + + ts = millis(); + Message::sendMessages(messages); + // roughly takes 3s in ideal conditions + ESP_LOGD(TAG, "Sending messages took %ld ms", millis() - ts); + + } catch (const NoDataAvailableException &e) { + std::cerr << e.what() << '\n'; + } + // just to be safe in case exception happens above + gpio_set_level(GPIO_NUM_32, 0); + // keep it in deep sleep + gpio_hold_en((gpio_num_t)GPIO_NUM_32); + + battery_monitor.setPowerMode(LC709203F_POWER_SLEEP); + // battery protection: go to deep sleep for unlimited time when voltage less than 3.2V + if (battery_monitor.cellVoltage_mV() > 3200) { + DeepSleep::deep_sleep(2); + } else { + esp_deep_sleep_start(); + } } void loop() {} \ No newline at end of file diff --git a/client/libs/SentecSensors/SentecRainGaugeSensor.cpp b/client/libs/SentecSensors/SentecRainGaugeSensor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..716c129743f2c68002b277c90b5af82ee505751c --- /dev/null +++ b/client/libs/SentecSensors/SentecRainGaugeSensor.cpp @@ -0,0 +1,61 @@ +// +// Created by zoe on 2/20/23. +// + +#include "SentecRainGaugeSensor.h" + +static const char *TAG = "SEM404"; + +ErrorType SEM404::resetPrecipitation() { + // clears rainfall rata from the rain gauge + // delay resetting after the last register reading + delay(100); + Serial.println("Resetting precipitation sum"); + auto writeRegisterReturn = writeRegister(0x00, 0x5A); + + // other errors like not connected will be shared when reading out the sensor + if (!isAnswerFrameEqualToQueryFrame(answerFrame, writeRegisterReturn.writtenQuery)) { + ESP_LOGE(TAG, "Could not reset precipitation"); + return ErrorType::SEM404_COULD_NOT_RESET_PRECIPITATION; + } + + return writeRegisterReturn.errorType; +} + +void SEM404::resetSensor() { + // no clue what the difference between this one and the previous one is... + // and the manual is not helpful, of course + delay(100); + Serial.println("Resetting precipitation sum"); + writeRegister(0x37, 0x03); + // TODO check response: matches the sent message exactly +} +out_data_rain_gauge SEM404::getInstantaneousPrecipitation() { + // gets tips of scale since the last reset, i.e. total precipitation (I THINK) + // manual says this is current precipitation - is it? + auto error = readRegister(0, 0x01); + precipitation = word(answerFrame[3], answerFrame[4]); + + ESP_LOGI("RainGauge", "Precipitation: %s mm", getPrecipitationStr().c_str()); + // resetPrecipitation(); + return {static_cast<float>(precipitation), error}; +} +String SEM404::getPrecipitationStr() { + return getValueStr((float)(precipitation / 10.0)); +} + +SensorInformation SEM404::getSensorInformation() const { + return {HardwareName::SEM404, SensorProtocol::RS485}; +} +std::list<Message> SEM404::buildMessages() { + auto messages = std::list<Message>(); + auto data = getInstantaneousPrecipitation(); + Measurement precipitationMeasurement{data.precipitation, address, NO_I2C_ADDRESS, MeasurementType::PRECIPITATION, + data.precipitationError}; + messages.emplace_back(precipitationMeasurement, getSensorInformation(), Time::getInstance().getEpochSeconds()); + return messages; +} +out_data_rain_gauge SEM404::readData() { + return getInstantaneousPrecipitation(); +} +void SEM404::setup() {} diff --git a/client/libs/SentecSensors/SentecRainGaugeSensor.h b/client/libs/SentecSensors/SentecRainGaugeSensor.h new file mode 100644 index 0000000000000000000000000000000000000000..521459d1219209f30caa2c8bd0266a917ba0b328 --- /dev/null +++ b/client/libs/SentecSensors/SentecRainGaugeSensor.h @@ -0,0 +1,51 @@ +// +// Created by zoe on 2/20/23. +// + +#ifndef CLIENT_CENTRAL_MAST_SENTECRAINGAUGESENSOR_H +#define CLIENT_CENTRAL_MAST_SENTECRAINGAUGESENSOR_H + +#include "SentecSensorsRS485.h" +#include <ForteSensor.hpp> +#include <Message.hpp> + +struct out_data_rain_gauge { + float precipitation; + ErrorType precipitationError; +}; + +/** + * @brief Class to read data from the Sentec rain gauge sensor (SEM404) + * @implements ForteSensor<out_data_rain_gauge> + * @extends SentecSensorRS485 + */ +class SEM404 : public SentecSensorRS485, ForteSensor<out_data_rain_gauge> { + public: + using SentecSensorRS485::SentecSensorRS485; + SEM404() : SentecSensorRS485(0) {} + // precipitation values [mm] + unsigned int precipitation = 0; // prcp since reset? (I THINK!!!) + + /** + * @brief Reset the precipitation value + * @return ErrorType. If the reset was unsuccessful, this will return ErrorType::SEM404_RESET_PRECIPITATION_ERROR. + * Otherwise it returns the error given from the device + */ + ErrorType resetPrecipitation(); + + void resetSensor(); + + /** + * @brief Get the instantaneous precipitation value + * @return out_data_rain_gauge + */ + out_data_rain_gauge getInstantaneousPrecipitation(); + + String getPrecipitationStr(); + + void setup() override; + out_data_rain_gauge readData() override; + std::list<Message> buildMessages() override; + [[nodiscard]] SensorInformation getSensorInformation() const override; +}; +#endif // CLIENT_CENTRAL_MAST_SENTECRAINGAUGESENSOR_H diff --git a/client/libs/SentecSensors/SentecSensors.h b/client/libs/SentecSensors/SentecSensors.h deleted file mode 100644 index 55fb834cdc770fd43edfff579a1f3f5ce08d5af1..0000000000000000000000000000000000000000 --- a/client/libs/SentecSensors/SentecSensors.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef SENTECSENSORS_H -#define SENTECSENSORS_H - -#include <Arduino.h> -#include <ErrorTypes.h> - -class SentecSensorRS485 { -public: - byte address; - uint8_t serialCommunicationControlPin = 19; - HardwareSerial *RS485; - byte answerFrame[10]; - // TODO use valid flag to log None - bool valid = false; - - SentecSensorRS485(HardwareSerial *ser, byte add); - - SentecSensorRS485(HardwareSerial *ser, byte add, uint8_t serialControlPin); - - void write(byte queryFrame[], int length); - - String getValueStr(float value); - - String getValueStr(int value); - - ErrorType queryAddress(); - - ErrorType readRegister(int registerStartAddress); - - ErrorType readRegister(int registerStartAddress, int registerLength); - - ErrorType writeRegister(int registerAddress, int value); - - ErrorType setAddress(byte add); - - void resetAnswerFrame(); - - ErrorType getResponse(); - - unsigned int calculateCRC(byte query[], int length); - - void printBytes(byte *data, int length); - - void printBytes(word data); - - std::string formatBytes(byte *data, int length); - - std::string formatBytes(word data); - -}; - -class SolarRadiationSensor : public SentecSensorRS485 { -public: - using SentecSensorRS485::SentecSensorRS485; - // global radiation [W/m^2] - word glob = 0; - - word getSolarRadiation(); - - String getSolarRadiationStr(); -}; - -class RainGaugeSensor : public SentecSensorRS485 { -public: - using SentecSensorRS485::SentecSensorRS485; - // precipitation values [mm] - word precipitation = 0; // prcp since reset? (I THINK!!!) - - void resetPrecipitation(); - - void resetSensor(); - - word getInstantaneousPrecipitation(); - - String getPrecipitationStr(); -}; - -class SoilMoistureSensor : public SentecSensorRS485 { -public: - using SentecSensorRS485::SentecSensorRS485; - // vwc: volumetric water content [%] - uint16_t moistureRaw = 0; - int moistureOffset = 0; - // soil temperature [deg C] - int temperatureRaw = 0; - int temperatureOffset = 0; - - float getMoistureTemp(); - - float getMoisture(); - - String getMoistureStr(); - - String getTemperatureStr(); -}; - -#endif diff --git a/client/libs/SentecSensors/SentecSensors.cpp b/client/libs/SentecSensors/SentecSensorsRS485.cpp similarity index 50% rename from client/libs/SentecSensors/SentecSensors.cpp rename to client/libs/SentecSensors/SentecSensorsRS485.cpp index 4029f3dcd049c916a852f92f2cc6ca279d015e59..a3a090321c22b5ea04f7d7ff607725768936385f 100644 --- a/client/libs/SentecSensors/SentecSensors.cpp +++ b/client/libs/SentecSensors/SentecSensorsRS485.cpp @@ -1,19 +1,18 @@ #include "NoDataAvailableException.hpp" -#include <SentecSensors.h> +#include "SentecRainGaugeSensor.h" +#include <SentecSensorsRS485.h> /*************************************** * RS485 SENSOR READOUT ****************************************/ static const char *TAG = "SENTEC"; -SentecSensorRS485::SentecSensorRS485(HardwareSerial *ser, byte add) { +SentecSensorRS485::SentecSensorRS485(byte add) { address = add; - RS485 = ser; } -SentecSensorRS485::SentecSensorRS485(HardwareSerial *ser, byte add, uint8_t serialControlPin) { +SentecSensorRS485::SentecSensorRS485(byte add, uint8_t serialControlPin) { address = add; - RS485 = ser; serialCommunicationControlPin = serialControlPin; } @@ -30,19 +29,11 @@ void SentecSensorRS485::write(byte queryFrame[], int length) { } String SentecSensorRS485::getValueStr(float value) { - if (valid) { - return String(value, 1); - } else { - return String("null"); - } + return String(value, 1); } String SentecSensorRS485::getValueStr(int value) { - if (valid) { - return String(value); - } else { - return String("null"); - } + return String(value); } ErrorType SentecSensorRS485::queryAddress() { @@ -81,7 +72,7 @@ ErrorType SentecSensorRS485::readRegister(int registerStartAddress, int register return getResponse(); } -ErrorType SentecSensorRS485::writeRegister(int registerAddress, int value) { +WriteRegisterReturnType SentecSensorRS485::writeRegister(int registerAddress, int value) { // function code 0x06: change sensor settings // e.g. a new address, reset rainfal data... @@ -99,96 +90,123 @@ ErrorType SentecSensorRS485::writeRegister(int registerAddress, int value) { ESP_LOGD(TAG, "Query (settings): "); printBytes(query, 8); write(query, sizeof(query)); - return getResponse(); + return {getResponse(), {query[0], query[1], query[2], query[3], query[4], query[5], query[6], query[7]}}; } ErrorType SentecSensorRS485::setAddress(byte add) { // change the address of a sensor - ErrorType tmp = writeRegister(word(0x07, 0xD0), add); - if (tmp == ErrorType::DATA_OK) + WriteRegisterReturnType tmp = writeRegister(word(0x07, 0xD0), add); + if (tmp.errorType == ErrorType::DATA_OK) address = add; - // TODO check response: matches the sent message exactly - return tmp; + + if (!isAnswerFrameEqualToQueryFrame(answerFrame, tmp.writtenQuery)) { + return ErrorType::COULD_NOT_SET_ADDRESS; + } + + return tmp.errorType; } void SentecSensorRS485::resetAnswerFrame() { - for (int i = 0; i < 10; i++) { - answerFrame[i] = 0; + for (unsigned char &i : answerFrame) { + i = 0; } } ErrorType SentecSensorRS485::getResponse() { // reads the response of a sensor ErrorType returnCode = ErrorType::DATA_OK; - valid = true; int idx = 0; - int byteReceived; // usual response length: changed in the while loop to match the response, // changed only when reading data (then it's 7 or 9 bytes, sensor dpendent) int responseLength = 8; // reading an answer takes up to 39 milliseconds for 2 byte readRegister - const int timeout = 200; const int retries = 1; // #editet to q - size_t tries = 1; // it doesn't seem to help to request multiple times if first time goes wrong - for (tries; tries <= retries; tries++) { + for (size_t tries = 1; tries <= retries; tries++) { // if we lose connection with the sensor, we get an array of zeros back resetAnswerFrame(); - unsigned long time = millis(); - while (idx < responseLength && (millis() - time) < timeout) { - if (RS485->available()) { - byteReceived = RS485->read(); - // Serial.println(byteReceived, HEX); - // check for first byte. It has to be the device address unless for broadcasts with address = 0xFF - if (idx == 0 && address != 0xFF && byteReceived != address) { - ESP_LOGE(TAG, - "Invalid byte. First byte needs to be address 0x%02X but got 0x%02Xinstead"); - } else { - answerFrame[idx] = byteReceived; - // for reading register: third received byte is data length, read number of bytes accordingly - if (idx == 2 && answerFrame[1] == 0x03) { - // 5 bytes for address, function code, data length, CRC_H, CRC_L - responseLength = 5 + byteReceived; - } - idx++; - } - } - } - ESP_LOGD(TAG, - "-----------------------------------------------------------------------------------------"); + readRS485(idx, responseLength); + ESP_LOGD(TAG, "Response: 0x%s", formatBytes(answerFrame, responseLength).c_str()); - // ESP_LOGD(TAG, "Tries: %d", tries); - // ESP_LOGD(TAG, "Bytes received: %d", idx); - if (answerFrame[0] == 0) { - ESP_LOGE(TAG, "Check sensor connection. First byte is 0x00."); - valid = false; - returnCode = ErrorType::SENSOR_NOT_CONNECTED; - } else if (idx < responseLength) { - ESP_LOGE(TAG, "Response too short: %d bytes < %d bytes. Unfinished transmission.", idx, - responseLength); - valid = false; - returnCode = ErrorType::CONNECTION_ENDED_PREMATURELY; - } - word crc_received = word(answerFrame[responseLength - 2], answerFrame[responseLength - 1]); - word crc = calculateCRC(answerFrame, responseLength - 2); - if (valid && crc_received != word(crc)) { - ESP_LOGE(TAG, "CRC wrong: Expected 0x%s got 0x%s", formatBytes(crc).c_str(), - formatBytes(crc_received).c_str()); - valid = false; - resetAnswerFrame(); - returnCode = ErrorType::WRONG_CRC; - } + + // TODO: Test this @future_zoe + returnCode = checkForErrors(idx, responseLength); + // breaking after first successfull try if (returnCode == ErrorType::DATA_OK) { break; } } - // ESP_LOGE(TAG, "Returncode: %d", returnCode); return returnCode; } +ErrorType SentecSensorRS485::checkForErrors(int idx, int responseLength) { + // TODO: Not optimal, has precedence + auto connectionEndedPrematurelyReturnCode = checkConnectionEndedPrematurely(idx, responseLength); + auto sensorConnectedReturnCode = checkSensorConnected(); + auto crcReturnCode = checkCRC(responseLength); + + if (sensorConnectedReturnCode != ErrorType::DATA_OK) { + return sensorConnectedReturnCode; + } else if (connectionEndedPrematurelyReturnCode != ErrorType::DATA_OK) { + return connectionEndedPrematurelyReturnCode; + } else if (crcReturnCode != ErrorType::DATA_OK) { + return crcReturnCode; + } + return ErrorType::DATA_OK; +} + +ErrorType SentecSensorRS485::checkCRC(int responseLength) { + word crc_received = word(answerFrame[responseLength - 2], answerFrame[responseLength - 1]); + word crc = calculateCRC(answerFrame, responseLength - 2); + if (crc_received != word(crc)) { + ESP_LOGE(TAG, "CRC wrong: Expected 0x%s got 0x%s", formatBytes(crc).c_str(), formatBytes(crc_received).c_str()); + return ErrorType::WRONG_CRC; + } + return ErrorType::DATA_OK; +} + +ErrorType SentecSensorRS485::checkConnectionEndedPrematurely(int idx, int responseLength) const { + if (idx < responseLength) { + ESP_LOGE(TAG, "Response too short: %d bytes < %d bytes. Unfinished transmission.", idx, responseLength); + return ErrorType::CONNECTION_ENDED_PREMATURELY; + } + return ErrorType::DATA_OK; +} + +ErrorType SentecSensorRS485::checkSensorConnected() const { + if (answerFrame[0] == 0) { + ESP_LOGE(TAG, "Check sensor connection. First byte is 0x00."); + return ErrorType::SENSOR_NOT_CONNECTED; + } + return ErrorType::DATA_OK; +} + +void SentecSensorRS485::readRS485(int &idx, int &responseLength, const int timeout) { + int byteReceived = 0; + unsigned long time = millis(); + while (idx < responseLength && (millis() - time) < timeout) { + if (RS485->available()) { + byteReceived = RS485->read(); + // Serial.println(byteReceived, HEX); + // check for first byte. It has to be the device address unless for broadcasts with address = 0xFF + if (idx == 0 && address != 0xFF && byteReceived != address) { + ESP_LOGE(TAG, "Invalid byte. First byte needs to be address 0x%02X but got 0x%02Xinstead"); + } else { + answerFrame[idx] = byteReceived; + // for reading register: third received byte is data length, read number of bytes accordingly + if (idx == 2 && answerFrame[1] == 0x03) { + // 5 bytes for address, function code, data length, CRC_H, CRC_L + responseLength = 5 + byteReceived; + } + idx++; + } + } + } +} + unsigned int SentecSensorRS485::calculateCRC(byte query[], int length) { // Change the last two bytes of the queryFrame to conform to a CRC check // Yes, this is necessary. No, I don't know exactly what it does. @@ -249,76 +267,18 @@ std::string SentecSensorRS485::formatBytes(byte *data, int length) { } std::string SentecSensorRS485::formatBytes(word data) { - byte arr[2] = {data >> 8, data & 0xFF}; + byte arr[2] = {static_cast<byte>(data >> 8), static_cast<byte>(data & 0xFF)}; return formatBytes(arr, 2); } -word SolarRadiationSensor::getSolarRadiation() { - readRegister(0, 1); - glob = word(answerFrame[3], answerFrame[4]); - ESP_LOGI(TAG, "Global solar radiation: %d W/m^2", glob); - return glob; -} - -String SolarRadiationSensor::getSolarRadiationStr() { - return getValueStr((int) glob); -} - -void RainGaugeSensor::resetPrecipitation() { - // clears rainfall rata from the rain gauge - // delay resetting after the last register reading - delay(100); - Serial.println("Resetting precipitation sum"); - writeRegister(0x00, 0x5A); - // TODO check response: matches the sent message exactly -} - -void RainGaugeSensor::resetSensor() { - // no clue what the difference between this one and the previous one is... - // and the manual is not helpful, of course - delay(100); - Serial.println("Resetting precipitation sum"); - writeRegister(0x37, 0x03); - // TODO check response: matches the sent message exactly -} - -word RainGaugeSensor::getInstantaneousPrecipitation() { - // gets tips of scale since the last reset, i.e. total precipitation (I THINK) - // manual says this is current precipitation - is it? - readRegister(0, 0x01); - precipitation = word(answerFrame[3], answerFrame[4]); - - ESP_LOGI(TAG, "Precipitation: %.1f mm", precipitation / 10.0); - // resetPrecipitation(); - return precipitation; -} - -String RainGaugeSensor::getPrecipitationStr() { - return getValueStr((float) (precipitation / 10.0)); -} - -float SoilMoistureSensor::getMoistureTemp() { - readRegister(0, 2); // start register at 0, read 2 variables (vwc, soil temp) - moistureRaw = (answerFrame[3] << 8) + answerFrame[4]; - // TODO: neg. temp check - if (answerFrame[5] < 0x80) { - temperatureRaw = (answerFrame[5] << 8) + answerFrame[6]; - } else { - temperatureRaw = (answerFrame[5] << 8) + answerFrame[6] - 65536; +bool SentecSensorRS485::isAnswerFrameEqualToQueryFrame(byte returnedFrame[8], byte queryFrame[8]) { + for (int i = 0; i < 8; i++) { + if (returnedFrame[i] != queryFrame[i]) { + ESP_LOGD(TAG, "Response: 0x%s", formatBytes(returnedFrame, 8).c_str()); + ESP_LOGD(TAG, "Response: 0x%s", formatBytes(queryFrame, 8).c_str()); + ESP_LOGE("TEST", "Error: returnedFrame[%d] != ret.writtenQuery[%d]", i, i); + return false; + } } - ESP_LOGI(TAG, "Soil moisture: %.1f %", (moistureRaw - moistureOffset) / 10.0); - ESP_LOGI(TAG, "Soil temperature: %.1f °C", (temperatureRaw - temperatureOffset) / 10.0); - return (temperatureRaw - temperatureOffset) / 10.0; -} - -float SoilMoistureSensor::getMoisture() { - return (moistureRaw - moistureOffset) / 10.0; -} - -String SoilMoistureSensor::getMoistureStr() { - return getValueStr((float) ((moistureRaw - moistureOffset) / 10.0)); -} - -String SoilMoistureSensor::getTemperatureStr() { - return getValueStr((float) ((temperatureRaw - temperatureOffset) / 10.0)); -} + return true; +} \ No newline at end of file diff --git a/client/libs/SentecSensors/SentecSensorsRS485.h b/client/libs/SentecSensors/SentecSensorsRS485.h new file mode 100644 index 0000000000000000000000000000000000000000..cab2500853625f2763b296e73d75d9f106d6b236 --- /dev/null +++ b/client/libs/SentecSensors/SentecSensorsRS485.h @@ -0,0 +1,86 @@ +#ifndef SENTECSENSORS_H +#define SENTECSENSORS_H + +#include <Arduino.h> +#include <ErrorTypes.h> +#include <HardwareNames.h> +#include <RS485HardwareSerial.h> +#include <SensorInformation.hpp> +#include <memory> + +struct WriteRegisterReturnType { + ErrorType errorType; + byte writtenQuery[8]; +}; + +class SentecSensorRS485 { + public: + byte address; + uint8_t serialCommunicationControlPin = 19; + std::shared_ptr<HardwareSerial> RS485 = RS485HardwareSerial::getInstance().getRS485Serial(); + byte answerFrame[10] = {0}; + + SentecSensorRS485(byte add); + + SentecSensorRS485(byte add, uint8_t serialControlPin); + + void write(byte queryFrame[], int length); + + String getValueStr(float value); + + String getValueStr(int value); + + ErrorType queryAddress(); + + ErrorType readRegister(int registerStartAddress); + + ErrorType readRegister(int registerStartAddress, int registerLength); + + WriteRegisterReturnType writeRegister(int registerAddress, int value); + + /** + * @brief Set the address of the sensor + * @param add The new address of the sensor + * @return ErrorType. If the address was not set correctly, the error type is set to + * ErrorType::COULD_NOT_SET_ADDRESS + */ + ErrorType setAddress(byte add); + + void resetAnswerFrame(); + + ErrorType getResponse(); + + unsigned int calculateCRC(byte query[], int length); + + void printBytes(byte *data, int length); + + void printBytes(word data); + + std::string formatBytes(byte *data, int length); + + std::string formatBytes(word data); + + protected: + /** + * @brief Check if the answer frame is equal to the query frame. ONLY CHECKS THE FIRST 8 BYTES + * @param returnedFrame The frame returned from the device + * @param queryFrame The frame sent to the device + * @return true if the answer frame is equal to the query frame + */ + bool isAnswerFrameEqualToQueryFrame(byte *returnedFrame, byte *queryFrame); + + private: + /** + * @brief Read the response from the RS485 bus + * @param[in, out] idx The index of the response + * @param[in, out] responseLength The length of the response + * @param timeout The timeout in ms. Default is 2000ms + */ + void readRS485(int &idx, int &responseLength, const int timeout = 2000); + ErrorType checkSensorConnected() const; + ErrorType checkConnectionEndedPrematurely(int idx, int responseLength) const; + ErrorType checkCRC(int responseLength); + ErrorType checkForErrors(int idx, int responseLength); +}; + +#endif diff --git a/client/libs/SentecSensors/SentecSolarRadiationSensor.cpp b/client/libs/SentecSensors/SentecSolarRadiationSensor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7082a2c43430da171980d37023fd1275815361fc --- /dev/null +++ b/client/libs/SentecSensors/SentecSolarRadiationSensor.cpp @@ -0,0 +1,32 @@ +// +// Created by zoe on 3/06/23. +// + +#include "SentecSolarRadiationSensor.h" + +String SEM228A::getSolarRadiationStr() { + return getValueStr((int)glob); +} + +void SEM228A::setup() { + // TODO: check if rs485 serial is active +} + +out_data_solar_radiation SEM228A::readData() { + auto error = readRegister(0, 1); + glob = word(answerFrame[3], answerFrame[4]); + ESP_LOGI("SolarRadiation", "Global solar radiation: %d W/m^2", glob); + return {static_cast<float>(glob), error}; +} +std::list<Message> SEM228A::buildMessages() { + auto messages = std::list<Message>(); + auto data = readData(); + Measurement solarRadiation{data.solarRadiation, address, NO_I2C_ADDRESS, MeasurementType::SOLAR_RADIATION, + data.solarError}; + messages.emplace_back(Message{solarRadiation, getSensorInformation(), Time::getInstance().getEpochSeconds()}); + return messages; +} + +SensorInformation SEM228A::getSensorInformation() const { + return SensorInformation(HardwareName::SEM228A, SensorProtocol::RS485); +} diff --git a/client/libs/SentecSensors/SentecSolarRadiationSensor.h b/client/libs/SentecSensors/SentecSolarRadiationSensor.h new file mode 100644 index 0000000000000000000000000000000000000000..3c1edc99a424c89a0f2f28fc863e027e2fa13782 --- /dev/null +++ b/client/libs/SentecSensors/SentecSolarRadiationSensor.h @@ -0,0 +1,37 @@ +// +// Created by zoe on 2/20/23. +// + +#ifndef CLIENT_CENTRAL_MAST_SENTECSOLARRADIATIONSENSOR_H +#define CLIENT_CENTRAL_MAST_SENTECSOLARRADIATIONSENSOR_H + +#include "SentecSensorsRS485.h" +#include <ForteSensor.hpp> + +struct out_data_solar_radiation { + float solarRadiation; + ErrorType solarError; +}; + +/** + * @brief Class to read data from the Sentec solar radiation sensor (SEM228A) + * @implements ForteSensor<out_data_solar_radiation> + * @extends SentecSensorRS485 + */ +class SEM228A : public SentecSensorRS485, public ForteSensor<out_data_solar_radiation> { + public: + using SentecSensorRS485::SentecSensorRS485; + + SEM228A() : SentecSensorRS485(0) {} + // global radiation [W/m^2] + word glob = 0; + + void setup() override; + out_data_solar_radiation readData() override; + std::list<Message> buildMessages() override; + [[nodiscard]] SensorInformation getSensorInformation() const override; + + String getSolarRadiationStr(); +}; + +#endif // CLIENT_CENTRAL_MAST_SENTECSOLARRADIATIONSENSOR_H diff --git a/client/libs/dr26_analogue/dr26.cpp b/client/libs/dr26_analogue/dr26.cpp index c0e7d0ee4959ea87d04043672a35fc82d59e4c2b..ea7f1fb639341812f1ed499a298b67efb7ce2b04 100644 --- a/client/libs/dr26_analogue/dr26.cpp +++ b/client/libs/dr26_analogue/dr26.cpp @@ -3,8 +3,11 @@ static const char *TAG = "DR26"; void ForteDR26::setup() { + if (sensorConnected) { + ESP_LOGD(TAG, "ADS already initialized"); + return; + } Wire.begin(); - ads.setGain(GAIN_ONE); ads.setDataRate(RATE_ADS1115_8SPS); if (ads.begin()) { @@ -14,8 +17,6 @@ void ForteDR26::setup() { ESP_LOGE(TAG, "failed to initialize ADS"); sensorConnected = false; } - - delay(100); channel = 0; } @@ -23,25 +24,22 @@ Measurement ForteDR26::readData() { float volts = 0; int16_t adc = 0; + if (!sensorConnected) { + return {ERROR_VALUE, channel, NO_I2C_ADDRESS, MeasurementType::CIRCUMFERENCE_INCREMENT, + ErrorType::SENSOR_INIT_FAILED}; + } + try { // TODO: This function might never return if conversionComplete is never true. Check if this is the case // FIXME: How to notice from the dr if a value is incorrect? adc = ads.readADC_SingleEnded(channel); volts = ads.computeVolts(adc); - } - catch (NoDataAvailableException &e) { + } catch (NoDataAvailableException &e) { // FIXME: This catch block will never be called since we aint throwing any exceptions - return {ERROR_VALUE, channel, NO_I2C_ADDRESS, MeasurementType::CIRCUMFERENCE_INCREMENT, - ErrorType::NO_DATA}; - } - - if (!sensorConnected) { - return {ERROR_VALUE, channel, NO_I2C_ADDRESS, MeasurementType::CIRCUMFERENCE_INCREMENT, - ErrorType::SENSOR_INIT_FAILED}; + return {ERROR_VALUE, channel, NO_I2C_ADDRESS, MeasurementType::CIRCUMFERENCE_INCREMENT, ErrorType::NO_DATA}; } - return {volts, channel, NO_I2C_ADDRESS, MeasurementType::CIRCUMFERENCE_INCREMENT, - ErrorType::DATA_OK}; + return {volts, channel, NO_I2C_ADDRESS, MeasurementType::CIRCUMFERENCE_INCREMENT, ErrorType::DATA_OK}; } // The following functions change the ADC input range: be careful @@ -70,9 +68,7 @@ void ForteDR26::setChannel(int c) { std::list<Message> ForteDR26::buildMessages() { std::list<Message> messages; auto data = readData(); - messages.emplace_back(data, - sensorInformation, - Time::getInstance().getEpochSeconds()); + messages.emplace_back(data, sensorInformation, Time::getInstance().getEpochSeconds()); return messages; } @@ -80,7 +76,5 @@ SensorInformation ForteDR26::getSensorInformation() const { return sensorInformation; } - // TODO: What is this? Adafruit_ADS1115 ForteDR26::ads = ads; - diff --git a/client/libs/dr26_analogue/dr26.hpp b/client/libs/dr26_analogue/dr26.hpp index ea209f597917e3aee4a0dd0f2e89394e4833e499..b84b61254a75342681a0c8c890c830d35f631866 100644 --- a/client/libs/dr26_analogue/dr26.hpp +++ b/client/libs/dr26_analogue/dr26.hpp @@ -23,7 +23,7 @@ class ForteDR26: public ForteSensor<Measurement> { const SensorInformation sensorInformation{HardwareName::DRS26, SensorProtocol::Analog}; int channel; - bool sensorConnected = true; + bool sensorConnected = false; }; #endif \ No newline at end of file diff --git a/client/libs/ina219/ina219.cpp b/client/libs/ina219/ina219.cpp index 1a39ff58e7c28aa573cf864159c5efe18e93ac03..4a0227ad4c51bc9b79e42a25dc96a2866aacfed8 100644 --- a/client/libs/ina219/ina219.cpp +++ b/client/libs/ina219/ina219.cpp @@ -46,11 +46,11 @@ std::list<Message> ForteINA219::buildMessages() { out_data_ina219 measurements = readData(); - messages.emplace_back(measurements.shuntVoltage_mV, sensorInformation, 0); - messages.emplace_back(measurements.busVoltage_V, sensorInformation, 0); - messages.emplace_back(measurements.current_mA, sensorInformation, 0); - messages.emplace_back(measurements.power_mW, sensorInformation, 0); - messages.emplace_back(measurements.loadVoltage_V, sensorInformation, 0); + messages.emplace_back(measurements.shuntVoltage_mV, sensorInformation, Time::getInstance().getEpochSeconds()); + messages.emplace_back(measurements.busVoltage_V, sensorInformation, Time::getInstance().getEpochSeconds()); + messages.emplace_back(measurements.current_mA, sensorInformation, Time::getInstance().getEpochSeconds()); + messages.emplace_back(measurements.power_mW, sensorInformation, Time::getInstance().getEpochSeconds()); + messages.emplace_back(measurements.loadVoltage_V, sensorInformation, Time::getInstance().getEpochSeconds()); // messages.emplace_back(ina219OverflowData, sensorInformation, 0); TODO: Do we need this as an extra message? return messages; diff --git a/client/libs/rs485/RS485HardwareSerial.h b/client/libs/rs485/RS485HardwareSerial.h new file mode 100644 index 0000000000000000000000000000000000000000..b5c688c3c4b9fcd6f542b37b98842466fac16656 --- /dev/null +++ b/client/libs/rs485/RS485HardwareSerial.h @@ -0,0 +1,53 @@ +// +// Created by zoe on 3/8/23. +// + +#ifndef CLIENT_CENTRAL_MAST_RS485HARDWARESERIAL_H +#define CLIENT_CENTRAL_MAST_RS485HARDWARESERIAL_H + + +#include <HardwareSerial.h> +#include <memory> + +/** + * @brief Singleton class to get the RS485 serial port + * @example std::shared_ptr<HardwareSerial> RS485 = RS485HardwareSerial::getInstance().getRS485Serial(); + + */ +class RS485HardwareSerial { + public: + static RS485HardwareSerial &getInstance() + { + static RS485HardwareSerial instance; // Guaranteed to be destroyed. + // Instantiated on first use. + return instance; + } + + std::shared_ptr<HardwareSerial> getRS485Serial() { + return RS485Serial; + } + + private: + RS485HardwareSerial() {} // Constructor? (the {} brackets) are needed here. + + const std::shared_ptr<HardwareSerial> RS485Serial = std::make_shared<HardwareSerial>(Serial2); + + + // C++ 11 + // ======= + // We can use the better technique of deleting the methods + // we don't want. + public: + RS485HardwareSerial(RS485HardwareSerial const &) = delete; + void operator=(RS485HardwareSerial const &) = delete; + + // Note: Scott Meyers mentions in his Effective Modern + // C++ book, that deleted functions should generally + // be public as it results in better error messages + // due to the compilers behavior to check accessibility + // before deleted status + +}; + + +#endif //CLIENT_CENTRAL_MAST_RS485HARDWARESERIAL_H diff --git a/client/libs/rs485/rs485.cpp b/client/libs/rs485/rs485.cpp index 55f18b6ba21b55729ba6e36f677770f7298135ce..62b749dc5e17f0c1dcc70007a47383dcb51d09ad 100644 --- a/client/libs/rs485/rs485.cpp +++ b/client/libs/rs485/rs485.cpp @@ -1,8 +1,11 @@ #include "rs485.hpp" +#include "SentecRainGaugeSensor.h" +#include "SentecSolarRadiationSensor.h" // RS485 control -#define RS485Serial Serial2 -#define RXPin 14 // Serial Receive pin -#define TXPin 15 // Serial Transmit pin +//#define RS485Serial Serial2 + +#define RX_PIN 14 // Serial Receive pin +#define TX_PIN 15 // Serial Transmit pin #define RE_DE_PIN 19 // Line to pull high or low to receive or send data from RS485 @@ -12,89 +15,61 @@ static const char *TAG = "RS485"; // Configure sensors -SolarRadiationSensor solarSensor(&RS485Serial, 1, RE_DE_PIN); -RainGaugeSensor rainGauge = RainGaugeSensor(&RS485Serial, - 2, - RE_DE_PIN); // Give 2 Sensor Adress 2 -SoilMoistureSensor - soilSensor3 = SoilMoistureSensor(&RS485Serial, 3, RE_DE_PIN); //..... -SoilMoistureSensor soilSensor4 = SoilMoistureSensor(&RS485Serial, 4, RE_DE_PIN); -SoilMoistureSensor soilSensor5 = SoilMoistureSensor(&RS485Serial, 5, RE_DE_PIN); - -void Forte_RS485::setup() { - // configure the pins to be output only - pinMode(RE_DE_PIN, OUTPUT); - pinMode(POWER_SWITCH_PIN_12V, OUTPUT); - pinMode(POWER_SWITCH_PIN_5V, OUTPUT); - RS485Serial.begin(4800, SERIAL_8N1, TXPin, RXPin); +SEM228A solarSensor(1, RE_DE_PIN); +SEM404 rainGauge = SEM404(2, RE_DE_PIN); + +void ForteRS485::setup() { + RS485Serial = RS485HardwareSerial::getInstance().getRS485Serial(); + // configure the pins to be output only + pinMode(RE_DE_PIN, OUTPUT); + pinMode(POWER_SWITCH_PIN_12V, OUTPUT); + pinMode(POWER_SWITCH_PIN_5V, OUTPUT); + RS485Serial->begin(4800, SERIAL_8N1, TX_PIN, RX_PIN); +} + +void ForteRS485::teardown() { + RS485Serial->end(); +} + +out_data_rs485 ForteRS485::readData() { + powerOnRS485Sensors(); + + out_data_rs485 output{}; + output.solar = solarSensor.readData(); + output.precipitation = rainGauge.readData(); + + powerOffRS485Sensors(); + return output; } +void ForteRS485::powerOffRS485Sensors() { + digitalWrite(POWER_SWITCH_PIN_12V, LOW); + digitalWrite(POWER_SWITCH_PIN_5V, LOW); -out_data_rs485 Forte_RS485::readData() { - // Power on sensor - digitalWrite(POWER_SWITCH_PIN_12V, HIGH); - digitalWrite(POWER_SWITCH_PIN_5V, HIGH); - // Wait for sensors to power up - // TODO minimize delay - delay(300); - out_data_rs485 output; - unsigned long ts = millis(); - output.solarRadiation = solarSensor.getSolarRadiation(); - output.soilTemperature3 = soilSensor3.getMoistureTemp(); - output.soilTemperature4 = soilSensor4.getMoistureTemp(); - output.soilTemperature5 = soilSensor5.getMoistureTemp(); - output.soilMoisture3 = soilSensor3.getMoisture(); - output.soilMoisture4 = soilSensor4.getMoisture(); - output.soilMoisture5 = soilSensor5.getMoisture(); - output.precipitation = rainGauge.getInstantaneousPrecipitation(); - digitalWrite(POWER_SWITCH_PIN_12V, LOW); - digitalWrite(POWER_SWITCH_PIN_5V, LOW); - - gpio_hold_en((gpio_num_t) POWER_SWITCH_PIN_12V); - gpio_hold_en((gpio_num_t) POWER_SWITCH_PIN_5V); - return output; + gpio_hold_en((gpio_num_t)POWER_SWITCH_PIN_12V); + gpio_hold_en((gpio_num_t)POWER_SWITCH_PIN_5V); +} +void ForteRS485::powerOnRS485Sensors() { // Power on sensor + digitalWrite(POWER_SWITCH_PIN_12V, HIGH); + digitalWrite(POWER_SWITCH_PIN_5V, HIGH); // Wait for sensors to power up + // TODO minimize delay + delay(100); } -std::list<Message> Forte_RS485::buildMessages() { - std::list<Message> messages; - out_data_rs485 output = readData(); - Measurement - solarRadiation{output.solarRadiation, MeasurementType::SOLAR_RADIATION}; - Measurement - soilTemp3{output.soilTemperature3, MeasurementType::SOIL_TEMPERATURE_3}; - Measurement - soilTemp4{output.soilTemperature4, MeasurementType::SOIL_TEMPERATURE_4}; - Measurement - soilTemp5{output.soilTemperature5, MeasurementType::SOIL_TEMPERATURE_5}; - Measurement - soilMoisture3{output.soilMoisture3, MeasurementType::SOIL_MOISTURE_3}; - Measurement - soilMoisture4{output.soilMoisture4, MeasurementType::SOIL_MOISTURE_4}; - Measurement - soilMoisture5{output.soilMoisture5, MeasurementType::SOIL_MOISTURE_5}; - Measurement - precipitation{output.precipitation, MeasurementType::PRECIPITATION}; - - messages.emplace_back(solarRadiation, sensorInformation, - Time::getInstance().getEpochSeconds()); - messages.emplace_back(soilTemp3, sensorInformation, - Time::getInstance().getEpochSeconds()); - messages.emplace_back(soilTemp4, sensorInformation, - Time::getInstance().getEpochSeconds()); - messages.emplace_back(soilTemp5, sensorInformation, - Time::getInstance().getEpochSeconds()); - messages.emplace_back(soilMoisture3, sensorInformation, - Time::getInstance().getEpochSeconds()); - messages.emplace_back(soilMoisture4, sensorInformation, - Time::getInstance().getEpochSeconds()); - messages.emplace_back(soilMoisture5, sensorInformation, - Time::getInstance().getEpochSeconds()); - messages.emplace_back(precipitation, - sensorInformation, - Time::getInstance().getEpochSeconds()); - - return messages; +std::list<Message> ForteRS485::buildMessages() { + std::list<Message> messages; + out_data_rs485 output = readData(); + + Measurement solarRadiation{output.solar.solarRadiation, 1, NO_I2C_ADDRESS, MeasurementType::SOLAR_RADIATION, + output.solar.solarError}; + Measurement precipitation{output.precipitation.precipitation, 2, NO_I2C_ADDRESS, MeasurementType::PRECIPITATION, + output.precipitation.precipitationError}; + + messages.emplace_back(solarRadiation, sensorInformation, Time::getInstance().getEpochSeconds()); + messages.emplace_back(precipitation, sensorInformation, Time::getInstance().getEpochSeconds()); + + return messages; } -SensorInformation Forte_RS485::getSensorInformation() const { - return sensorInformation; +SensorInformation ForteRS485::getSensorInformation() const { + return sensorInformation; } \ No newline at end of file diff --git a/client/libs/rs485/rs485.hpp b/client/libs/rs485/rs485.hpp index 7ae7c9287f12f4af6370398495bfa083e9a88a5a..823fecbafcd6a506605f66d02abea4888d231fee 100644 --- a/client/libs/rs485/rs485.hpp +++ b/client/libs/rs485/rs485.hpp @@ -1,32 +1,48 @@ #ifndef _RS485 #define _RS485 -#include <MeasurementTypes.h> -#include "Message.hpp" #include "ForteSensor.hpp" -#include "SentecSensors.h" +#include "Message.hpp" +#include "SentecSensorsRS485.h" +#include <MeasurementTypes.h> +#include <RS485HardwareSerial.h> +#include <SentecRainGaugeSensor.h> +#include <SentecSolarRadiationSensor.h> + +/** + * @brief Struct to hold all the data from the RS485 sensors + */ struct out_data_rs485 { - float solarRadiation; - float soilMoisture3; - float soilTemperature3; - float soilMoisture4; - float soilTemperature4; - float soilMoisture5; - float soilTemperature5; - float precipitation; + out_data_solar_radiation solar; + out_data_rain_gauge precipitation; }; -class Forte_RS485: public ForteSensor<out_data_rs485> { - public: - void setup() override; - out_data_rs485 readData() override; - std::list<Message> buildMessages() override; - [[nodiscard]] SensorInformation getSensorInformation() const override; +/** + * @brief Class to read data from both the Sentec solar radiation sensor and the Sentec rain gauge sensor at once + * This class is required to be instantiated and setup in order to use RS485 communication. + */ +class ForteRS485 : public ForteSensor<out_data_rs485> { + public: + void setup() override; + out_data_rs485 readData() override; + std::list<Message> buildMessages() override; + [[nodiscard]] SensorInformation getSensorInformation() const override; + void teardown(); + + /** + * @brief Power on the RS485 sensors + */ + static void powerOnRS485Sensors(); + + /** + * @brief Power off the RS485 sensors + */ + static void powerOffRS485Sensors(); - private: - const SensorInformation - sensorInformation{HardwareName::RS485, SensorProtocol::RS485}; + private: + std::shared_ptr<HardwareSerial> RS485Serial; + const SensorInformation sensorInformation{HardwareName::RS485, SensorProtocol::RS485}; }; -#endif \ No newline at end of file +#endif \ No newline at end of file diff --git a/host/host_central_mast/lib/Utilities/SDCardLogger.cpp b/host/host_central_mast/lib/Utilities/SDCardLogger.cpp index e35196503a0b10e858b8f32916ae4b2acaef24a3..86735a0abb3396887422d0957024a801c2a5e358 100644 --- a/host/host_central_mast/lib/Utilities/SDCardLogger.cpp +++ b/host/host_central_mast/lib/Utilities/SDCardLogger.cpp @@ -13,12 +13,14 @@ namespace SDCardLogger { printToSerial = printToSerialAsWell; } int vprintf_into_sd(const char *szFormat, va_list args) { - String logstring = "[" + rtc.getDateTime() + "] "; - logstring += szFormat; + auto timeSinceBootMs = esp_timer_get_time() / 1000; + String logstring = String(timeSinceBootMs) + ", "; // print current core logstring += "Core: "; logstring += xPortGetCoreID(); - logstring += ". "; + logstring += ", "; + logstring += "[" + rtc.getDateTime() + "] "; + logstring += szFormat; if (!SDUtilities::isSDAvailable()) { if (printToSerial) { logstring += " (SD card not available)\n"; diff --git a/shared-libs/DataTransfer/ErrorTypes.cpp b/shared-libs/DataTransfer/ErrorTypes.cpp index 8526b717b36e6328c8c08f5cab1af360112e557d..558d35f4a465320a9d1856eafcf9afaf4852192b 100644 --- a/shared-libs/DataTransfer/ErrorTypes.cpp +++ b/shared-libs/DataTransfer/ErrorTypes.cpp @@ -5,37 +5,42 @@ #include "ErrorTypes.h" namespace ErrorTypes { - // INFO: If you add a new error type, add it here and to the documentation at https://git.uibk.ac.at/informatik/qe/forte/sensor-system/-/wikis/Error-Types as well + // INFO: If you add a new error type, add it here and to the documentation at + // https://git.uibk.ac.at/informatik/qe/forte/sensor-system/-/wikis/Error-Types as well std::string errorTypeToString(ErrorType errorType) { switch (errorType) { - case ErrorType::SENSOR_NOT_FOUND: - return "SENSOR_NOT_FOUND"; - case ErrorType::SENSOR_NOT_CONNECTED: - return "SENSOR_NOT_CONNECTED"; - case ErrorType::NO_DATA: - return "NO_DATA"; - case ErrorType::DATA_OK: - return "DATA_OK"; - case ErrorType::NULL_MESSAGE: - return "NULL_MESSAGE"; - case ErrorType::SENSOR_DOES_NOT_RETURN_DATA: - return "SENSOR_DOES_NOT_RETURN_DATA"; - case ErrorType::BATTERY_VOLTAGE_TOO_LOW: - return "BATTERY_VOLTAGE_TOO_LOW"; - case ErrorType::INVALID_VALUE: - return "INVALID_VALUE"; - case ErrorType::SENSOR_INIT_FAILED: - return "SENSOR_INIT_FAILED"; - case ErrorType::INA219_OVERFLOW: - return "INA219_OVERFLOW"; - case ErrorType::CONNECTION_ENDED_PREMATURELY: - return "CONNECTION_ENDED_PREMATURELY"; - case ErrorType::WRONG_CRC: - return "WRONG_CRC"; - case ErrorType::UNKNOWN: - default: - return "UNKNOWN_ERROR_TYPE"; + case ErrorType::SENSOR_NOT_FOUND: + return "SENSOR_NOT_FOUND"; + case ErrorType::SENSOR_NOT_CONNECTED: + return "SENSOR_NOT_CONNECTED"; + case ErrorType::NO_DATA: + return "NO_DATA"; + case ErrorType::DATA_OK: + return "DATA_OK"; + case ErrorType::NULL_MESSAGE: + return "NULL_MESSAGE"; + case ErrorType::SENSOR_DOES_NOT_RETURN_DATA: + return "SENSOR_DOES_NOT_RETURN_DATA"; + case ErrorType::BATTERY_VOLTAGE_TOO_LOW: + return "BATTERY_VOLTAGE_TOO_LOW"; + case ErrorType::INVALID_VALUE: + return "INVALID_VALUE"; + case ErrorType::SENSOR_INIT_FAILED: + return "SENSOR_INIT_FAILED"; + case ErrorType::INA219_OVERFLOW: + return "INA219_OVERFLOW"; + case ErrorType::CONNECTION_ENDED_PREMATURELY: + return "CONNECTION_ENDED_PREMATURELY"; + case ErrorType::WRONG_CRC: + return "WRONG_CRC"; + case ErrorType::SEM404_COULD_NOT_RESET_PRECIPITATION: + return "SEM404_COULD_NOT_RESET_PRECIPITATION"; + case ErrorType::COULD_NOT_SET_ADDRESS: + return "COULD_NOT_SET_ADDRESS"; + case ErrorType::UNKNOWN: + default: + return "UNKNOWN_ERROR_TYPE"; } } -} \ No newline at end of file +} // namespace ErrorTypes \ No newline at end of file diff --git a/shared-libs/DataTransfer/ErrorTypes.h b/shared-libs/DataTransfer/ErrorTypes.h index 3d12cbd8bbdc923154322960ed984ef9e734334a..c53c25f13d774540decaba83b2ae2a73741aab16 100644 --- a/shared-libs/DataTransfer/ErrorTypes.h +++ b/shared-libs/DataTransfer/ErrorTypes.h @@ -11,6 +11,8 @@ enum class ErrorType : char { SENSOR_NOT_FOUND, SENSOR_INIT_FAILED, SENSOR_NOT_CONNECTED, + SEM404_COULD_NOT_RESET_PRECIPITATION, + COULD_NOT_SET_ADDRESS, NO_DATA, DATA_OK, NULL_MESSAGE, // message that is sent as padding, should be thrown away @@ -19,7 +21,7 @@ enum class ErrorType : char { INVALID_VALUE, INA219_OVERFLOW, CONNECTION_ENDED_PREMATURELY, // connection ended prematurely - WRONG_CRC, // corrupted data package + WRONG_CRC, // corrupted data package UNKNOWN, }; @@ -27,5 +29,4 @@ namespace ErrorTypes { std::string errorTypeToString(ErrorType errorType); } - -#endif //CLIENT_MOCK_ERRORTYPES_H +#endif // CLIENT_MOCK_ERRORTYPES_H diff --git a/shared-libs/DataTransfer/HardwareNames.cpp b/shared-libs/DataTransfer/HardwareNames.cpp index 72c2256e8833d912ca02021593d71949679ada0f..94fbb405a8e7faf9fe22995f3720d12c9876b849 100644 --- a/shared-libs/DataTransfer/HardwareNames.cpp +++ b/shared-libs/DataTransfer/HardwareNames.cpp @@ -4,36 +4,42 @@ #include "HardwareNames.h" namespace HardwareNames { - std::string hardwareNameToString(HardwareName hardwareName) { - // switch - switch (hardwareName) { - case HardwareName::RS485: - return "RS485"; - case HardwareName::INA219: - return "INA219"; - case HardwareName::SCD30: - return "SCD30"; - case HardwareName::RAIN_GAUGE: - return "RAIN_GAUGE"; - case HardwareName::SOIL_MOISTURE_SENSOR: - return "SOIL_MOISTURE_SENSOR"; - case HardwareName::SOIL_TEMPERATURE_SENSOR: - return "SOIL_TEMPERATURE_SENSOR"; - case HardwareName::SOLAR_RADIATION_SENSOR: - return "SOLAR_RADIATION_SENSOR"; - case HardwareName::SHT85: - return "SHT85"; - case HardwareName::DRS26: - return "DRS26"; - case HardwareName::DR26: - return "DR26"; - case HardwareName::MOCK: - return "MOCK"; - case HardwareName::NONE: - return "NONE"; - case HardwareName::LC709203: - break; - } - return "UNKNOWN_HARDWARE_NAME"; - } +std::string hardwareNameToString(HardwareName hardwareName) { + // switch + switch (hardwareName) { + case HardwareName::RS485: + return "RS485"; + case HardwareName::INA219: + return "INA219"; + case HardwareName::SCD30: + return "SCD30"; + case HardwareName::RAIN_GAUGE: + return "RAIN_GAUGE"; + case HardwareName::SOIL_MOISTURE_SENSOR: + return "SOIL_MOISTURE_SENSOR"; + case HardwareName::SOIL_TEMPERATURE_SENSOR: + return "SOIL_TEMPERATURE_SENSOR"; + case HardwareName::SOLAR_RADIATION_SENSOR: + return "SOLAR_RADIATION_SENSOR"; + case HardwareName::SHT85: + return "SHT85"; + case HardwareName::DRS26: + return "DRS26"; + case HardwareName::DR26: + return "DR26"; + case HardwareName::MOCK: + return "MOCK"; + case HardwareName::NONE: + return "NONE"; + case HardwareName::LC709203: + return "LC709203"; + case HardwareName::SEM228A: + return "SEM228A"; + case HardwareName::SEM225: + return "SEM225"; + case HardwareName::SEM404: + return "SEM404"; + } + return "UNKNOWN_HARDWARE_NAME"; +} } // namespace HardwareNames \ No newline at end of file diff --git a/shared-libs/DataTransfer/HardwareNames.h b/shared-libs/DataTransfer/HardwareNames.h index 5bf6930379ab6069940cd6763eb022db8d511287..ee689f81c5fc58f810fc99d83a2cfa6340fa3b34 100644 --- a/shared-libs/DataTransfer/HardwareNames.h +++ b/shared-libs/DataTransfer/HardwareNames.h @@ -16,6 +16,9 @@ enum class HardwareName : short { SOIL_MOISTURE_SENSOR, SOIL_TEMPERATURE_SENSOR, SOLAR_RADIATION_SENSOR, + SEM404, + SEM228A, + SEM225, SHT85, DRS26, DR26, diff --git a/shared-libs/DataTransfer/MeasurementTypes.cpp b/shared-libs/DataTransfer/MeasurementTypes.cpp index 220da6e1879f570b4faacd47372aea5974bdee7b..6144cc12a8338955307d71a59e7958fc274d92e4 100644 --- a/shared-libs/DataTransfer/MeasurementTypes.cpp +++ b/shared-libs/DataTransfer/MeasurementTypes.cpp @@ -47,6 +47,10 @@ std::string measurementTypeToString(MeasurementType measurementType) { return "CO2"; case MeasurementType::NULL_MEASUREMENT: return "NULL_MEASUREMENT"; + case MeasurementType::SOIL_MOISTURE: + return "SOIL_MOISTURE"; + case MeasurementType::SOIL_TEMPERATURE: + return "SOIL_TEMPERATURE"; } return "UNKNOWN"; } diff --git a/shared-libs/DataTransfer/MeasurementTypes.h b/shared-libs/DataTransfer/MeasurementTypes.h index 0818bba5453a7223c9f84025bd9608343a6a0672..f642e3b6cca9372cc2d206cf7bd1d27072a33acf 100644 --- a/shared-libs/DataTransfer/MeasurementTypes.h +++ b/shared-libs/DataTransfer/MeasurementTypes.h @@ -20,6 +20,8 @@ enum class MeasurementType { BATTERY_VOLTAGE, MOCK, SOLAR_RADIATION, + SOIL_MOISTURE, + SOIL_TEMPERATURE, SOIL_MOISTURE_3, SOIL_TEMPERATURE_3, SOIL_MOISTURE_4,