From 1a926726032769abfa6aa8abde8e9036b2fd99d2 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Fri, 20 Jun 2025 09:52:47 +0200 Subject: [PATCH] Added Example files from Waveshare repo --- .gitignore | 1 + .vscode/extensions.json | 10 + .vscode/launch.json | 44 ++++ build/esp32-s3-devkitm-1/idedata.json | 1 + build/project.checksum | 1 + include/README | 37 +++ lib/README | 46 ++++ platformio.ini | 18 ++ src/I2C_Driver.cpp | 36 +++ src/I2C_Driver.h | 10 + src/MAIN_WIFI_MQTT.cpp | 37 +++ src/WS_Bluetooth.cpp | 152 +++++++++++ src/WS_Bluetooth.h | 24 ++ src/WS_CAN.cpp | 219 ++++++++++++++++ src/WS_CAN.h | 22 ++ src/WS_DIN.cpp | 151 +++++++++++ src/WS_DIN.h | 18 ++ src/WS_ETH.cpp | 120 +++++++++ src/WS_ETH.h | 44 ++++ src/WS_GPIO.cpp | 166 ++++++++++++ src/WS_GPIO.h | 44 ++++ src/WS_Information.h | 18 ++ src/WS_MQTT.cpp | 248 ++++++++++++++++++ src/WS_MQTT.h | 25 ++ src/WS_PCF85063.cpp | 189 ++++++++++++++ src/WS_PCF85063.h | 103 ++++++++ src/WS_RS485.cpp | 163 ++++++++++++ src/WS_RS485.h | 26 ++ src/WS_RTC.cpp | 350 ++++++++++++++++++++++++++ src/WS_RTC.h | 45 ++++ src/WS_Relay.cpp | 273 ++++++++++++++++++++ src/WS_Relay.h | 56 +++++ src/WS_SD.cpp | 113 +++++++++ src/WS_SD.h | 18 ++ src/WS_Serial.cpp | 8 + src/WS_Serial.h | 8 + src/WS_TCA9554PWR.cpp | 107 ++++++++ src/WS_TCA9554PWR.h | 41 +++ test/README | 11 + 39 files changed, 3003 insertions(+) create mode 100644 .vscode/extensions.json create mode 100644 .vscode/launch.json create mode 100644 build/esp32-s3-devkitm-1/idedata.json create mode 100644 build/project.checksum create mode 100644 include/README create mode 100644 lib/README create mode 100644 platformio.ini create mode 100644 src/I2C_Driver.cpp create mode 100644 src/I2C_Driver.h create mode 100644 src/MAIN_WIFI_MQTT.cpp create mode 100644 src/WS_Bluetooth.cpp create mode 100644 src/WS_Bluetooth.h create mode 100644 src/WS_CAN.cpp create mode 100644 src/WS_CAN.h create mode 100644 src/WS_DIN.cpp create mode 100644 src/WS_DIN.h create mode 100644 src/WS_ETH.cpp create mode 100644 src/WS_ETH.h create mode 100644 src/WS_GPIO.cpp create mode 100644 src/WS_GPIO.h create mode 100644 src/WS_Information.h create mode 100644 src/WS_MQTT.cpp create mode 100644 src/WS_MQTT.h create mode 100644 src/WS_PCF85063.cpp create mode 100644 src/WS_PCF85063.h create mode 100644 src/WS_RS485.cpp create mode 100644 src/WS_RS485.h create mode 100644 src/WS_RTC.cpp create mode 100644 src/WS_RTC.h create mode 100644 src/WS_Relay.cpp create mode 100644 src/WS_Relay.h create mode 100644 src/WS_SD.cpp create mode 100644 src/WS_SD.h create mode 100644 src/WS_Serial.cpp create mode 100644 src/WS_Serial.h create mode 100644 src/WS_TCA9554PWR.cpp create mode 100644 src/WS_TCA9554PWR.h create mode 100644 test/README diff --git a/.gitignore b/.gitignore index 24ceb21..fcc3e15 100644 --- a/.gitignore +++ b/.gitignore @@ -87,6 +87,7 @@ Mkfile.old dkms.conf # ---> VisualStudioCode +.pio .vscode/* !.vscode/settings.json !.vscode/tasks.json diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..080e70d --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..d9a0fc2 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,44 @@ +// AUTOMATICALLY GENERATED FILE. PLEASE DO NOT MODIFY IT MANUALLY +// +// PlatformIO Debugging Solution +// +// Documentation: https://docs.platformio.org/en/latest/plus/debugging.html +// Configuration: https://docs.platformio.org/en/latest/projectconf/sections/env/options/debug/index.html + +{ + "version": "0.2.0", + "configurations": [ + { + "type": "platformio-debug", + "request": "launch", + "name": "PIO Debug", + "executable": "d:/Emanuele/Documenti/VScode/ETcontroller_PRO/.pio/build/esp32-s3-devkitm-1/firmware.elf", + "projectEnvName": "esp32-s3-devkitm-1", + "toolchainBinDir": "C:/Users/Emanuele Trabattoni/.platformio/packages/toolchain-xtensa-esp32s3/bin", + "internalConsoleOptions": "openOnSessionStart", + "preLaunchTask": { + "type": "PlatformIO", + "task": "Pre-Debug" + } + }, + { + "type": "platformio-debug", + "request": "launch", + "name": "PIO Debug (skip Pre-Debug)", + "executable": "d:/Emanuele/Documenti/VScode/ETcontroller_PRO/.pio/build/esp32-s3-devkitm-1/firmware.elf", + "projectEnvName": "esp32-s3-devkitm-1", + "toolchainBinDir": "C:/Users/Emanuele Trabattoni/.platformio/packages/toolchain-xtensa-esp32s3/bin", + "internalConsoleOptions": "openOnSessionStart" + }, + { + "type": "platformio-debug", + "request": "launch", + "name": "PIO Debug (without uploading)", + "executable": "d:/Emanuele/Documenti/VScode/ETcontroller_PRO/.pio/build/esp32-s3-devkitm-1/firmware.elf", + "projectEnvName": "esp32-s3-devkitm-1", + "toolchainBinDir": "C:/Users/Emanuele Trabattoni/.platformio/packages/toolchain-xtensa-esp32s3/bin", + "internalConsoleOptions": "openOnSessionStart", + "loadMode": "manual" + } + ] +} diff --git a/build/esp32-s3-devkitm-1/idedata.json b/build/esp32-s3-devkitm-1/idedata.json new file mode 100644 index 0000000..b92bf1d --- /dev/null +++ b/build/esp32-s3-devkitm-1/idedata.json @@ -0,0 +1 @@ +{"build_type": "release", "env_name": "esp32-s3-devkitm-1", "libsource_dirs": ["d:\\Emanuele\\Documenti\\PlatformIO\\Projects\\250620-093152-esp32-s3-devkitm-1\\lib", "d:\\Emanuele\\Documenti\\PlatformIO\\Projects\\250620-093152-esp32-s3-devkitm-1\\.pio\\libdeps\\esp32-s3-devkitm-1", "C:\\Users\\Emanuele Trabattoni\\.platformio\\lib", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries"], "defines": ["PLATFORMIO=60118", "ARDUINO_ESP32S3_DEV", "ARDUINO_USB_MODE=1", "ARDUINO_RUNNING_CORE=1", "ARDUINO_EVENT_RUNNING_CORE=1", "HAVE_CONFIG_H", "MBEDTLS_CONFIG_FILE=\"mbedtls/esp_config.h\"", "UNITY_INCLUDE_CONFIG_H", "WITH_POSIX", "_GNU_SOURCE", "IDF_VER=\"v4.4.7-dirty\"", "ESP_PLATFORM", "_POSIX_READER_WRITER_LOCKS", "ARDUINO_ARCH_ESP32", "ESP32", "F_CPU=240000000L", "ARDUINO=10812", "ARDUINO_VARIANT=\"esp32s3\"", "ARDUINO_BOARD=\"Espressif ESP32-S3-DevKitM-1\"", "ARDUINO_PARTITION_default"], "includes": {"build": ["d:\\Emanuele\\Documenti\\PlatformIO\\Projects\\250620-093152-esp32-s3-devkitm-1\\include", "d:\\Emanuele\\Documenti\\PlatformIO\\Projects\\250620-093152-esp32-s3-devkitm-1\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\SD_MMC\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\FS\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\WiFiClientSecure\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\SPI\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\Ethernet\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\BLE\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\Wire\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\WiFi\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\newlib\\platform_include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\freertos\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\freertos\\include\\esp_additions\\freertos", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\freertos\\port\\xtensa\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\freertos\\include\\esp_additions", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_hw_support\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_hw_support\\include\\soc", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_hw_support\\include\\soc\\esp32s3", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_hw_support\\port\\esp32s3", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_hw_support\\port\\esp32s3\\private_include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\heap\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\log\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\lwip\\include\\apps", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\lwip\\include\\apps\\sntp", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\lwip\\lwip\\src\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\lwip\\port\\esp32\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\lwip\\port\\esp32\\include\\arch", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\soc\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\soc\\esp32s3", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\soc\\esp32s3\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\hal\\esp32s3\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\hal\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\hal\\platform_port\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_rom\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_rom\\include\\esp32s3", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_rom\\esp32s3", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_common\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_system\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_system\\port\\soc", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_system\\port\\public_compat", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\xtensa\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\xtensa\\esp32s3\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\driver\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\driver\\esp32s3\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_pm\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_ringbuf\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\efuse\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\efuse\\esp32s3\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\vfs\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_wifi\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_event\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_netif\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_eth\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\tcpip_adapter\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_phy\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_phy\\esp32s3\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_ipc\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\app_trace\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_timer\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\mbedtls\\port\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\mbedtls\\mbedtls\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\mbedtls\\esp_crt_bundle\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\app_update\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\spi_flash\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\bootloader_support\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\nvs_flash\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\pthread\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_gdbstub\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_gdbstub\\xtensa", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_gdbstub\\esp32s3", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espcoredump\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espcoredump\\include\\port\\xtensa", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\wpa_supplicant\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\wpa_supplicant\\port\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\wpa_supplicant\\esp_supplicant\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\ieee802154\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\console", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\asio\\asio\\asio\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\asio\\port\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\bt\\common\\osi\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\bt\\include\\esp32c3\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\bt\\common\\api\\include\\api", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\bt\\common\\btc\\profile\\esp\\blufi\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\bt\\common\\btc\\profile\\esp\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\bt\\host\\bluedroid\\api\\include\\api", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\mesh_common\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\mesh_common\\tinycrypt\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\mesh_core", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\mesh_core\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\mesh_core\\storage", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\btc\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\mesh_models\\common\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\mesh_models\\client\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\mesh_models\\server\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\api\\core\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\api\\models\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\api", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\cbor\\port\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\unity\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\unity\\unity\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\cmock\\CMock\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\coap\\port\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\coap\\libcoap\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\nghttp\\port\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\nghttp\\nghttp2\\lib\\includes", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp-tls", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp-tls\\esp-tls-crypto", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_adc_cal\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_hid\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\tcp_transport\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_http_client\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_http_server\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_https_ota\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_https_server\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_lcd\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_lcd\\interface", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\protobuf-c\\protobuf-c", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\protocomm\\include\\common", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\protocomm\\include\\security", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\protocomm\\include\\transports", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\mdns\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_local_ctrl\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\sdmmc\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_serial_slave_link\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_websocket_client\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\expat\\expat\\expat\\lib", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\expat\\port\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\wear_levelling\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\fatfs\\diskio", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\fatfs\\vfs", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\fatfs\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\freemodbus\\freemodbus\\common\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\idf_test\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\idf_test\\include\\esp32s3", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\jsmn\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\json\\cJSON", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\libsodium\\libsodium\\src\\libsodium\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\libsodium\\port_include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\mqtt\\esp-mqtt\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\openssl\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\perfmon\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\spiffs\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\usb\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\ulp\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\wifi_provisioning\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\rmaker_common\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_diagnostics\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\rtc_store\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_insights\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\json_parser\\upstream\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\json_parser\\upstream", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\json_generator\\upstream", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_schedule\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp_secure_cert_mgr\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_rainmaker\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\gpio_button\\button\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\qrcode\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\ws2812_led", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\freertos\\include\\freertos", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\arduino_tinyusb\\tinyusb\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\arduino_tinyusb\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp_littlefs\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp-dl\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp-dl\\include\\tool", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp-dl\\include\\typedef", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp-dl\\include\\image", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp-dl\\include\\math", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp-dl\\include\\nn", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp-dl\\include\\layer", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp-dl\\include\\detect", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp-dl\\include\\model_zoo", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp32-camera\\driver\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\esp32-camera\\conversions\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\dotprod\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\support\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\support\\mem\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\windows\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\windows\\hann\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\windows\\blackman\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\windows\\blackman_harris\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\windows\\blackman_nuttall\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\windows\\nuttall\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\windows\\flat_top\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\iir\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\fir\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\math\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\math\\add\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\math\\sub\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\math\\mul\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\math\\addc\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\math\\mulc\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\math\\sqrt\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\matrix\\mul\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\matrix\\add\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\matrix\\addc\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\matrix\\mulc\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\matrix\\sub\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\matrix\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\fft\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\dct\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\conv\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\common\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\matrix\\mul\\test\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\kalman\\ekf\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\kalman\\ekf_imu13states\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\include\\fb_gfx\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\sdk\\esp32s3\\qio_qspi\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\cores\\esp32", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\variants\\esp32s3"], "compatlib": ["C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\BLE\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\Ethernet\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\FS\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\SD_MMC\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\SPI\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\WiFi\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\WiFiClientSecure\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\Wire\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\ArduinoOTA\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\AsyncUDP\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\BluetoothSerial\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\DNSServer\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\EEPROM\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\ESP32\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\ESPmDNS\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\FFat\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\HTTPClient\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\HTTPUpdate\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\HTTPUpdateServer\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\I2S\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\Insights\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\LittleFS\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\NetBIOS\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\Preferences\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\RainMaker\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\SD\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\SPIFFS\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\SimpleBLE\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\Ticker\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\USB\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\Update\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\WebServer\\src", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\libraries\\WiFiProv\\src"], "toolchain": ["C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\toolchain-riscv32-esp\\riscv32-esp-elf\\include\\c++\\8.4.0", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\toolchain-riscv32-esp\\riscv32-esp-elf\\include\\c++\\8.4.0\\riscv32-esp-elf", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\toolchain-riscv32-esp\\lib\\gcc\\riscv32-esp-elf\\8.4.0\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\toolchain-riscv32-esp\\lib\\gcc\\riscv32-esp-elf\\8.4.0\\include-fixed", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\toolchain-riscv32-esp\\riscv32-esp-elf\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\toolchain-xtensa-esp32s3\\xtensa-esp32s3-elf\\include\\c++\\8.4.0", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\toolchain-xtensa-esp32s3\\xtensa-esp32s3-elf\\include\\c++\\8.4.0\\xtensa-esp32s3-elf", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\toolchain-xtensa-esp32s3\\lib\\gcc\\xtensa-esp32s3-elf\\8.4.0\\include", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\toolchain-xtensa-esp32s3\\lib\\gcc\\xtensa-esp32s3-elf\\8.4.0\\include-fixed", "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\toolchain-xtensa-esp32s3\\xtensa-esp32s3-elf\\include"]}, "cc_flags": ["-std=gnu99", "-Wno-old-style-declaration", "-Os", "-mlongcalls", "-ffunction-sections", "-fdata-sections", "-Wno-error=unused-function", "-Wno-error=unused-variable", "-Wno-error=deprecated-declarations", "-Wno-unused-parameter", "-Wno-sign-compare", "-ggdb", "-freorder-blocks", "-Wwrite-strings", "-fstack-protector", "-fstrict-volatile-bitfields", "-Wno-error=unused-but-set-variable", "-fno-jump-tables", "-fno-tree-switch-conversion", "-MMD"], "cxx_flags": ["-std=gnu++11", "-fexceptions", "-fno-rtti", "-Os", "-mlongcalls", "-ffunction-sections", "-fdata-sections", "-Wno-error=unused-function", "-Wno-error=unused-variable", "-Wno-error=deprecated-declarations", "-Wno-unused-parameter", "-Wno-sign-compare", "-ggdb", "-freorder-blocks", "-Wwrite-strings", "-fstack-protector", "-fstrict-volatile-bitfields", "-Wno-error=unused-but-set-variable", "-fno-jump-tables", "-fno-tree-switch-conversion", "-MMD"], "cc_path": "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\toolchain-xtensa-esp32s3\\bin\\xtensa-esp32s3-elf-gcc.exe", "cxx_path": "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\toolchain-xtensa-esp32s3\\bin\\xtensa-esp32s3-elf-g++.exe", "gdb_path": "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\toolchain-xtensa-esp32s3\\bin\\xtensa-esp32s3-elf-gdb.exe", "prog_path": "d:\\Emanuele\\Documenti\\PlatformIO\\Projects\\250620-093152-esp32-s3-devkitm-1\\.pio\\build\\esp32-s3-devkitm-1\\firmware.elf", "svd_path": null, "compiler_type": "gcc", "targets": [{"name": "buildfs", "title": "Build Filesystem Image", "description": null, "group": "Platform"}, {"name": "size", "title": "Program Size", "description": "Calculate program size", "group": "Platform"}, {"name": "upload", "title": "Upload", "description": null, "group": "Platform"}, {"name": "uploadfs", "title": "Upload Filesystem Image", "description": null, "group": "Platform"}, {"name": "uploadfsota", "title": "Upload Filesystem Image OTA", "description": null, "group": "Platform"}, {"name": "erase", "title": "Erase Flash", "description": null, "group": "Platform"}], "extra": {"flash_images": [{"offset": "0x0000", "path": "D:\\Emanuele\\Documenti\\PlatformIO\\Projects\\250620-093152-esp32-s3-devkitm-1\\.pio\\build\\esp32-s3-devkitm-1\\bootloader.bin"}, {"offset": "0x8000", "path": "d:\\Emanuele\\Documenti\\PlatformIO\\Projects\\250620-093152-esp32-s3-devkitm-1\\.pio\\build\\esp32-s3-devkitm-1\\partitions.bin"}, {"offset": "0xe000", "path": "C:\\Users\\Emanuele Trabattoni\\.platformio\\packages\\framework-arduinoespressif32\\tools\\partitions\\boot_app0.bin"}], "application_offset": "0x10000"}} \ No newline at end of file diff --git a/build/project.checksum b/build/project.checksum new file mode 100644 index 0000000..d876d84 --- /dev/null +++ b/build/project.checksum @@ -0,0 +1 @@ +cda0d1d4f19a5b63f560f45fa5bf4bc81f42e811 \ No newline at end of file diff --git a/include/README b/include/README new file mode 100644 index 0000000..49819c0 --- /dev/null +++ b/include/README @@ -0,0 +1,37 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the convention is to give header files names that end with `.h'. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..9379397 --- /dev/null +++ b/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into the executable file. + +The source code of each library should be placed in a separate directory +("lib/your_library_name/[Code]"). + +For example, see the structure of the following example libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +Example contents of `src/main.c` using Foo and Bar: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +The PlatformIO Library Dependency Finder will find automatically dependent +libraries by scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..30fc71c --- /dev/null +++ b/platformio.ini @@ -0,0 +1,18 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:esp32-s3-devkitm-1] +platform = espressif32 +board = esp32-s3-devkitm-1 +framework = arduino +lib_deps = + bblanchon/ArduinoJson@^7.4.2 + arduino-libraries/NTPClient@^3.2.1 + knolleary/PubSubClient@^2.8 diff --git a/src/I2C_Driver.cpp b/src/I2C_Driver.cpp new file mode 100644 index 0000000..826bfda --- /dev/null +++ b/src/I2C_Driver.cpp @@ -0,0 +1,36 @@ +#include "I2C_Driver.h" + + +void I2C_Init(void) { + Wire.begin( I2C_SDA_PIN, I2C_SCL_PIN); +} + + +bool I2C_Read(uint8_t Driver_addr, uint8_t Reg_addr, uint8_t *Reg_data, uint32_t Length) +{ + Wire.beginTransmission(Driver_addr); + Wire.write(Reg_addr); + if ( Wire.endTransmission(true)){ + printf("The I2C transmission fails. - I2C Read\r\n"); + return -1; + } + Wire.requestFrom(Driver_addr, Length); + for (int i = 0; i < Length; i++) { + *Reg_data++ = Wire.read(); + } + return 0; +} +bool I2C_Write(uint8_t Driver_addr, uint8_t Reg_addr, const uint8_t *Reg_data, uint32_t Length) +{ + Wire.beginTransmission(Driver_addr); + Wire.write(Reg_addr); + for (int i = 0; i < Length; i++) { + Wire.write(*Reg_data++); + } + if ( Wire.endTransmission(true)) + { + printf("The I2C transmission fails. - I2C Write\r\n"); + return -1; + } + return 0; +} \ No newline at end of file diff --git a/src/I2C_Driver.h b/src/I2C_Driver.h new file mode 100644 index 0000000..ca8d388 --- /dev/null +++ b/src/I2C_Driver.h @@ -0,0 +1,10 @@ +#pragma once +#include + +#define I2C_SCL_PIN 41 +#define I2C_SDA_PIN 42 + +void I2C_Init(void); + +bool I2C_Read(uint8_t Driver_addr, uint8_t Reg_addr, uint8_t *Reg_data, uint32_t Length); +bool I2C_Write(uint8_t Driver_addr, uint8_t Reg_addr, const uint8_t *Reg_data, uint32_t Length); \ No newline at end of file diff --git a/src/MAIN_WIFI_MQTT.cpp b/src/MAIN_WIFI_MQTT.cpp new file mode 100644 index 0000000..055e7dd --- /dev/null +++ b/src/MAIN_WIFI_MQTT.cpp @@ -0,0 +1,37 @@ +#include +#include // Reference the ESP32 built-in serial port library +#include "WS_MQTT.h" +#include "WS_Bluetooth.h" +#include "WS_GPIO.h" +#include "WS_Serial.h" +#include "WS_RTC.h" +#include "WS_GPIO.h" +#include "WS_DIN.h" +#include "WS_SD.h" +#include "WS_ETH.h" + + +uint32_t Simulated_time=0; // Analog time counting + +/******************************************************** Initializing ********************************************************/ +void setup() { + Flash_test(); + GPIO_Init(); // RGB . Buzzer GPIO + I2C_Init(); + RTC_Init();// RTC + SD_Init(); + Serial_Init(); // UART(RS485/CAN) + MQTT_Init();// MQTT + Bluetooth_Init();// Bluetooth + ETH_Init(); + + DIN_Init(); // If you don't want to control the relay through DIN, change Relay_Immediate_Default to 0 in WS_DIN.h and re-burn the program + Relay_Init(); + + printf("Connect to the WIFI network named \"ESP32-S3-POE-ETH-8DI-8RO\" and access the Internet using the connected IP address!!!\r\n"); +} + +/********************************************************** While **********************************************************/ +void loop() { + +} \ No newline at end of file diff --git a/src/WS_Bluetooth.cpp b/src/WS_Bluetooth.cpp new file mode 100644 index 0000000..fdbe1a2 --- /dev/null +++ b/src/WS_Bluetooth.cpp @@ -0,0 +1,152 @@ +#include "WS_Bluetooth.h" + +BLEServer* pServer; // Used to represent a BLE server +BLECharacteristic* pTxCharacteristic; +BLECharacteristic* pRxCharacteristic; + +/********************************************************** Bluetooth *********************************************************/ + +class MyServerCallbacks : public BLEServerCallbacks { //By overriding the onConnect() and onDisconnect() functions + void onConnect(BLEServer* pServer) { // When the Device is connected, "Device connected" is printed. + Serial.println("Device connected"); + } + + void onDisconnect(BLEServer* pServer) { // "Device disconnected" will be printed when the device is disconnected + Serial.println("Device disconnected"); + + BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); // Re-broadcast so that the device can query + pAdvertising->addServiceUUID(SERVICE_UUID); // Re-broadcast so that the device can query + pAdvertising->setScanResponse(true); // Re-broadcast so that the device can query + pAdvertising->setMinPreferred(0x06); // Re-broadcast so that the device can query + pAdvertising->setMinPreferred(0x12); // Re-broadcast so that the device can query + BLEDevice::startAdvertising(); // Re-broadcast so that the device can query + pRxCharacteristic->notify(); // Re-broadcast so that the device can query + pAdvertising->start(); // Re-broadcast so that the device can query + } +}; +class MyRXCallback : public BLECharacteristicCallbacks { + void onWrite(BLECharacteristic* pCharacteristic) { // The onWrite function is called when the remote device sends data to your feature + String rxValue = String(pCharacteristic->getValue().c_str()); + if (!rxValue.isEmpty()) { + // The received data rxValue is processed here + if(rxValue.length() == 1) + { + printf("%s\n", rxValue.c_str()); // Print output through the serial port + uint8_t* valueBytes = reinterpret_cast(const_cast(rxValue.c_str())); // Convert value to uint8 t* + Relay_Analysis(valueBytes,Bluetooth_Mode); // pilot relay + } + else if(rxValue.length() == 2) + { + if(Extension_Enable) + { + printf("%s\n", rxValue.c_str()); // Print output through the serial port + uint8_t* valueBytes = reinterpret_cast(const_cast(rxValue.c_str())); // Convert value to uint8 t* + if(valueBytes[0] == 0x06) // Instruction check correct + RS485_Analysis(valueBytes); // Control external relay + else + printf("Note : Non-instruction data was received - Bluetooth !\r\n"); + } + else + printf("Note : Non-instruction data was received or external relays are not enabled - Bluetooth !\r\n"); + } + + else if(rxValue.length() == 14) + { + if(RTC_Event_Enable) + { + // printf("%s\n", rxValue.c_str()); // Print output through the serial port + uint8_t* valueBytes = reinterpret_cast(const_cast(rxValue.c_str())); + BLE_Set_RTC_Event(valueBytes); + } + else + printf("Note : Non-instruction data was received or RTC events were not enabled - Bluetooth !\r\n"); + } + else + { + printf("Note : Non-instruction data was received - Bluetooth !\r\n"); + } + pRxCharacteristic->setValue(""); // After data is read, set it to blank for next read + } + } +}; + +void BLE_Set_RTC_Event(uint8_t* valueBytes){ + if(valueBytes[0] == 0xA1 && valueBytes[6] == 0xAA && valueBytes[13] == 0xFF ){ + datetime_t Event_Time={0}; + Event_Time.year = (valueBytes[1]/16*10 + valueBytes[1] % 16) *100 + valueBytes[2]/16*10 + valueBytes[2] % 16; + Event_Time.month = valueBytes[3]/16*10 + valueBytes[3] % 16; + Event_Time.day = valueBytes[4]/16*10 + valueBytes[4] % 16; + Event_Time.dotw = valueBytes[5]/16*10 + valueBytes[5] % 16; + // valueBytes[6] == 0xAA; // check + Event_Time.hour = valueBytes[7]/16*10 + valueBytes[7] % 16; + Event_Time.minute = valueBytes[8]/16*10 + valueBytes[8] % 16; + Event_Time.second = valueBytes[9]/16*10 + valueBytes[9] % 16; + Repetition_event Repetition = (Repetition_event)valueBytes[12]; // cyclical indicators + if(valueBytes[11]){ // Whether to control all relays 1:Control all relays 0:Control a relay + uint8_t CHxs = valueBytes[10]; // relay control + TimerEvent_CHxs_Set(Event_Time, CHxs, Repetition); + } + else{ + uint8_t CHx = valueBytes[10]/16; + bool State = (valueBytes[10] % 16); + TimerEvent_CHx_Set(Event_Time,CHx, State, Repetition); + } + } +} +void Bluetooth_SendData(char* Data) { // Send data using Bluetooth + if (Data != nullptr && strlen(Data) > 0) { + if (pServer->getConnectedCount() > 0) { + String SendValue = String(Data); // Convert char* to String + pTxCharacteristic->setValue(SendValue.c_str()); // Set SendValue to the eigenvalue (String type) + pTxCharacteristic->notify(); // Sends a notification to all connected devices + } + } +} +void Bluetooth_Init() +{ + /************************************************************************* + Bluetooth + *************************************************************************/ + BLEDevice::init("ESP32-S3-POE-ETH-8DI-8RO"); // Initialize Bluetooth and start broadcasting + pServer = BLEDevice::createServer(); + pServer->setCallbacks(new MyServerCallbacks()); + BLEService* pService = pServer->createService(SERVICE_UUID); + pTxCharacteristic = pService->createCharacteristic( + TX_CHARACTERISTIC_UUID, + BLECharacteristic:: PROPERTY_READ); // The eigenvalues are readable and can be read by remote devices + pRxCharacteristic = pService->createCharacteristic( + RX_CHARACTERISTIC_UUID, + BLECharacteristic::PROPERTY_WRITE); // The eigenvalues are writable and can be written to by remote devices + pRxCharacteristic->setCallbacks(new MyRXCallback()); + + pRxCharacteristic->setValue("Successfully Connect To ESP32-S3-POE-ETH-8DI-8RO"); + pService->start(); + + BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); + pAdvertising->addServiceUUID(SERVICE_UUID); + pAdvertising->setScanResponse(true); + pAdvertising->setMinPreferred(0x06); + pAdvertising->setMinPreferred(0x12); + BLEDevice::startAdvertising(); + pRxCharacteristic->notify(); + pAdvertising->start(); + RGB_Open_Time(0, 0, 60,1000, 0); + printf("Now you can read it in your phone!\r\n"); + xTaskCreatePinnedToCore( + BLETask, + "BLETask", + 4096, + NULL, + 2, + NULL, + 0 + ); +} + +void BLETask(void *parameter) { + while(1){ + Bluetooth_SendData(ipStr); + vTaskDelay(pdMS_TO_TICKS(100)); + } + vTaskDelete(NULL); +} \ No newline at end of file diff --git a/src/WS_Bluetooth.h b/src/WS_Bluetooth.h new file mode 100644 index 0000000..7ee6bf2 --- /dev/null +++ b/src/WS_Bluetooth.h @@ -0,0 +1,24 @@ +#pragma once + +#include // Reference the ESP32 built-in serial port library +#include +#include +#include +#include "WS_GPIO.h" +#include "WS_Serial.h" +#include "WS_Information.h" +#include "WS_Relay.h" +#include "WS_MQTT.h" +#include "WS_RTC.h" + +#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" // UUID of the server +#define RX_CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" // UUID of the characteristic Tx +#define TX_CHARACTERISTIC_UUID "beb5484a-36e1-4688-b7f5-ea07361b26a8" // UUID of the characteristic Rx + +#define Bluetooth_Mode 2 + + +void Bluetooth_SendData(char * Data); +void Bluetooth_Init(); +void BLETask(void *parameter); +void BLE_Set_RTC_Event(uint8_t* valueBytes); \ No newline at end of file diff --git a/src/WS_CAN.cpp b/src/WS_CAN.cpp new file mode 100644 index 0000000..82ab9ea --- /dev/null +++ b/src/WS_CAN.cpp @@ -0,0 +1,219 @@ +#include "WS_CAN.h" + +static bool driver_installed = false; + +void CAN_Init(void) +{ // Initializing serial port + // Initialize configuration structures using macro initializers + twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT((gpio_num_t)TXD1, (gpio_num_t)RXD1, TWAI_MODE_NORMAL); + twai_timing_config_t t_config = TWAI_TIMING_CONFIG_250KBITS(); //Look in the api-reference for other speed sets. + twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL(); + + // Install TWAI driver + if (twai_driver_install(&g_config, &t_config, &f_config) == ESP_OK) { + printf("Driver installed\r\n"); + } else { + printf("Failed to install driver\r\n"); + return; + } + + // Start TWAI driver + if (twai_start() == ESP_OK) { + printf("Driver started\r\n"); + } else { + printf("Failed to start driver\r\n"); + return; + } + + // Reconfigure alerts to detect TX alerts and Bus-Off errors + uint32_t alerts_to_enable = TWAI_ALERT_RX_DATA | TWAI_ALERT_ERR_PASS | TWAI_ALERT_BUS_ERROR | TWAI_ALERT_RX_QUEUE_FULL | TWAI_ALERT_TX_IDLE | TWAI_ALERT_TX_SUCCESS | TWAI_ALERT_TX_FAILED; + if (twai_reconfigure_alerts(alerts_to_enable, NULL) == ESP_OK) { + printf("CAN Alerts reconfigured\r\n"); + } else { + printf("Failed to reconfigure alerts\r\n"); + return; + } + + // TWAI driver is now successfully installed and started + driver_installed = true; + + xTaskCreatePinnedToCore( + CANTask, + "CANTask", + 4096, + NULL, + 3, + NULL, + 0 + ); +} + +static void send_message_Test(void) { + // Send message + // Configure message to transmit + twai_message_t message; + message.identifier = 0x0F6; + message.data_length_code = 4; + for (int i = 0; i < 4; i++) { + message.data[i] = i; + } + + // Queue message for transmission + if (twai_transmit(&message, pdMS_TO_TICKS(1000)) == ESP_OK) { + printf("Message queued for transmission\n"); + } else { + printf("Failed to queue message for transmission\n"); + } +} +// Standard frames ID: 0x000 to 0x7FF +// Extended frames ID: 0x00000000 to 0x1FFFFFFF +// Frame_type : 1:Extended frames 0:Standard frames +void send_message(uint32_t CAN_ID, uint8_t* Data, uint8_t Data_length, bool Frame_type) { + // Send message + // Configure message to transmit + twai_message_t message; + message.identifier = CAN_ID; + message.rtr = 0; // Disable remote frame + if(CAN_ID > 0x7FF){ + if(!Frame_type) + printf("The frame type is set incorrectly and data will eventually be sent as an extended frame!!!!\r\n"); + message.extd = 1; + } + else + message.extd = Frame_type; + if(Data_length > 8){ + uint16_t Frame_count = (Data_length / 8); + for (int i = 0; i < Frame_count; i++) { + message.data_length_code = 8; + for (int j = 0; j < 8; j++) { + message.data[j] = Data[j + (i * 8)]; + } + // Queue message for transmission + if (twai_transmit(&message, pdMS_TO_TICKS(1000)) == ESP_OK) { + printf("Message queued for transmission\n"); + } else { + printf("Failed to queue message for transmission\n"); + } + } + if(Data_length % 8){ + uint8_t Data_length_Now = Data_length % 8; + message.data_length_code = Data_length_Now; + for (int k = 0; k < Data_length_Now; k++) { + message.data[k] = Data[k + (Data_length - Data_length_Now)]; + } + // Queue message for transmission + if (twai_transmit(&message, pdMS_TO_TICKS(1000)) == ESP_OK) { + printf("Message queued for transmission\n"); + } else { + printf("Failed to queue message for transmission\n"); + } + } + } + else{ + message.data_length_code = Data_length; + for (int i = 0; i < Data_length; i++) { + message.data[i] = Data[i]; + } + // Queue message for transmission + if (twai_transmit(&message, pdMS_TO_TICKS(1000)) == ESP_OK) { + printf("Message queued for transmission\n"); + } else { + printf("Failed to queue message for transmission\n"); + } + } +} + + + +static void handle_rx_message(twai_message_t &message) { + // Process received message + if (message.extd) { + printf("Message is in Extended Format\r\n"); + } else { + printf("Message is in Standard Format\r\n"); + } + printf("ID: %lx\nByte:", message.identifier); + if (!(message.rtr)) { + if (message.data_length_code > 0) { + printf(" Data: "); + for (int i = 0; i < message.data_length_code; i++) { + printf("%02x ", message.data[i]); + } + printf("\r\n"); + // printf("Send back the received data!\r\n"); + // send_message(message.identifier, message.data, message.data_length_code, message.extd); + } else { + printf(" No data available\r\n"); + } + } else { + printf("This is a Remote Transmission Request (RTR) frame.\r\n"); + } +} + +unsigned long previousMillis = 0; // will store last time a message was send +#if Communication_failure_Enable + static unsigned long previous_bus_error_time = 0; // To store the last time a BUS_ERROR was printed +#endif +void CAN_Loop(void) +{ + if(driver_installed){ + // Check if an alert happened + uint32_t alerts_triggered; + twai_read_alerts(&alerts_triggered, pdMS_TO_TICKS(POLLING_RATE_MS)); + twai_status_info_t twaistatus; + twai_get_status_info(&twaistatus); + + // Handle alerts + if (alerts_triggered & TWAI_ALERT_ERR_PASS) { + printf("Alert: TWAI controller has become error passive.\r\n"); + } + if (alerts_triggered & TWAI_ALERT_BUS_ERROR) { + // printf("Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.\r\n"); + // printf("Bus error count: %ld\n", twaistatus.bus_error_count); + #if Communication_failure_Enable + unsigned long currentMillis = millis(); + // Only print the message if more than 2 seconds have passed since the last time it was printed + if (currentMillis - previous_bus_error_time >= BUS_ERROR_INTERVAL_MS) { + printf("Note if there are other devices on the CAN bus (other devices must be present) and that the rate of the device is the same as set in this program\r\n"); + previous_bus_error_time = currentMillis; // Update the last print time + } + #endif + } + if (alerts_triggered & TWAI_ALERT_RX_QUEUE_FULL) { + printf("Alert: The RX queue is full causing a received frame to be lost.\r\n"); + printf("RX buffered: %ld\t", twaistatus.msgs_to_rx); + printf("RX missed: %ld\t", twaistatus.rx_missed_count); + printf("RX overrun %ld\n", twaistatus.rx_overrun_count); + } + if (alerts_triggered & TWAI_ALERT_TX_FAILED) { + printf("Alert: The Transmission failed.\r\n"); + printf("TX buffered: %ld\t", twaistatus.msgs_to_tx); + printf("TX error: %ld\t", twaistatus.tx_error_counter); + printf("TX failed: %ld\n", twaistatus.tx_failed_count); + } + if (alerts_triggered & TWAI_ALERT_TX_SUCCESS) { + printf("Alert: The Transmission was successful.\r\n"); + printf("TX buffered: %ld\t \r\n", twaistatus.msgs_to_tx); + } + + // Receive messages if any are available + if (alerts_triggered & TWAI_ALERT_RX_DATA) { + // One or more messages received. Handle all. + twai_message_t message; // This is the structure used to store the received CAN message. + while (twai_receive(&message, 0) == ESP_OK) { + handle_rx_message(message); // This function will process the received message. + } + } + } +} + +void CANTask(void *parameter) { + // send_message_Test(); + // uint8_t Data[27]={0x80, 0x2A, 0xC3, 0x58, 0x17, 0x11, 0x4D, 0x3F, 0x3B, 0xCE, 0x0F, 0xFF, 0x79, 0x20, 0xB4, 0x40, 0x5D, 0x29, 0x05, 0x49, 0xE6, 0x12, 0x57, 0x0E, 0x6D, 0xC9, 0xAE}; + // send_message(0x079,Data,27); + while(1){ + CAN_Loop(); + vTaskDelay(pdMS_TO_TICKS(50)); + } + vTaskDelete(NULL); +} \ No newline at end of file diff --git a/src/WS_CAN.h b/src/WS_CAN.h new file mode 100644 index 0000000..5e3b84f --- /dev/null +++ b/src/WS_CAN.h @@ -0,0 +1,22 @@ +#pragma once + +#include "driver/twai.h" +#include "WS_GPIO.h" + +// Interval: +#define TRANSMIT_RATE_MS 1000 +// Interval: +#define POLLING_RATE_MS 1000 + +#define Communication_failure_Enable 0 // If the CAN bus is faulty for a long time, determine whether to forcibly exit + +#if Communication_failure_Enable + #define BUS_ERROR_INTERVAL_MS 5000 // Send a message every 2 seconds (2000 ms) +#endif + + +void CAN_Init(void); +void CAN_Loop(void); +void CANTask(void *parameter); + +void send_message(uint32_t CAN_ID, uint8_t* Data, uint8_t Data_length); \ No newline at end of file diff --git a/src/WS_DIN.cpp b/src/WS_DIN.cpp new file mode 100644 index 0000000..00f3799 --- /dev/null +++ b/src/WS_DIN.cpp @@ -0,0 +1,151 @@ +#include "WS_DIN.h" + +bool DIN_Flag[8] = {0}; // DIN current status flag +uint8_t DIN_Data = 0; +bool Relay_Immediate_Enable = Relay_Immediate_Default; + +bool DIN_Read_CH1(void){ + DIN_Flag[0] = digitalRead(DIN_PIN_CH1); + if(DIN_Flag[0]){ + DIN_Data |= (1 << 0); + return 1; + } + else{ + DIN_Data &= (~(1 << 0)); + return 0; + } +} +bool DIN_Read_CH2(void){ + DIN_Flag[1] = digitalRead(DIN_PIN_CH2); + if(DIN_Flag[1]){ + DIN_Data |= (1 << 1); + return 1; + } + else{ + DIN_Data &= (~(1 << 1)); + return 0; + } +} +bool DIN_Read_CH3(void){ + DIN_Flag[2] = digitalRead(DIN_PIN_CH3); + if(DIN_Flag[2]){ + DIN_Data |= (1 << 2); + return 1; + } + else{ + DIN_Data &= (~(1 << 2)); + return 0; + } +} +bool DIN_Read_CH4(void){ + DIN_Flag[3] = digitalRead(DIN_PIN_CH4); + if(DIN_Flag[3]){ + DIN_Data |= (1 << 3); + return 1; + } + else{ + DIN_Data &= (~(1 << 3)); + return 0; + } +} +bool DIN_Read_CH5(void){ + DIN_Flag[4] = digitalRead(DIN_PIN_CH5); + if(DIN_Flag[4]){ + DIN_Data |= (1 << 4); + return 1; + } + else{ + DIN_Data &= (~(1 << 4)); + return 0; + } +} +bool DIN_Read_CH6(void){ + DIN_Flag[5] = digitalRead(DIN_PIN_CH6); + if(DIN_Flag[5]){ + DIN_Data |= (1 << 5); + return 1; + } + else{ + DIN_Data &= (~(1 << 5)); + return 0; + } +} +bool DIN_Read_CH7(void){ + DIN_Flag[6] = digitalRead(DIN_PIN_CH7); + if(DIN_Flag[6]){ + DIN_Data |= (1 << 6); + return 1; + } + else{ + DIN_Data &= (~(1 << 6)); + return 0; + } +} +bool DIN_Read_CH8(void){ + DIN_Flag[7] = digitalRead(DIN_PIN_CH8); + if(DIN_Flag[7]){ + DIN_Data |= (1 << 7); + return 1; + } + else{ + DIN_Data &= (~(1 << 7)); + return 0; + } +} +uint8_t DIN_Read_CHxs(){ + DIN_Read_CH1(); + DIN_Read_CH2(); + DIN_Read_CH3(); + DIN_Read_CH4(); + DIN_Read_CH5(); + DIN_Read_CH6(); + DIN_Read_CH7(); + DIN_Read_CH8(); + return DIN_Data; +} + +static uint8_t DIN_Data_Old = 0; +void DINTask(void *parameter) { + while(1){ + if(Relay_Immediate_Enable){ + DIN_Read_CHxs(); + if(DIN_Data_Old != DIN_Data){ + if(DIN_Inverse_Enable) + Relay_Immediate_CHxs(~DIN_Data , DIN_Mode); + else + Relay_Immediate_CHxs(DIN_Data , DIN_Mode); + DIN_Data_Old = DIN_Data; + } + } + vTaskDelay(pdMS_TO_TICKS(20)); + } + vTaskDelete(NULL); +} + +void DIN_Init(void) +{ + pinMode(DIN_PIN_CH1, INPUT_PULLUP); + pinMode(DIN_PIN_CH2, INPUT_PULLUP); + pinMode(DIN_PIN_CH3, INPUT_PULLUP); + pinMode(DIN_PIN_CH4, INPUT_PULLUP); + pinMode(DIN_PIN_CH5, INPUT_PULLUP); + pinMode(DIN_PIN_CH6, INPUT_PULLUP); + pinMode(DIN_PIN_CH7, INPUT_PULLUP); + pinMode(DIN_PIN_CH8, INPUT_PULLUP); + + DIN_Read_CHxs(); + if(DIN_Inverse_Enable) + DIN_Data_Old = 0xFF; + else + DIN_Data_Old = 0x00; + + xTaskCreatePinnedToCore( + DINTask, + "DINTask", + 4096, + NULL, + 4, + NULL, + 0 + ); +} diff --git a/src/WS_DIN.h b/src/WS_DIN.h new file mode 100644 index 0000000..13180a6 --- /dev/null +++ b/src/WS_DIN.h @@ -0,0 +1,18 @@ +#pragma once + +#include "WS_GPIO.h" +#include "WS_Relay.h" +/************************************************************* I/O *************************************************************/ +#define DIN_PIN_CH1 4 // DIN CH1 GPIO +#define DIN_PIN_CH2 5 // DIN CH2 GPIO +#define DIN_PIN_CH3 6 // DIN CH3 GPIO +#define DIN_PIN_CH4 7 // DIN CH4 GPIO +#define DIN_PIN_CH5 8 // DIN CH5 GPIO +#define DIN_PIN_CH6 9 // DIN CH6 GPIO +#define DIN_PIN_CH7 10 // DIN CH7 GPIO +#define DIN_PIN_CH8 11 // DIN CH8 GPIO + +#define Relay_Immediate_Default 1 // Enable the input control relay +#define DIN_Inverse_Enable 1 // Input is reversed from control + +void DIN_Init(void); diff --git a/src/WS_ETH.cpp b/src/WS_ETH.cpp new file mode 100644 index 0000000..ce31fb4 --- /dev/null +++ b/src/WS_ETH.cpp @@ -0,0 +1,120 @@ +#include "WS_ETH.h" + +#include +#include + +static bool eth_connected = false; +static bool eth_connected_Old = false; +IPAddress ETH_ip; +// NTP setup +WiFiUDP udp; +NTPClient timeClient(udp, "pool.ntp.org", timezone*3600, 60000); // NTP server, time offset in seconds, update interval + +void onEvent(arduino_event_id_t event, arduino_event_info_t info) { + switch (event) { + case ARDUINO_EVENT_ETH_START: + printf("ETH Started\r\n"); + //set eth hostname here + ETH.setHostname("esp32-eth0"); + break; + case ARDUINO_EVENT_ETH_CONNECTED: printf("ETH Connected\r\n"); break; + case ARDUINO_EVENT_ETH_GOT_IP: printf("ETH Got IP: '%s'\n", esp_netif_get_desc(info.got_ip.esp_netif)); //printf("%s\r\n",ETH); + ETH_ip = ETH.localIP(); + printf("ETH Got IP: %d.%d.%d.%d\n", ETH_ip[0], ETH_ip[1], ETH_ip[2], ETH_ip[3]); +#if USE_TWO_ETH_PORTS + // printf("%d\r\n",ETH1); +#endif + eth_connected = true; + break; + case ARDUINO_EVENT_ETH_LOST_IP: + printf("ETH Lost IP\r\n"); + eth_connected = false; + break; + case ARDUINO_EVENT_ETH_DISCONNECTED: + printf("ETH Disconnected\r\n"); + eth_connected = false; + break; + case ARDUINO_EVENT_ETH_STOP: + printf("ETH Stopped\r\n"); + eth_connected = false; + break; + default: break; + } +} + +void testClient(const char *host, uint16_t port) { + printf("\nconnecting to \r\n");; + printf("%s\r\n",host); + + NetworkClient client; + if (!client.connect(host, port)) { + printf("connection failed\r\n"); + return; + } + client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host); + while (client.connected() && !client.available()); + while (client.available()) { + printf("%c",(char)client.read()); + } + + printf("closing connection\n"); + client.stop(); +} + +void ETH_Init(void) { + printf("Ethernet Start\r\n"); + Network.onEvent(onEvent); + + SPI.begin(ETH_SPI_SCK, ETH_SPI_MISO, ETH_SPI_MOSI); + ETH.begin(ETH_PHY_TYPE, ETH_PHY_ADDR, ETH_PHY_CS, ETH_PHY_IRQ, ETH_PHY_RST, SPI); +#if USE_TWO_ETH_PORTS + ETH1.begin(ETH1_PHY_TYPE, ETH1_PHY_ADDR, ETH1_PHY_CS, ETH1_PHY_IRQ, ETH1_PHY_RST, SPI); +#endif + xTaskCreatePinnedToCore( + EthernetTask, + "EthernetTask", + 4096, + NULL, + 2, + NULL, + 0 + ); +} +void EthernetTask(void *parameter) { + while(1){ + if (eth_connected && !eth_connected_Old) { + eth_connected_Old = eth_connected; + RGB_Open_Time(0, 60, 0,1000, 0); + printf("Network port connected!\r\n"); + Acquisition_time(); + } + else if(!eth_connected && eth_connected_Old){ + eth_connected_Old = eth_connected; + printf("Network port disconnected!\r\n"); + } + vTaskDelay(pdMS_TO_TICKS(100)); + } + vTaskDelete(NULL); +} +void Acquisition_time(void) { // Get the network time and set to DS3231 to be called after the WIFI connection is successful + timeClient.begin(); + timeClient.update(); + + time_t currentTime = timeClient.getEpochTime(); + while(currentTime < 1609459200) // Using the current timestamp to compare with a known larger value,1609459200 is a known larger timestamp value that corresponds to January 1, 2021 + { + timeClient.update(); + currentTime = timeClient.getEpochTime(); + printf("ETH - Online clock error!!!\r\n"); + } + struct tm *localTime = localtime(¤tTime); + static datetime_t PCF85063_Time = {0}; + PCF85063_Time.year = localTime->tm_year + 1900; + PCF85063_Time.month = localTime->tm_mon + 1; + PCF85063_Time.day = localTime->tm_mday; + PCF85063_Time.dotw = localTime->tm_wday; + PCF85063_Time.hour = localTime->tm_hour; + PCF85063_Time.minute = localTime->tm_min; + PCF85063_Time.second = localTime->tm_sec; + PCF85063_Set_All(PCF85063_Time); +} diff --git a/src/WS_ETH.h b/src/WS_ETH.h new file mode 100644 index 0000000..e5976ba --- /dev/null +++ b/src/WS_ETH.h @@ -0,0 +1,44 @@ +#pragma once +#include +#include +#include + +#include "WS_PCF85063.h" +#include "WS_GPIO.h" +#include "WS_RTC.h" + +// Set this to 1 to enable dual Ethernet support +#define USE_TWO_ETH_PORTS 0 + +#ifndef ETH_PHY_TYPE + #define ETH_PHY_TYPE ETH_PHY_W5500 + #define ETH_PHY_ADDR 1 + #define ETH_PHY_CS 16 + #define ETH_PHY_IRQ 12 + #define ETH_PHY_RST 39 +#endif + +// SPI pins +#define ETH_SPI_SCK 15 +#define ETH_SPI_MISO 14 +#define ETH_SPI_MOSI 13 + +#if USE_TWO_ETH_PORTS + // Second port on shared SPI bus + #ifndef ETH1_PHY_TYPE + #define ETH1_PHY_TYPE ETH_PHY_W5500 + #define ETH1_PHY_ADDR 1 + #define ETH1_PHY_CS 32 + #define ETH1_PHY_IRQ 33 + #define ETH1_PHY_RST 18 + #endif + ETHClass ETH1(1); +#endif + +#define timezone 8 // china + +void ETH_Init(void); +void ETH_Loop(void); +void EthernetTask(void *parameter); + +void Acquisition_time(void); \ No newline at end of file diff --git a/src/WS_GPIO.cpp b/src/WS_GPIO.cpp new file mode 100644 index 0000000..7ba397d --- /dev/null +++ b/src/WS_GPIO.cpp @@ -0,0 +1,166 @@ +#include "WS_GPIO.h" + +/************************************************************* I/O Init *************************************************************/ +void GPIO_Init() { + pinMode(GPIO_PIN_RGB, OUTPUT); // Initialize the control GPIO of RGB + pinMode(GPIO_PIN_Buzzer, OUTPUT); // Initialize the control GPIO of Buzzer + + // TODO: Re enable this + //ledcAttach(GPIO_PIN_Buzzer, Frequency, Resolution); + Set_Dutyfactor(0); //0~100 + + xTaskCreatePinnedToCore( + RGBTask, + "RelayFailTask", + 4096, + NULL, + 2, + NULL, + 0 + ); + xTaskCreatePinnedToCore( + BuzzerTask, + "RelayFailTask", + 4096, + NULL, + 2, + NULL, + 0 + ); +} + +/************************************************************* RGB *************************************************************/ +void RGB_Light(uint8_t red_val, uint8_t green_val, uint8_t blue_val) { + neopixelWrite(GPIO_PIN_RGB, green_val, red_val, blue_val); // RGB color adjustment +} +RGB_Indicate RGB_indicate[RGB_Indicate_Number]; +static uint8_t RGB_indicate_Num = 0; +void RGB_Open_Time(uint8_t red_val, uint8_t green_val, uint8_t blue_val, uint16_t Time, uint16_t flicker_time) { + + if(RGB_indicate_Num + 1 >= RGB_Indicate_Number) + { + printf("Note : The RGB indicates that the cache is full and has been ignored\r\n"); + } + else{ + RGB_indicate[RGB_indicate_Num].Red = red_val; + RGB_indicate[RGB_indicate_Num].Green = green_val; + RGB_indicate[RGB_indicate_Num].Blue = blue_val; + RGB_indicate[RGB_indicate_Num].RGB_Time = Time; + if(flicker_time<51) + flicker_time = 0; // If the blinking interval is less than 50ms, the blinking is ignored + RGB_indicate[RGB_indicate_Num].RGB_Flicker = flicker_time; + RGB_indicate_Num ++; + } +} +void RGBTask(void *parameter) { + bool RGB_Flag = 0; + while(1){ + if(RGB_indicate[0].RGB_Time) + { + RGB_Flag = 1; + RGB_Light(RGB_indicate[0].Red, RGB_indicate[0].Green, RGB_indicate[0].Blue); + if(RGB_indicate[0].RGB_Flicker){ + vTaskDelay(pdMS_TO_TICKS(RGB_indicate[0].RGB_Flicker)); + RGB_Light(0, 0, 0); + vTaskDelay(pdMS_TO_TICKS(RGB_indicate[0].RGB_Flicker)); + } + if(RGB_indicate[0].RGB_Time > (RGB_indicate[0].RGB_Flicker * 2 +50)) + RGB_indicate[0].RGB_Time = RGB_indicate[0].RGB_Time -(RGB_indicate[0].RGB_Flicker * 2 +50); + else + RGB_indicate[0].RGB_Time = 0; + } + else if(RGB_Flag && !RGB_indicate[0].RGB_Time){ + RGB_Light(0, 0, 0); + RGB_Flag = 0; + RGB_indicate[0].Red = 0; + RGB_indicate[0].Green = 0; + RGB_indicate[0].Blue = 0; + RGB_indicate[0].RGB_Time = 0; + RGB_indicate[0].RGB_Flicker = 0; + if(RGB_indicate_Num > 0){ + for (int i = 1; i < RGB_Indicate_Number; i++) { + RGB_indicate[i-1] = RGB_indicate[i]; + } + RGB_indicate[RGB_Indicate_Number -1].Red = 0; + RGB_indicate[RGB_Indicate_Number -1].Green = 0; + RGB_indicate[RGB_Indicate_Number -1].Blue = 0; + RGB_indicate[RGB_Indicate_Number -1].RGB_Time = 0; + RGB_indicate[RGB_Indicate_Number -1].RGB_Flicker = 0; + RGB_indicate_Num --; + vTaskDelay(pdMS_TO_TICKS(RGB_Indicating_interval)); + } + } + vTaskDelay(pdMS_TO_TICKS(50)); + } + vTaskDelete(NULL); +} + + +/************************************************************* Buzzer *************************************************************/ +void Set_Dutyfactor(uint16_t dutyfactor) +{ + if(dutyfactor > Dutyfactor_MAX || dutyfactor < 0) + printf("Set Backlight parameters in the range of 0 to %d \r\n",Dutyfactor_MAX); + else{ + ledcWrite(GPIO_PIN_Buzzer, dutyfactor); + } +} +void Buzzer_Open(void) +{ + Set_Dutyfactor(Dutyfactor); +} +void Buzzer_Closs(void) +{ + Set_Dutyfactor(0); +} +Buzzer_Indicate Buzzer_indicate[Buzzer_Indicate_Number]; +static uint8_t Buzzer_indicate_Num = 0; +void Buzzer_Open_Time(uint16_t Time, uint16_t flicker_time) +{ + if(Buzzer_indicate_Num + 1 >= Buzzer_Indicate_Number) + { + printf("Note : The buzzer indicates that the cache is full and has been ignored\r\n"); + } + else{ + Buzzer_indicate[Buzzer_indicate_Num].Buzzer_Time = Time; + if(flicker_time<51) + flicker_time = 0; // If the blinking interval is less than 50ms, the blinking is ignored + Buzzer_indicate[Buzzer_indicate_Num].Buzzer_Flicker = flicker_time; + Buzzer_indicate_Num ++; + } +} +void BuzzerTask(void *parameter) { + bool Buzzer_Flag = 0; + while(1){ + if(Buzzer_indicate[0].Buzzer_Time) + { + Buzzer_Flag = 1; + Buzzer_Open(); + if(Buzzer_indicate[0].Buzzer_Flicker){ + vTaskDelay(pdMS_TO_TICKS(Buzzer_indicate[0].Buzzer_Flicker)); + Buzzer_Closs(); + vTaskDelay(pdMS_TO_TICKS(Buzzer_indicate[0].Buzzer_Flicker)); + } + if(Buzzer_indicate[0].Buzzer_Time > (Buzzer_indicate[0].Buzzer_Flicker * 2 +50)) + Buzzer_indicate[0].Buzzer_Time = Buzzer_indicate[0].Buzzer_Time -(Buzzer_indicate[0].Buzzer_Flicker * 2 +50); + else + Buzzer_indicate[0].Buzzer_Time = 0; + } + else if(Buzzer_Flag && !Buzzer_indicate[0].Buzzer_Time){ + Buzzer_Closs(); + Buzzer_Flag = 0; + Buzzer_indicate[0].Buzzer_Time = 0; + Buzzer_indicate[0].Buzzer_Flicker = 0; + if(Buzzer_indicate_Num > 0){ + for (int i = 1; i < Buzzer_indicate_Num; i++) { + Buzzer_indicate[i-1] = Buzzer_indicate[i]; + } + Buzzer_indicate[Buzzer_indicate_Num - 1].Buzzer_Time = 0; + Buzzer_indicate[Buzzer_indicate_Num - 1].Buzzer_Flicker = 0; + Buzzer_indicate_Num --; + } + } + vTaskDelay(pdMS_TO_TICKS(50)); + } + vTaskDelete(NULL); +} \ No newline at end of file diff --git a/src/WS_GPIO.h b/src/WS_GPIO.h new file mode 100644 index 0000000..8f517d4 --- /dev/null +++ b/src/WS_GPIO.h @@ -0,0 +1,44 @@ +#pragma once +#include +#include // Reference the ESP32 built-in serial port library + +/************************************************************* I/O *************************************************************/ +#define TXD1 17 //The TXD of UART1 corresponds to GPIO RS485/CAN +#define RXD1 18 //The RXD of UART1 corresponds to GPIO RS485/CAN +#define GPIO_PIN_RGB 38 // RGB Control GPIO + +/*********************************************************** Buzzer ***********************************************************/ +#define GPIO_PIN_Buzzer 46 // Buzzer Control GPIO +#define PWM_Channel 1 // PWM Channel +#define Frequency 1000 // PWM frequencyconst +#define Resolution 8 // PWM resolution ratio +#define Dutyfactor 200 // PWM Dutyfactor +#define Dutyfactor_MAX 255 + + +#define RGB_Indicate_Number 10 // Number of saved RGB indicator signals +#define RGB_Indicating_interval 500 // Time interval of each indication signal(unit: ms) +typedef struct { + uint8_t Red = 0; + uint8_t Green = 0; + uint8_t Blue = 0; + uint16_t RGB_Time = 0; // RGB lighting duration + uint16_t RGB_Flicker = 0; // RGB flicker interval +} RGB_Indicate; + +#define Buzzer_Indicate_Number 10 // Number of saved RGB indicator signals +typedef struct { + uint16_t Buzzer_Time = 0; // Buzzer duration + uint16_t Buzzer_Flicker = 0; // Buzzer interval duration +} Buzzer_Indicate; +/************************************************************* I/O *************************************************************/ +void GPIO_Init(); +void RGB_Light(uint8_t red_val, uint8_t green_val, uint8_t blue_val); +void RGB_Open_Time(uint8_t red_val, uint8_t green_val, uint8_t blue_val, uint16_t Time, uint16_t flicker_time); +void RGBTask(void *parameter); + +void Set_Dutyfactor(uint16_t dutyfactor); +void Buzzer_Open(void); +void Buzzer_Closs(void); +void Buzzer_Open_Time(uint16_t Time, uint16_t flicker_time); +void BuzzerTask(void *parameter); diff --git a/src/WS_Information.h b/src/WS_Information.h new file mode 100644 index 0000000..ebfbe7d --- /dev/null +++ b/src/WS_Information.h @@ -0,0 +1,18 @@ +#pragma once + +#define Extension_Enable 1 // Whether to extend the connection to external devices 1:Expansion device Modbus RTU Relay 0:No extend +#define RS485_CAN_Enable 1 // This item is configured according to product selection 1:Select RS485 0:Select CAN +#define RTC_Event_Enable 1 // Whether to enable RTC events (Bluetooth) 1:Enable 0:Disable + + + +// Name and password of the WiFi access point +#define STASSID "JSBPI" +#define STAPSK "waveshare0755" + +// Details about devices on the Waveshare cloud +#define MQTT_Server "mqtt.waveshare.cloud" +#define MQTT_Port 1883 +#define MQTT_ID "fc2d8db5" +#define MQTT_Pub "Pub/59/54/fc2d8db5" +#define MQTT_Sub "Sub/59/54/fc2d8db5" diff --git a/src/WS_MQTT.cpp b/src/WS_MQTT.cpp new file mode 100644 index 0000000..b0baf17 --- /dev/null +++ b/src/WS_MQTT.cpp @@ -0,0 +1,248 @@ +#include "WS_MQTT.h" + +// The name and password of the WiFi access point +const char* ssid = STASSID; +const char* password = STAPSK; +// Details about devices on the Waveshare cloud +const char* mqtt_server = MQTT_Server; +int PORT = MQTT_Port; +const char* ID = MQTT_ID; // Defining device ID +char pub[] = MQTT_Pub; // MQTT release topic +char sub[] = MQTT_Sub; // MQTT subscribe to topics + + +WiFiClient espClient; //MQTT initializes the contents +PubSubClient client(espClient); + +StaticJsonDocument<400> sendJson; +StaticJsonDocument<400> readJson; +unsigned long lastUpdateTime = 0; +char msg[MSG_BUFFER_SIZE]; +bool WIFI_Connection = 0; +bool WIFI_Connection_Old = 0; +char ipStr[16]; + +const unsigned long updateInterval = 5000; + +void WIFI_Init(void) +{ + xTaskCreatePinnedToCore( + WifiStaTask, + "WifiStaTask", + 4096, + NULL, + 3, + NULL, + 0 + ); +} + + +void WifiStaTask(void *parameter) { + uint8_t Count = 0; + WiFi.mode(WIFI_STA); + WiFi.setSleep(true); + WiFi.begin(ssid, password); // Connect to the specified Wi-Fi network + while(1){ + if(WiFi.status() != WL_CONNECTED) + { + WIFI_Connection = 0; + printf(".\n"); + RGB_Open_Time(50, 0, 0, 500, 0); + Count++; + if(Count >= 10){ + Count = 0; + printf("\r\n"); + WiFi.disconnect(); + vTaskDelay(pdMS_TO_TICKS(100)); + WiFi.mode(WIFI_OFF); + vTaskDelay(pdMS_TO_TICKS(100)); + WiFi.mode(WIFI_STA); + vTaskDelay(pdMS_TO_TICKS(100)); + WiFi.begin(ssid, password); + } + } + else{ + WIFI_Connection = 1; + IPAddress myIP = WiFi.localIP(); + printf("IP Address: "); + sprintf(ipStr, "%d.%d.%d.%d", myIP[0], myIP[1], myIP[2], myIP[3]); + printf("%s\r\n", ipStr); + RGB_Open_Time(0, 50, 0, 1000, 0); + + printf("WIFI connection is successful, relay control can be performed via Waveshare cloud.\r\n"); + + while (WiFi.status() == WL_CONNECTED){ + vTaskDelay(pdMS_TO_TICKS(100)); + } + } + vTaskDelay(pdMS_TO_TICKS(1000)); + } + vTaskDelete(NULL); +} + +// MQTT subscribes to callback functions for processing received messages +void callback(char* topic, byte* payload, unsigned int length) { + uint8_t CH_Flag = 0; + String inputString; + for (int i = 0; i < length; i++) { + inputString += (char)payload[i]; + } + printf("%s\r\n",inputString.c_str()); // Format of data sent back by the server {"data":{"CH1":1}} + int dataBegin = inputString.indexOf("\"data\""); // Finds if "data" is present in the string (quotes also) + if (dataBegin == -1) { + printf("Missing 'data' field in JSON. - MQTT\r\n"); + return; + } + int CH_Begin = -1; + if (inputString.indexOf("\"CH1\"", dataBegin) != -1){ + CH_Flag = 1; + CH_Begin = inputString.indexOf("\"CH1\"", dataBegin); + } + else if (inputString.indexOf("\"CH2\"", dataBegin) != -1){ + CH_Flag = 2; + CH_Begin = inputString.indexOf("\"CH2\"", dataBegin); + } + else if (inputString.indexOf("\"CH3\"", dataBegin) != -1){ + CH_Flag = 3; + CH_Begin = inputString.indexOf("\"CH3\"", dataBegin); + } + else if (inputString.indexOf("\"CH4\"", dataBegin) != -1){ + CH_Flag = 4; + CH_Begin = inputString.indexOf("\"CH4\"", dataBegin); + } + else if (inputString.indexOf("\"CH5\"", dataBegin) != -1){ + CH_Flag = 5; + CH_Begin = inputString.indexOf("\"CH5\"", dataBegin); + } + else if (inputString.indexOf("\"CH6\"", dataBegin) != -1){ + CH_Flag = 6; + CH_Begin = inputString.indexOf("\"CH6\"", dataBegin); + } + else if (inputString.indexOf("\"CH7\"", dataBegin) != -1){ + CH_Flag = 7; + CH_Begin = inputString.indexOf("\"CH7\"", dataBegin); + } + else if (inputString.indexOf("\"CH8\"", dataBegin) != -1){ + CH_Flag = 8; + CH_Begin = inputString.indexOf("\"CH8\"", dataBegin); + } + else if (inputString.indexOf("\"ALL\"", dataBegin) != -1){ + CH_Flag = 9; + CH_Begin = inputString.indexOf("\"ALL\"", dataBegin); + } + else{ + printf("Note : Non-instruction data was received - MQTT!\r\n"); + CH_Flag = 0; + return; + } + int valueBegin = inputString.indexOf(':', CH_Begin); + int valueEnd = inputString.indexOf('}', valueBegin); + if (valueBegin != -1 && valueEnd != -1) { + if(CH_Flag != 0) + { + String ValueStr = inputString.substring(valueBegin + 1, valueEnd); + int Value = ValueStr.toInt(); + if(CH_Flag < 9){ + if(Value == 1 && Relay_Flag[CH_Flag - 1] == 0){ + uint8_t Data[1]={CH_Flag+48}; + Relay_Analysis(Data,MQTT_Mode); + } + else if(Value == 0 && Relay_Flag[CH_Flag - 1] == 1){ + uint8_t Data[1]={CH_Flag+48}; + Relay_Analysis(Data,MQTT_Mode); + } + } + else if(CH_Flag == 9){ + if(Value == 1 && ((Relay_Flag[0] & Relay_Flag[1] & Relay_Flag[2] & Relay_Flag[3] & Relay_Flag[4] & Relay_Flag[5] & Relay_Flag[6] & Relay_Flag[7]) == 0)){ + uint8_t Data[1]={9+48}; + Relay_Analysis(Data,MQTT_Mode); + } + else if(Value == 0 && ((Relay_Flag[0] | Relay_Flag[1] | Relay_Flag[2] | Relay_Flag[3] | Relay_Flag[4] | Relay_Flag[5] | Relay_Flag[6] | Relay_Flag[7] )== 1)){ + uint8_t Data[1]={0+48}; + Relay_Analysis(Data,MQTT_Mode); + } + } + } + } +} + + +// Reconnect to the MQTT server +void reconnect(void) { + uint8_t Count = 0; + while (!client.connected()) { + Count++; + if (client.connect(ID)) { + client.subscribe(sub); + printf("Waveshare Cloud connection is successful and now you can use all features.\r\n"); + } + else{ + delay(500); + if(Count % 2 == 0 && Count != 0){ + printf("%d\r\n", client.state()); + RGB_Open_Time(50, 0, 50, 1000, 0); + } + if(Count % 10 == 0){ // 10 attempts failed to connect, cancel the connection, try again + client.disconnect(); + delay(100); + client.setServer(mqtt_server, PORT); + delay(100); + client.setCallback(callback); + delay(100); + } + if(Count > 32){ // connection fail + Count = 0; + printf("warning: Waveshare cloud connection fails. Currently, only Bluetooth control is available !!!\r\n"); + } + + } + } +} +// Send data in JSON format to MQTT server +void sendJsonData(void) { + sendJson["ID"] = ID; + String pubres; + serializeJson(sendJson, pubres); + int str_len = pubres.length() + 1; + char char_array[str_len]; + pubres.toCharArray(char_array, str_len); + client.publish(pub, char_array); +} + +void MQTTTask(void *parameter) { + bool WIFI_Connection_Old; + while(1){ + if(WIFI_Connection == 1) + { + if(!WIFI_Connection_Old){ + WIFI_Connection_Old = 1; + client.setServer(mqtt_server, PORT); + client.setCallback(callback); + } + if (!client.connected()) { + reconnect(); + } + client.loop(); + } + else{ + WIFI_Connection_Old = 0; + } + vTaskDelay(pdMS_TO_TICKS(10)); + } + vTaskDelete(NULL); +} +void MQTT_Init(void) +{ + WIFI_Init(); + xTaskCreatePinnedToCore( + MQTTTask, + "MQTTTask", + 4096, + NULL, + 3, + NULL, + 0 + ); +} + diff --git a/src/WS_MQTT.h b/src/WS_MQTT.h new file mode 100644 index 0000000..49a27de --- /dev/null +++ b/src/WS_MQTT.h @@ -0,0 +1,25 @@ +#ifndef _WS_MQTT_H_ +#define _WS_MQTT_H_ + +#include +#include +#include +#include +#include +#include "WS_GPIO.h" +#include "WS_Information.h" +#include "WS_Relay.h" + + +#define MSG_BUFFER_SIZE (50) + +extern char ipStr[16]; + +void WIFI_Init(void); +void WifiStaTask(void *parameter); +void callback(char* topic, byte* payload, unsigned int length); // MQTT subscribes to callback functions for processing received messages +void reconnect(void); // Reconnect to the MQTT server +void sendJsonData(void); // Send data in JSON format to MQTT server +void MQTT_Init(void); + +#endif \ No newline at end of file diff --git a/src/WS_PCF85063.cpp b/src/WS_PCF85063.cpp new file mode 100644 index 0000000..3a48448 --- /dev/null +++ b/src/WS_PCF85063.cpp @@ -0,0 +1,189 @@ +#include "WS_PCF85063.h" + +datetime_t datetime= {0}; +datetime_t Update_datetime= {0}; +static uint8_t decToBcd(int val); +static int bcdToDec(uint8_t val); + + +void Time_printf(void *parameter) { + while(1){ + char datetime_str[50]; + datetime_to_str(datetime_str,datetime); + printf("Time:%s\r\n",datetime_str); + vTaskDelay(pdMS_TO_TICKS(500)); + } + vTaskDelete(NULL); +} +void PCF85063_Init(void) // PCF85063 initialized +{ + uint8_t Value = RTC_CTRL_1_DEFAULT|RTC_CTRL_1_CAP_SEL; + + I2C_Write(PCF85063_ADDRESS, RTC_CTRL_1_ADDR, &Value, 1); + I2C_Read(PCF85063_ADDRESS, RTC_CTRL_1_ADDR, &Value, 1); + if(Value & RTC_CTRL_1_STOP) + printf("PCF85063 failed to be initialized.state :%d\r\n",Value); + else + printf("PCF85063 is running,state :%d\r\n",Value); + + // + // Update_datetime.year = 2024; + // Update_datetime.month = 9; + // Update_datetime.day = 20; + // Update_datetime.dotw = 5; + // Update_datetime.hour = 9; + // Update_datetime.minute = 50; + // Update_datetime.second = 0; + // PCF85063_Set_All(Update_datetime); + xTaskCreatePinnedToCore( + PCF85063Task, + "PCF85063Task", + 4096, + NULL, + 3, + NULL, + 0 + ); + // xTaskCreatePinnedToCore( + // Time_printf, + // "Time_printf", + // 4096, + // NULL, + // 3, + // NULL, + // 0 + // ); +} + +void PCF85063Task(void *parameter) { + while(1){ + PCF85063_Read_Time(&datetime); + vTaskDelay(pdMS_TO_TICKS(100)); + } + vTaskDelete(NULL); +} + +void PCF85063_Reset() // Reset PCF85063 +{ + uint8_t Value = RTC_CTRL_1_DEFAULT|RTC_CTRL_1_CAP_SEL|RTC_CTRL_1_SR; + esp_err_t ret = I2C_Write(PCF85063_ADDRESS, RTC_CTRL_1_ADDR, &Value, 1); + if(ret != ESP_OK) + printf("PCF85063 : Reset failure\r\n"); +} +void PCF85063_Set_Time(datetime_t time) // Set Time +{ + uint8_t buf[3] = {decToBcd(time.second), + decToBcd(time.minute), + decToBcd(time.hour)}; + esp_err_t ret = I2C_Write(PCF85063_ADDRESS, RTC_SECOND_ADDR, buf, sizeof(buf)); + if(ret != ESP_OK) + printf("PCF85063 : Time setting failure\r\n"); +} +void PCF85063_Set_Date(datetime_t date) // Set Date +{ + uint8_t buf[4] = {decToBcd(date.day), + decToBcd(date.dotw), + decToBcd(date.month), + decToBcd(date.year - YEAR_OFFSET)}; + esp_err_t ret = I2C_Write(PCF85063_ADDRESS, RTC_DAY_ADDR, buf, sizeof(buf)); + if(ret != ESP_OK) + printf("PCF85063 : Date setting failed\r\n"); +} + +void PCF85063_Set_All(datetime_t time) // Set Time And Date +{ + uint8_t buf[7] = {decToBcd(time.second), + decToBcd(time.minute), + decToBcd(time.hour), + decToBcd(time.day), + decToBcd(time.dotw), + decToBcd(time.month), + decToBcd(time.year - YEAR_OFFSET)}; + esp_err_t ret = I2C_Write(PCF85063_ADDRESS, RTC_SECOND_ADDR, buf, sizeof(buf)); + if(ret != ESP_OK) + printf("PCF85063 : Failed to set the date and time\r\n"); +} + +void PCF85063_Read_Time(datetime_t *time) // Read Time And Date +{ + uint8_t buf[7] = {0}; + esp_err_t ret = I2C_Read(PCF85063_ADDRESS, RTC_SECOND_ADDR, buf, sizeof(buf)); + if(ret != ESP_OK) + printf("PCF85063 : Time read failure\r\n"); + else{ + time->second = bcdToDec(buf[0] & 0x7F); + time->minute = bcdToDec(buf[1] & 0x7F); + time->hour = bcdToDec(buf[2] & 0x3F); + time->day = bcdToDec(buf[3] & 0x3F); + time->dotw = bcdToDec(buf[4] & 0x07); + time->month = bcdToDec(buf[5] & 0x1F); + time->year = bcdToDec(buf[6]) + YEAR_OFFSET; + } +} + +void PCF85063_Enable_Alarm() // Enable Alarm and Clear Alarm flag +{ + uint8_t Value = RTC_CTRL_2_DEFAULT | RTC_CTRL_2_AIE; + Value &= ~RTC_CTRL_2_AF; + esp_err_t ret = I2C_Write(PCF85063_ADDRESS, RTC_CTRL_2_ADDR, &Value, 1); + if(ret != ESP_OK) + printf("PCF85063 : Failed to enable Alarm Flag and Clear Alarm Flag \r\n"); +} + +uint8_t PCF85063_Get_Alarm_Flag() // Get Alarm flag +{ + uint8_t Value = 0; + esp_err_t ret = I2C_Read(PCF85063_ADDRESS, RTC_CTRL_2_ADDR, &Value, 1); + if(ret != ESP_OK) + printf("PCF85063 : Failed to obtain a warning flag.\r\n"); + else + Value &= RTC_CTRL_2_AF | RTC_CTRL_2_AIE; + //printf("Value = 0x%x",Value); + return Value; +} + +void PCF85063_Set_Alarm(datetime_t time) // Set Alarm +{ + + uint8_t buf[5] ={ + decToBcd(time.second)&(~RTC_ALARM), + decToBcd(time.minute)&(~RTC_ALARM), + decToBcd(time.hour)&(~RTC_ALARM), + //decToBcd(time.day)&(~RTC_ALARM), + //decToBcd(time.dotw)&(~RTC_ALARM) + RTC_ALARM, //disalbe day + RTC_ALARM //disalbe weekday + }; + esp_err_t ret = I2C_Write(PCF85063_ADDRESS, RTC_SECOND_ALARM, buf, sizeof(buf)); + if(ret != ESP_OK) + printf("PCF85063 : Failed to set alarm flag\r\n"); +} + +void PCF85063_Read_Alarm(datetime_t *time) // Read Alarm +{ + uint8_t buf[5] = {0}; + esp_err_t ret = I2C_Read(PCF85063_ADDRESS, RTC_SECOND_ALARM, buf, sizeof(buf)); + if(ret != ESP_OK) + printf("PCF85063 : Failed to read the alarm sign\r\n"); + else{ + time->second = bcdToDec(buf[0] & 0x7F); + time->minute = bcdToDec(buf[1] & 0x7F); + time->hour = bcdToDec(buf[2] & 0x3F); + time->day = bcdToDec(buf[3] & 0x3F); + time->dotw = bcdToDec(buf[4] & 0x07); + } +} + +static uint8_t decToBcd(int val) // Convert normal decimal numbers to binary coded decimal +{ + return (uint8_t)((val / 10 * 16) + (val % 10)); +} +static int bcdToDec(uint8_t val) // Convert binary coded decimal to normal decimal numbers +{ + return (int)((val / 16 * 10) + (val % 16)); +} +void datetime_to_str(char *datetime_str,datetime_t time) +{ + sprintf(datetime_str, " %d.%d.%d %d:%d:%d %s", time.year, time.month, + time.day, time.hour, time.minute, time.second, Week[time.dotw]); +} \ No newline at end of file diff --git a/src/WS_PCF85063.h b/src/WS_PCF85063.h new file mode 100644 index 0000000..984d73e --- /dev/null +++ b/src/WS_PCF85063.h @@ -0,0 +1,103 @@ +#pragma once + +#include "I2C_Driver.h" + +//PCF85063_ADDRESS +#define PCF85063_ADDRESS (0x51) +// +#define YEAR_OFFSET (1970) +// registar overview - crtl & status reg +#define RTC_CTRL_1_ADDR (0x00) +#define RTC_CTRL_2_ADDR (0x01) +#define RTC_OFFSET_ADDR (0x02) +#define RTC_RAM_by_ADDR (0x03) +// registar overview - time & data reg +#define RTC_SECOND_ADDR (0x04) +#define RTC_MINUTE_ADDR (0x05) +#define RTC_HOUR_ADDR (0x06) +#define RTC_DAY_ADDR (0x07) +#define RTC_WDAY_ADDR (0x08) +#define RTC_MONTH_ADDR (0x09) +#define RTC_YEAR_ADDR (0x0A) // years 0-99; calculate real year = 1970 + RCC reg year +// registar overview - alarm reg +#define RTC_SECOND_ALARM (0x0B) +#define RTC_MINUTE_ALARM (0x0C) +#define RTC_HOUR_ALARM (0x0D) +#define RTC_DAY_ALARM (0x0E) +#define RTC_WDAY_ALARM (0x0F) +// registar overview - timer reg +#define RTC_TIMER_VAL (0x10) +#define RTC_TIMER_MODE (0x11) + +//RTC_CTRL_1 registar +#define RTC_CTRL_1_EXT_TEST (0x80) +#define RTC_CTRL_1_STOP (0x20) //0-RTC clock runs 1- RTC clock is stopped +#define RTC_CTRL_1_SR (0X10) //0-no software reset 1-initiate software rese +#define RTC_CTRL_1_CIE (0X04) //0-no correction interrupt generated 1-interrupt pulses are generated at every correction cycle +#define RTC_CTRL_1_12_24 (0X02) //0-24H 1-12H +#define RTC_CTRL_1_CAP_SEL (0X01) //0-7PF 1-12.5PF + +//RTC_CTRL_2 registar +#define RTC_CTRL_2_AIE (0X80) //alarm interrupt 0-disalbe 1-enable +#define RTC_CTRL_2_AF (0X40) //alarm flag 0-inactive/cleared 1-active/unchanged +#define RTC_CTRL_2_MI (0X20) //minute interrupt 0-disalbe 1-enable +#define RTC_CTRL_2_HMI (0X10) //half minute interrupt +#define RTC_CTRL_2_TF (0X08) + +// +#define RTC_OFFSET_MODE (0X80) + +// +#define RTC_TIMER_MODE_TE (0X04) //timer enable 0-disalbe 1-enable +#define RTC_TIMER_MODE_TIE (0X02) //timer interrupt enable 0-disalbe 1-enable +#define RTC_TIMER_MODE_TI_TP (0X01) //timer interrupt mode 0-interrupt follows timer flag 1-interrupt generates a pulse + +// format +#define RTC_ALARM (0x80) // set AEN_x registers +#define RTC_CTRL_1_DEFAULT (0x00) +#define RTC_CTRL_2_DEFAULT (0x00) + +#define RTC_TIMER_FLAG (0x08) + +typedef struct { + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t dotw; + uint8_t hour; + uint8_t minute; + uint8_t second; +}datetime_t; + + +const unsigned char MonthStr[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov","Dec"}; +const unsigned char Week[7][5] = {"SUN","Mon","Tues","Wed","Thur","Fri","Sat"}; + +extern datetime_t datetime; +void PCF85063_Init(void); +void PCF85063_Reset(void); +void PCF85063Task(void *parameter); + +void PCF85063_Set_Time(datetime_t time); +void PCF85063_Set_Date(datetime_t date); +void PCF85063_Set_All(datetime_t time); + +void PCF85063_Read_Time(datetime_t *time); + + +void PCF85063_Enable_Alarm(void); +uint8_t PCF85063_Get_Alarm_Flag(); +void PCF85063_Set_Alarm(datetime_t time); +void PCF85063_Read_Alarm(datetime_t *time); + +void datetime_to_str(char *datetime_str,datetime_t time); + + +// weekday format +// 0 - sunday +// 1 - monday +// 2 - tuesday +// 3 - wednesday +// 4 - thursday +// 5 - friday +// 6 - saturday \ No newline at end of file diff --git a/src/WS_RS485.cpp b/src/WS_RS485.cpp new file mode 100644 index 0000000..4390571 --- /dev/null +++ b/src/WS_RS485.cpp @@ -0,0 +1,163 @@ +#include "WS_RS485.h" +#include + +HardwareSerial lidarSerial(1); // Using serial port 1 +uint8_t data[][8] = { // ESP32-S3-POE-ETH-8DI-8RO Control Command (RS485 receiving data) + { 0x06, 0x05, 0x00, 0x01, 0x55, 0x00, 0xA2, 0xED }, // ESP32-S3-POE-ETH-8DI-8RO CH1 Toggle + { 0x06, 0x05, 0x00, 0x02, 0x55, 0x00, 0x52, 0xED }, // ESP32-S3-POE-ETH-8DI-8RO CH2 Toggle + { 0x06, 0x05, 0x00, 0x03, 0x55, 0x00, 0x03, 0x2D }, // ESP32-S3-POE-ETH-8DI-8RO CH3 Toggle + { 0x06, 0x05, 0x00, 0x04, 0x55, 0x00, 0xB2, 0xEC }, // ESP32-S3-POE-ETH-8DI-8RO CH4 Toggle + { 0x06, 0x05, 0x00, 0x05, 0x55, 0x00, 0xE3, 0x2C }, // ESP32-S3-POE-ETH-8DI-8RO CH5 Toggle + { 0x06, 0x05, 0x00, 0x06, 0x55, 0x00, 0x13, 0x2C }, // ESP32-S3-POE-ETH-8DI-8RO CH6 Toggle + { 0x06, 0x05, 0x00, 0x07, 0x55, 0x00, 0x42, 0xEC }, // ESP32-S3-POE-ETH-8DI-8RO CH7 Toggle + { 0x06, 0x05, 0x00, 0x08, 0x55, 0x00, 0x72, 0xEF }, // ESP32-S3-POE-ETH-8DI-8RO CH8 Toggle + { 0x06, 0x05, 0x00, 0xFF, 0xFF, 0x00, 0xBD, 0xBD }, // ESP32-S3-POE-ETH-8DI-8RO ALL ON + { 0x06, 0x05, 0x00, 0xFF, 0x00, 0x00, 0xFC, 0x4D }, // ESP32-S3-POE-ETH-8DI-8RO ALL OFF +}; +uint8_t Send_Data[][8] = { // Modbus RTU Relay Control Command (RS485 send data) + { 0x01, 0x05, 0x00, 0x00, 0x55, 0x00, 0xF2, 0x9A }, // Modbus RTU Relay CH1 Toggle + { 0x01, 0x05, 0x00, 0x01, 0x55, 0x00, 0xA3, 0x5A }, // Modbus RTU Relay CH2 Toggle + { 0x01, 0x05, 0x00, 0x02, 0x55, 0x00, 0x53, 0x5A }, // Modbus RTU Relay CH3 Toggle + { 0x01, 0x05, 0x00, 0x03, 0x55, 0x00, 0x02, 0x9A }, // Modbus RTU Relay CH4 Toggle + { 0x01, 0x05, 0x00, 0x04, 0x55, 0x00, 0xB3, 0x5B }, // Modbus RTU Relay CH5 Toggle + { 0x01, 0x05, 0x00, 0x05, 0x55, 0x00, 0xE2, 0x9B }, // Modbus RTU Relay CH6 Toggle + { 0x01, 0x05, 0x00, 0x06, 0x55, 0x00, 0x12, 0x9B }, // Modbus RTU Relay CH7 Toggle + { 0x01, 0x05, 0x00, 0x07, 0x55, 0x00, 0x43, 0x5B }, // Modbus RTU Relay CH8 Toggle + { 0x01, 0x05, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0x4A }, // Modbus RTU Relay ALL ON + { 0x01, 0x05, 0x00, 0xFF, 0x00, 0x00, 0xFD, 0xFA }, // Modbus RTU Relay ALL OFF +}; +uint8_t buf[20] = {0}; // Data storage area +int numRows = sizeof(data) / sizeof(data[0]); + +void SetData(uint8_t* data, size_t length) { + lidarSerial.write(data, length); // Send data from the RS485 +} +void ReadData(uint8_t* buf, uint8_t length) { + uint8_t Receive_Flag = 0; + Receive_Flag = lidarSerial.available(); + if (Receive_Flag >= length) { + lidarSerial.readBytes(buf, length); + char printBuf[length * 3 + 1]; + sprintf(printBuf, "Received data: "); + for (int i = 0; i < length; i++) { + sprintf(printBuf + strlen(printBuf), "%02X ", buf[i]); + } + printf(printBuf); + /************************* + Add a receiving data handler + *************************/ + Receive_Flag = 0; + memset(buf, 0, sizeof(buf)); + } +} +void RS485_Analysis(uint8_t *buf) +{ + switch(buf[1]) + { + case Extension_CH1: + SetData(Send_Data[0],sizeof(Send_Data[0])); + printf("|*** Toggle expansion channel 1 ***|\r\n"); + break; + case Extension_CH2: + SetData(Send_Data[1],sizeof(Send_Data[1])); + printf("|*** Toggle expansion channel 2 ***|\r\n"); + break; + case Extension_CH3: + SetData(Send_Data[2],sizeof(Send_Data[2])); + printf("|*** Toggle expansion channel 3 ***|\r\n"); + break; + case Extension_CH4: + SetData(Send_Data[3],sizeof(Send_Data[3])); + printf("|*** Toggle expansion channel 4 ***|\r\n"); + break; + case Extension_CH5: + SetData(Send_Data[4],sizeof(Send_Data[4])); + printf("|*** Toggle expansion channel 5 ***|\r\n"); + break; + case Extension_CH6: + SetData(Send_Data[5],sizeof(Send_Data[5])); + printf("|*** Toggle expansion channel 6 ***|\r\n"); + break; + case Extension_CH7: + SetData(Send_Data[6],sizeof(Send_Data[6])); + printf("|*** Toggle expansion channel 7 ***|\r\n"); + break; + case Extension_CH8: + SetData(Send_Data[7],sizeof(Send_Data[7])); + printf("|*** Toggle expansion channel 8 ***|\r\n"); + break; + case Extension_ALL_ON: + SetData(Send_Data[8],sizeof(Send_Data[8])); + printf("|*** Enable all extension channels ***|\r\n"); + break; + case Extension_ALL_OFF: + SetData(Send_Data[9],sizeof(Send_Data[9])); + printf("|*** Close all expansion channels ***|\r\n"); + break; + default: + printf("Note : Non-control external device instructions !\r\n"); + } +} +uint32_t Baudrate = 0; +double transmission_time = 0; +double RS485_cmd_Time = 0; +void RS485_Init() // Initializing serial port +{ + Baudrate = 9600; // Set the baud rate of the serial port + lidarSerial.begin(Baudrate, SERIAL_8N1, RXD1, TXD1); // Initializing serial port + transmission_time = 10.0 / Baudrate * 1000 ; + RS485_cmd_Time = transmission_time*8; // 8:data length + xTaskCreatePinnedToCore( + RS485Task, + "RS485Task", + 4096, + NULL, + 3, + NULL, + 0 + ); +} + +void RS485Task(void *parameter) { + while(1){ + RS485_Loop(); + vTaskDelay(pdMS_TO_TICKS(50)); + } + vTaskDelete(NULL); +} + +void RS485_Loop() +{ + uint8_t Receive_Flag = 0; // Receiving mark + Receive_Flag = lidarSerial.available(); + + if (Receive_Flag > 0) { + if(RS485_cmd_Time > 1) // Time greater than 1 millisecond + delay((uint16_t)RS485_cmd_Time); + else // Time is less than 1 millisecond + delay(1); + Receive_Flag = lidarSerial.available(); + lidarSerial.readBytes(buf, Receive_Flag); // The Receive_Flag length is read + if(Receive_Flag == 8){ + uint8_t i=0; + for(i=0;i numRows-1) + printf("Note : Non-instruction data was received - RS485 !\r\n"); + } + else{ + printf("Note : Non-instruction data was received .Number of bytes: %d - RS485 !\r\n",Receive_Flag); + } + Receive_Flag=0; + memset(buf,0, sizeof(buf)); + } +} \ No newline at end of file diff --git a/src/WS_RS485.h b/src/WS_RS485.h new file mode 100644 index 0000000..9eb4e98 --- /dev/null +++ b/src/WS_RS485.h @@ -0,0 +1,26 @@ +#pragma once + +#include // Reference the ESP32 built-in serial port library +#include "WS_GPIO.h" +#include "WS_Relay.h" + +#define Extension_CH1 1 // Expansion Channel 1 +#define Extension_CH2 2 // Expansion Channel 2 +#define Extension_CH3 3 // Expansion Channel 3 +#define Extension_CH4 4 // Expansion Channel 4 +#define Extension_CH5 5 // Expansion Channel 5 +#define Extension_CH6 6 // Expansion Channel 6 +#define Extension_CH7 7 // Expansion Channel 7 +#define Extension_CH8 8 // Expansion Channel 8 +#define Extension_ALL_ON 9 // Expansion ALL ON +#define Extension_ALL_OFF 10 // Expansion ALL OFF + + + +void SetData(uint8_t* data, size_t length); // Send data from the RS485 +void ReadData(uint8_t* buf, uint8_t length); // Data is received over RS485 + +void RS485_Analysis(uint8_t *buf); // External relay control +void RS485_Init(); // Example Initialize the system serial port and RS485 +void RS485_Loop(); // Read RS485 data, parse and control relays +void RS485Task(void *parameter); diff --git a/src/WS_RTC.cpp b/src/WS_RTC.cpp new file mode 100644 index 0000000..77ee290 --- /dev/null +++ b/src/WS_RTC.cpp @@ -0,0 +1,350 @@ +#include "WS_RTC.h" + +Timing_RTC CHx_State[Timing_events_Number_MAX]; // Set a maximum of Timing_events_Number_MAX timers +char Event_str[Timing_events_Number_MAX][1000]; +static Timing_RTC CHx_State_Default; // Event initial state +const unsigned char Event_cycle[4][13] = {"Aperiodicity","everyday","Weekly","monthly"}; + +void RTC_Init(void){ + PCF85063_Init(); + xTaskCreatePinnedToCore( + RTCTask, + "RTCTask", + 4096, + NULL, + 3, + NULL, + 0 + ); +} +uint8_t Timing_events_Num = 0; +void RTCTask(void *parameter) +{ + static uint8_t Time_Old = 0; + while(1){ + if(Timing_events_Num){ + for (int i = 0; i < Timing_events_Number_MAX; i++){ + if(CHx_State[i].Enable_Flag){ + if(CHx_State[i].Time.hour == datetime.hour && CHx_State[i].Time.minute == datetime.minute && CHx_State[i].Time.second == datetime.second && datetime.second != Time_Old){ // The event time is consistent with the current time + switch(CHx_State[i].repetition_State){ + case Repetition_NONE: + if(CHx_State[i].Time.year == datetime.year && CHx_State[i].Time.month == datetime.month && CHx_State[i].Time.day == datetime.day){ // Executes at the defined date and time + TimerEvent_handling(CHx_State[i]); + TimerEvent_Del(CHx_State[i]); + } + break; + case Repetition_everyday: + TimerEvent_handling(CHx_State[i]); + break; + case Repetition_Weekly: + if(CHx_State[i].Time.dotw == datetime.dotw){ + TimerEvent_handling(CHx_State[i]); + } + break; + case Repetition_monthly: + if(CHx_State[i].Time.day == datetime.day){ + TimerEvent_handling(CHx_State[i]); + } + break; + default: + printf("Event error!!!!\n"); + break; + } + } + } + } + } + Time_Old = datetime.second; + vTaskDelay(pdMS_TO_TICKS(100)); + } + vTaskDelete(NULL); +} + +void TimerEvent_handling(Timing_RTC event){ + uint8_t Retain_channels = 0; + printf("Event %d : \r\n", event.Event_Number); + char datetime_str[50]; + datetime_to_str(datetime_str,event.Time); + for (int i = 0; i < Relay_Number_MAX; i++) { + if(*(&(event.Relay_CH1)+i) == STATE_Retain) // Find the modified channel + Retain_channels ++; // Number of unmodified channels + } + if(Retain_channels < Relay_Number_MAX - 1){ + printf("%s\r\n", datetime_str); + printf("CHx Open : "); + int j = 0; + for (j = 0; j < Relay_Number_MAX; j++) { + if(*(&(event.Relay_CH1)+j) == STATE_Open) + printf("CH%d ", j+1); + } + printf("\r\nCHx Closs : "); + for (j = 0; j < Relay_Number_MAX; j++) { + if(*(&(event.Relay_CH1)+j) == STATE_Closs) + printf("CH%d ", j+1); + } + if(Retain_channels){ + printf("\r\nCHx Retain : "); + for (j = 0; j < Relay_Number_MAX; j++) { + if(*(&(event.Relay_CH1)+j) == STATE_Retain) + printf("CH%d ", j+1); + } + } + printf("\r\n"); + Relay_Immediate_CHxn(&(event.Relay_CH1), RTC_Mode); + printf("\r\n"); + } + else if(Retain_channels == Relay_Number_MAX - 1){ // Modified a channel (use TimerEvent_CHx_Set()) + printf("%s\r\n", datetime_str); + for (int x = 0; x < Relay_Number_MAX; x++) { + if(*(&(event.Relay_CH1)+x) != STATE_Retain){ // Find the modified channel + if(*(&(event.Relay_CH1)+x)){ + printf("CH%d Open\r\n", x); + Relay_Immediate(x, true, RTC_Mode); + printf("\r\n"); + } + else{ + printf("CH%d Closs\r\n", x); + Relay_Immediate(x, false, RTC_Mode); + printf("\r\n"); + } + break; + } + } + } + else{ + printf("Event error or no relay control!!!\r\n"); + } +} + +void TimerEvent_CHx_Set(datetime_t time,uint8_t CHx, bool State, Repetition_event Repetition) +{ + char datetime_str[50]; + datetime_to_str(datetime_str,datetime); + printf("Now Time: %s!!!!\r\n", datetime_str); + if(CHx > Relay_Number_MAX){ + printf("Timing_CHx_Set(function): Error passing parameter CHx!!!!\r\n"); + return; + } + if(Timing_events_Num + 1 >= Timing_events_Number_MAX) + { + printf("Note : The number of scheduled events is full.\r\n"); + } + else{ + RGB_Open_Time(50, 36, 0, 1000, 0); + CHx_State[Timing_events_Num].Enable_Flag = true; + CHx_State[Timing_events_Num].Event_Number = Timing_events_Num + 1; + *(&(CHx_State[Timing_events_Num].Relay_CH1)+CHx) = (Status_adjustment)State; + CHx_State[Timing_events_Num].Time = time; + CHx_State[Timing_events_Num].repetition_State = Repetition; + Timing_events_Num ++; + datetime_to_str(datetime_str,time); + if(State){ + printf("New timing event%d :\r\n %s set CH%d Open ----- %s\r\n\r\n", Timing_events_Num, datetime_str, CHx, Event_cycle[Repetition]); + sprintf(Event_str[Timing_events_Num-1], "Event %d : %s set CH%d Open ----- %s\\n\\n", Timing_events_Num, datetime_str, CHx, Event_cycle[Repetition]); + } + else{ + printf("New timing event%d :\r\n %s set CH%d Closs ----- %s\r\n\r\n", Timing_events_Num, datetime_str, CHx, Event_cycle[Repetition]); + sprintf(Event_str[Timing_events_Num-1], "Event %d : %s set CH%d Closs ----- %s\\n\\n", Timing_events_Num, datetime_str, CHx, Event_cycle[Repetition]); + } + Buzzer_Open_Time(700, 0); + } +} + +void TimerEvent_CHxs_Set(datetime_t time,uint8_t PinState, Repetition_event Repetition) +{ + + char datetime_str[50]; + datetime_to_str(datetime_str,datetime); + printf("Now Time: %s!!!!\r\n", datetime_str); + if(Timing_events_Num + 1 >= Timing_events_Number_MAX) + { + printf("Note : The number of scheduled events is full.\r\n"); + } + else{ + RGB_Open_Time(50, 36, 0, 1000, 0); + CHx_State[Timing_events_Num].Enable_Flag = true; + CHx_State[Timing_events_Num].Event_Number = Timing_events_Num + 1; + for (int i = 0; i < Relay_Number_MAX; i++) { + *(&(CHx_State[Timing_events_Num].Relay_CH1)+i) = (Status_adjustment)((PinState >> i) & 0x01); + } + CHx_State[Timing_events_Num].Time = time; + CHx_State[Timing_events_Num].repetition_State = Repetition; + Timing_events_Num ++; + datetime_to_str(datetime_str,time); + printf("New timing event%d :\r\n %s \r\n",Timing_events_Num, datetime_str); + printf(" CHx :"); + for (int i = 0; i < Relay_Number_MAX; i++) + printf("CH%d ", i+1); + printf("\r\n State :"); + for (int i = 0; i < Relay_Number_MAX; i++) { + if((PinState >> i) & 0x01) + printf("Open "); + else + printf("Closs "); + } + printf("\r\n"); + printf(" ----- %s\r\n\r\n", Event_cycle[Repetition]); + printf("\r\n"); + Buzzer_Open_Time(700, 0); + + int len = 0; + char Event_content[1000]; + len += snprintf(Event_content + len, sizeof(Event_content) - len, "    CHx  :"); + for (int i = 0; i < Relay_Number_MAX; i++) { + len += snprintf(Event_content + len, sizeof(Event_content) - len, "CH%d       ", i + 1); + } + len += snprintf(Event_content + len, sizeof(Event_content) - len, "\\n     State :"); + for (int i = 0; i < Relay_Number_MAX; i++) { + if ((PinState >> i) & 0x01) + len += snprintf(Event_content + len, sizeof(Event_content) - len, "Open     "); + else + len += snprintf(Event_content + len, sizeof(Event_content) - len, "Closs     "); + } + len += snprintf(Event_content + len, sizeof(Event_content) - len, "\\n    ----- %s\\n\\n", Event_cycle[Repetition]); + // printf("%s\r\n", Event_content); + sprintf(Event_str[Timing_events_Num-1], "Event %d : %s \\n%s", Timing_events_Num, datetime_str,Event_content); + } +} +void TimerEvent_CHxn_Set(datetime_t time,Status_adjustment *Relay_n, Repetition_event Repetition) +{ + char datetime_str[50]; + datetime_to_str(datetime_str,datetime); + printf("Now Time: %s!!!!\r\n", datetime_str); + if(Timing_events_Num + 1 >= Timing_events_Number_MAX) + { + printf("Note : The number of scheduled events is full.\r\n"); + } + else{ + RGB_Open_Time(50, 36, 0, 1000, 0); + CHx_State[Timing_events_Num].Enable_Flag = true; + CHx_State[Timing_events_Num].Event_Number = Timing_events_Num + 1; + for (int i = 0; i < Relay_Number_MAX; i++) { + *(&(CHx_State[Timing_events_Num].Relay_CH1)+i) = Relay_n[i]; + } + CHx_State[Timing_events_Num].Time = time; + CHx_State[Timing_events_Num].repetition_State = Repetition; + Timing_events_Num ++; + datetime_to_str(datetime_str,time); + printf("New timing event%d :\r\n %s \r\n",Timing_events_Num, datetime_str); + printf(" CHx :"); + for (int i = 0; i < Relay_Number_MAX; i++) + printf("CH%d ", i+1); + printf("\r\n State :"); + for (int i = 0; i < Relay_Number_MAX; i++) { + if(Relay_n[i] == STATE_Open) + printf("Open "); + else if(Relay_n[i] == STATE_Closs) + printf("Closs "); + else if(Relay_n[i] == STATE_Retain) + printf("Retain "); + } + printf("\r\n"); + printf(" ----- %s\r\n\r\n", Event_cycle[Repetition]); + printf("\r\n"); + Buzzer_Open_Time(700, 0); + + int len = 0; + char Event_content[1000]; + len += snprintf(Event_content + len, sizeof(Event_content) - len, "    CHx  :"); + for (int i = 0; i < Relay_Number_MAX; i++) { + len += snprintf(Event_content + len, sizeof(Event_content) - len, "CH%d       ", i + 1); + } + len += snprintf(Event_content + len, sizeof(Event_content) - len, "\\n    State :"); + for (int i = 0; i < Relay_Number_MAX; i++) { + if (Relay_n[i] == STATE_Open) + len += snprintf(Event_content + len, sizeof(Event_content) - len, "Open     "); + else if(Relay_n[i] == STATE_Closs) + len += snprintf(Event_content + len, sizeof(Event_content) - len, "Closs     "); + else if(Relay_n[i] == STATE_Retain) + len += snprintf(Event_content + len, sizeof(Event_content) - len, "Retain   "); + } + len += snprintf(Event_content + len, sizeof(Event_content) - len, "\\n    ----- %s\\n\\n", Event_cycle[Repetition]); + // printf("%s\r\n", Event_content); + sprintf(Event_str[Timing_events_Num-1], "Event %d : %s \\n%s", Timing_events_Num, datetime_str,Event_content); + } +} + +void TimerEvent_printf(Timing_RTC event){ + uint8_t Retain_channels = 0; + uint8_t open[8]={0}; + printf("Event %d : \r\n", event.Event_Number); + char datetime_str[50]; + datetime_to_str(datetime_str,event.Time); + for (int i = 0; i < Relay_Number_MAX; i++) { + if(*(&(event.Relay_CH1)+i) == STATE_Retain) // Find the modified channel + Retain_channels ++; // Number of unmodified channels + else + open[i] = *(&(event.Relay_CH1)+i); + } + if(Retain_channels == 0){ // All channels have been modified (use TimerEvent_CHxs_Set()) + printf("%s\r\n", datetime_str); + printf(" CHx Open : "); + for (int j = 0; j < Relay_Number_MAX; j++) { + if(open[j]) + printf("CH%d ", j); + } + printf("\r\n CHx Closs : "); + for (int k = 0; k < Relay_Number_MAX; k++) { + if(!open[k]) + printf("CH%d ", k); + } + printf("\r\n"); + } + else if(Retain_channels == Relay_Number_MAX - 1){ // Modified a channel (use TimerEvent_CHx_Set()) + printf("%s ,", datetime_str); + for (int x = 0; x < Relay_Number_MAX; x++) { + if(*(&(event.Relay_CH1)+x) != STATE_Retain){ // Find the modified channel + if(*(&(event.Relay_CH1)+x)) + printf("CH%d Open\r\n", x); + else + printf("CH%d Closs\r\n", x); + break; + } + } + } + else{ + printf("%s\r\n", datetime_str); + printf("CHx Open : "); + int j = 0; + for (j = 0; j < Relay_Number_MAX; j++) { + if(open[j] == STATE_Open) + printf("CH%d ", j+1); + } + printf("\r\nCHx Closs : "); + for (j = 0; j < Relay_Number_MAX; j++) { + if(open[j] == STATE_Closs) + printf("CH%d ", j+1); + } + printf("\r\nCHx Retain : "); + for (j = 0; j < Relay_Number_MAX; j++) { + if(open[j] == STATE_Retain) + printf("CH%d ", j+1); + } + printf("\r\n"); + } +} + +void TimerEvent_printf_ALL(void) +{ + printf("/******************* Current RTC event *******************/ \r\n"); + for (int i = 0; i < Timing_events_Number_MAX; i++) { + if(CHx_State[i].Enable_Flag) + TimerEvent_printf(CHx_State[i]); + } + printf("/******************* Current RTC event *******************/\r\n\r\n "); +} +void TimerEvent_Del(Timing_RTC event){ + RGB_Open_Time(20, 0, 50, 1000, 0); + printf("Example Delete an RTC event%d\r\n\r\n",event.Event_Number); + for (int i = event.Event_Number; i < Timing_events_Number_MAX; i++) { + CHx_State[i].Event_Number = CHx_State[i].Event_Number -1; + CHx_State[i-1] = CHx_State[i]; + } + CHx_State[Timing_events_Number_MAX - 1] = CHx_State_Default; + memset(Event_str[Timing_events_Number_MAX - 1], 0, sizeof(Event_str[Timing_events_Number_MAX - 1])); + Timing_events_Num --; +} +void TimerEvent_Del_Number(uint8_t Event_Number){ + TimerEvent_Del(CHx_State[Event_Number - 1]); + Buzzer_Open_Time(700, 300); +} \ No newline at end of file diff --git a/src/WS_RTC.h b/src/WS_RTC.h new file mode 100644 index 0000000..5640e11 --- /dev/null +++ b/src/WS_RTC.h @@ -0,0 +1,45 @@ +#pragma once + +#include "WS_PCF85063.h" +#include "WS_Relay.h" +#include "WS_GPIO.h" + +#define Timing_events_Number_MAX 10 // Indicates the number of timers that can be set + +typedef enum { + Repetition_NONE = 0, // aperiodicity + Repetition_everyday = 1, // The event is repeated at this time every day + Repetition_Weekly = 2, // This event is repeated every week at this time + Repetition_monthly = 3, // This event is repeated every month at this time +} Repetition_event; + +typedef struct { + bool Enable_Flag = false; // The timer event enabled flag. + uint8_t Event_Number = 0; // Current event sequence number + Status_adjustment Relay_CH1 = STATE_Retain; // The CH1 status is changed periodically + Status_adjustment Relay_CH2 = STATE_Retain; // The CH2 status is changed periodically + Status_adjustment Relay_CH3 = STATE_Retain; // The CH3 status is changed periodically + Status_adjustment Relay_CH4 = STATE_Retain; // The CH4 status is changed periodically + Status_adjustment Relay_CH5 = STATE_Retain; // The CH5 status is changed periodically + Status_adjustment Relay_CH6 = STATE_Retain; // The CH6 status is changed periodically + Status_adjustment Relay_CH7 = STATE_Retain; // The CH7 status is changed periodically + Status_adjustment Relay_CH8 = STATE_Retain; // The CH8 status is changed periodically + datetime_t Time; + Repetition_event repetition_State = Repetition_NONE; // Periodic execution +}Timing_RTC; + +extern uint8_t Timing_events_Num; +extern Timing_RTC CHx_State[Timing_events_Number_MAX]; +extern char Event_str[Timing_events_Number_MAX][1000]; + +void RTCTask(void *parameter); +void TimerEvent_handling(Timing_RTC event); +void TimerEvent_printf(Timing_RTC event); +void TimerEvent_Del(Timing_RTC event); + +void RTC_Init(void); +void TimerEvent_CHx_Set(datetime_t time,uint8_t CHx, bool State, Repetition_event Repetition); +void TimerEvent_CHxs_Set(datetime_t time,uint8_t PinState, Repetition_event Repetition); +void TimerEvent_CHxn_Set(datetime_t time,Status_adjustment *Relay_n, Repetition_event Repetition); +void TimerEvent_printf_ALL(void); +void TimerEvent_Del_Number(uint8_t Event_Number); \ No newline at end of file diff --git a/src/WS_Relay.cpp b/src/WS_Relay.cpp new file mode 100644 index 0000000..31a92e4 --- /dev/null +++ b/src/WS_Relay.cpp @@ -0,0 +1,273 @@ +#include "WS_Relay.h" + +bool Failure_Flag = 0; +/************************************************************* Relay I/O *************************************************************/ +bool Relay_Open(uint8_t CHx) +{ + if(!Set_EXIO(CHx, true)){ + printf("Failed to Open CH%d!!!\r\n", CHx); + Failure_Flag = 1; + return 0; + } + return 1; +} +bool Relay_Closs(uint8_t CHx) +{ + if(!Set_EXIO(CHx, false)){ + printf("Failed to Closs CH%d!!!\r\n", CHx); + Failure_Flag = 1; + return 0; + } + return 1; +} +bool Relay_CHx_Toggle(uint8_t CHx) +{ + if(!Set_Toggle(CHx)){ + printf("Failed to Toggle CH%d!!!\r\n", CHx); + Failure_Flag = 1; + return 0; + } + return 1; +} +bool Relay_CHx(uint8_t CHx, bool State) +{ + bool result = 0; + if(State) + result = Relay_Open(CHx); + else + result = Relay_Closs(CHx); + if(!result) + Failure_Flag = 1; + return result; +} +bool Relay_CHxs_PinState(uint8_t PinState) +{ + if(!Set_EXIOS(PinState)){ + printf("Failed to set the relay status!!!\r\n"); + Failure_Flag = 1; + return 0; + } + return 1; +} + +void RelayFailTask(void *parameter) { + while(1){ + if(Failure_Flag) + { + Failure_Flag = 0; + printf("Error: Relay control failed!!!\r\n"); + RGB_Open_Time(60,0,0,5000,500); + Buzzer_Open_Time(5000, 500); + } + vTaskDelay(pdMS_TO_TICKS(50)); + } + vTaskDelete(NULL); +} +void Relay_Init(void) +{ + TCA9554PWR_Init(0x00); + xTaskCreatePinnedToCore( + RelayFailTask, + "RelayFailTask", + 4096, + NULL, + 3, + NULL, + 0 + ); +} + +/******************************************************** Data Analysis ********************************************************/ +bool Relay_Flag[8] = {0}; // Relay current status flag +void Relay_Analysis(uint8_t *buf,uint8_t Mode_Flag) +{ + uint8_t ret = 0; + if(Mode_Flag == Bluetooth_Mode) + printf("Bluetooth Data :\r\n"); + else if(Mode_Flag == WIFI_Mode) + printf("WIFI Data :\r\n"); + else if(Mode_Flag == MQTT_Mode) + printf("MQTT Data :\r\n"); + else if(Mode_Flag == RS485_Mode) + printf("RS485 Data :\r\n"); + switch(buf[0]) + { + case CH1: + ret = Relay_CHx_Toggle(GPIO_PIN_CH1); //Toggle the level status of the GPIO_PIN_CH1 pin + if(ret){ + Relay_Flag[0] =! Relay_Flag[0]; + Buzzer_Open_Time(200, 0); + if(Relay_Flag[0]) + printf("|*** Relay CH1 on ***|\r\n"); + else + printf("|*** Relay CH1 off ***|\r\n"); + } + break; + case CH2: + ret = Relay_CHx_Toggle(GPIO_PIN_CH2); //Toggle the level status of the GPIO_PIN_CH2 pin + if(ret){ + Relay_Flag[1] =! Relay_Flag[1]; + Buzzer_Open_Time(200, 0); + if(Relay_Flag[1]) + printf("|*** Relay CH2 on ***|\r\n"); + else + printf("|*** Relay CH2 off ***|\r\n"); + } + break; + case CH3: + ret = Relay_CHx_Toggle(GPIO_PIN_CH3); //Toggle the level status of the GPIO_PIN_CH3 pin + if(ret){ + Relay_Flag[2] =! Relay_Flag[2]; + Buzzer_Open_Time(200, 0); + if(Relay_Flag[2]) + printf("|*** Relay CH3 on ***|\r\n"); + else + printf("|*** Relay CH3 off ***|\r\n"); + } + break; + case CH4: + ret = Relay_CHx_Toggle(GPIO_PIN_CH4); //Toggle the level status of the GPIO_PIN_CH4 pin + if(ret){ + Relay_Flag[3] =! Relay_Flag[3]; + Buzzer_Open_Time(200, 0); + if(Relay_Flag[3]) + printf("|*** Relay CH4 on ***|\r\n"); + else + printf("|*** Relay CH4 off ***|\r\n"); + } + break; + case CH5: + ret = Relay_CHx_Toggle(GPIO_PIN_CH5); //Toggle the level status of the GPIO_PIN_CH5 pin + if(ret){ + Relay_Flag[4] =! Relay_Flag[4]; + Buzzer_Open_Time(200, 0); + if(Relay_Flag[4]) + printf("|*** Relay CH5 on ***|\r\n"); + else + printf("|*** Relay CH5 off ***|\r\n"); + } + break; + case CH6: + ret = Relay_CHx_Toggle(GPIO_PIN_CH6); //Toggle the level status of the GPIO_PIN_CH6 pin + if(ret){ + Relay_Flag[5] =! Relay_Flag[5]; + Buzzer_Open_Time(200, 0); + if(Relay_Flag[5]) + printf("|*** Relay CH6 on ***|\r\n"); + else + printf("|*** Relay CH6 off ***|\r\n"); + } + break; + case CH7: + ret = Relay_CHx_Toggle(GPIO_PIN_CH7); //Toggle the level status of the GPIO_PIN_CH6 pin + if(ret){ + Relay_Flag[6] =! Relay_Flag[6]; + Buzzer_Open_Time(200, 0); + if(Relay_Flag[6]) + printf("|*** Relay CH7 on ***|\r\n"); + else + printf("|*** Relay CH7 off ***|\r\n"); + } + break; + case CH8: + ret = Relay_CHx_Toggle(GPIO_PIN_CH8); //Toggle the level status of the GPIO_PIN_CH6 pin + if(ret){ + Relay_Flag[7] =! Relay_Flag[7]; + Buzzer_Open_Time(200, 0); + if(Relay_Flag[7]) + printf("|*** Relay CH8 on ***|\r\n"); + else + printf("|*** Relay CH8 off ***|\r\n"); + } + break; + case ALL_ON: + ret = Relay_CHxs_PinState(0xFF); // Turn on all relay + if(ret){ + memset(Relay_Flag,1, sizeof(Relay_Flag)); + printf("|*** Relay ALL on ***|\r\n"); + Buzzer_Open_Time(500, 0); + } + + break; + case ALL_OFF: + ret = Relay_CHxs_PinState(0x00); // Turn off all relay + if(ret){ + memset(Relay_Flag,0, sizeof(Relay_Flag)); + printf("|*** Relay ALL off ***|\r\n"); + Buzzer_Open_Time(500, 150); + } + break; + default: + printf("Note : Non-instruction data was received ! - %c\r\n", buf[0]); + } +} + +void Relay_Immediate(uint8_t CHx, bool State, uint8_t Mode_Flag) +{ + if(!CHx || CHx > 8){ + printf("Relay_Immediate(function): Incoming parameter error!!!!\r\n"); + Failure_Flag = 1; + } + else{ + uint8_t ret = 0; + if(Mode_Flag == DIN_Mode) + printf("DIN Data :\r\n"); + else if(Mode_Flag == RTC_Mode) + printf("RTC Data :\r\n"); + ret = Relay_CHx(CHx,State); + if(ret){ + Relay_Flag[CHx-1] = State; + Buzzer_Open_Time(200, 0); + if(Relay_Flag[0]) + printf("|*** Relay CH%d on ***|\r\n",CHx); + else + printf("|*** Relay CH%d off ***|\r\n",CHx); + } + } +} +void Relay_Immediate_CHxn(Status_adjustment * Relay_n, uint8_t Mode_Flag) +{ + uint8_t ret = 0; + if(Mode_Flag == DIN_Mode) + printf("DIN Data :\r\n"); + else if(Mode_Flag == RTC_Mode) + printf("RTC Data :\r\n"); + for (int i = 0; i < 8; i++) { + if(Relay_n[i] == STATE_Open || Relay_n[i] == STATE_Closs){ + Relay_Flag[i] = (bool)Relay_n[i]; + ret = Relay_CHx(i+1,Relay_n[i]); + if(Relay_n[i] == STATE_Open) + printf("|*** Relay CH%d on ***|\r\n",i+1); + else if(Relay_n[i] == STATE_Closs) + printf("|*** Relay CH%d off ***|\r\n",i+1); + } + } + Buzzer_Open_Time(200, 0); +} + +void Relay_Immediate_CHxs(uint8_t PinState, uint8_t Mode_Flag) +{ + uint8_t ret = 0; + if(Mode_Flag == DIN_Mode) + printf("DIN Data :\r\n"); + else if(Mode_Flag == RTC_Mode) + printf("RTC Data :\r\n"); + for (int i = 0; i < 8; i++) { + Relay_Flag[i] = (PinState >> i) & 0x01; // 提取每一位并赋值 + } + ret = Relay_CHxs_PinState(PinState); + if(ret){ + for (int j = 0; j < 8; j++) { + if(Relay_Flag[j]) + printf("|*** Relay CH%d on ***|\r\n",j+1); + else + printf("|*** Relay CH%d off ***|\r\n",j+1); + } + Buzzer_Open_Time(200, 0); + } + else + { + printf("Relay_Immediate_CHxs(function): Relay control failure!!!!\r\n"); + Failure_Flag = 1; + } +} \ No newline at end of file diff --git a/src/WS_Relay.h b/src/WS_Relay.h new file mode 100644 index 0000000..bbf95b0 --- /dev/null +++ b/src/WS_Relay.h @@ -0,0 +1,56 @@ +#pragma once + +#include "WS_TCA9554PWR.h" +#include // Reference the ESP32 built-in serial port library +#include "WS_GPIO.h" + + +/************************************************************* I/O *************************************************************/ +#define Relay_Number_MAX 8 +#define GPIO_PIN_CH1 EXIO_PIN1 // CH1 Control GPIO +#define GPIO_PIN_CH2 EXIO_PIN2 // CH2 Control GPIO +#define GPIO_PIN_CH3 EXIO_PIN3 // CH3 Control GPIO +#define GPIO_PIN_CH4 EXIO_PIN4 // CH4 Control GPIO +#define GPIO_PIN_CH5 EXIO_PIN5 // CH5 Control GPIO +#define GPIO_PIN_CH6 EXIO_PIN6 // CH6 Control GPIO +#define GPIO_PIN_CH7 EXIO_PIN7 // CH7 Control GPIO +#define GPIO_PIN_CH8 EXIO_PIN8 // CH8 Control GPIO + + +#define CH1 '1' // CH1 Enabled Instruction Hex : 0x31 +#define CH2 '2' // CH2 Enabled Instruction Hex : 0x32 +#define CH3 '3' // CH3 Enabled Instruction Hex : 0x33 +#define CH4 '4' // CH4 Enabled Instruction Hex : 0x34 +#define CH5 '5' // CH5 Enabled Instruction Hex : 0x35 +#define CH6 '6' // CH6 Enabled Instruction Hex : 0x36 +#define CH7 '7' // CH5 Enabled Instruction Hex : 0x37 +#define CH8 '8' // CH6 Enabled Instruction Hex : 0x38 +#define ALL_ON '9' // Start all channel instructions Hex : 0x39 +#define ALL_OFF '0' // Disable all channel instructions Hex : 0x30 + +#define DIN_Mode 1 +#define RS485_Mode 2 // Used to distinguish data sources +#define Bluetooth_Mode 3 +#define WIFI_Mode 4 +#define MQTT_Mode 5 +#define RTC_Mode 6 + +typedef enum { + STATE_Closs = 0, // Closs Relay + STATE_Open = 1, // Open Relay + STATE_Retain = 2, // Stay in place +} Status_adjustment; + +extern bool Relay_Flag[8]; // Relay current status flag + +void Relay_Init(void); +bool Relay_Closs(uint8_t CHx); +bool Relay_Open(uint8_t CHx); +bool Relay_CHx_Toggle(uint8_t CHx); +bool Relay_CHx(uint8_t CHx, bool State); +bool Relay_CHxs_PinState(uint8_t PinState); + +void Relay_Analysis(uint8_t *buf,uint8_t Mode_Flag); +void Relay_Immediate(uint8_t CHx, bool State, uint8_t Mode_Flag); +void Relay_Immediate_CHxs(uint8_t PinState, uint8_t Mode_Flag); +void Relay_Immediate_CHxn(Status_adjustment * Relay_n, uint8_t Mode_Flag); diff --git a/src/WS_SD.cpp b/src/WS_SD.cpp new file mode 100644 index 0000000..5088639 --- /dev/null +++ b/src/WS_SD.cpp @@ -0,0 +1,113 @@ +#include "WS_SD.h" + +bool SDCard_Flag = 0; +bool SDCard_Finish = 0; + +uint16_t SDCard_Size = 0; +uint16_t Flash_Size = 0; + +void SD_Init() { + // SD MMC + if(!SD_MMC.setPins(SD_CLK_PIN, SD_CMD_PIN, SD_D0_PIN,-1,-1,-1)){ + printf("SD MMC: Pin change failed!\r\n"); + return; + } + if (SD_MMC.begin("/sdcard", true, true)) { // "/sdcard", true, true or "/sdcard", true, false + printf("SD card initialization successful!\r\n"); + } else { + printf("SD card initialization failed!\r\n"); + } + uint8_t cardType = SD_MMC.cardType(); + if(cardType == CARD_NONE){ + printf("No SD card attached\r\n"); + return; + } + else{ + printf("SD Card Type: "); + if(cardType == CARD_MMC){ + printf("MMC\r\n"); + } else if(cardType == CARD_SD){ + printf("SDSC\r\n"); + } else if(cardType == CARD_SDHC){ + printf("SDHC\r\n"); + } else { + printf("UNKNOWN\r\n"); + } + uint64_t totalBytes = SD_MMC.totalBytes(); + uint64_t usedBytes = SD_MMC.usedBytes(); + SDCard_Size = totalBytes/(1024*1024); + printf("Total space: %llu\n", totalBytes); + printf("Used space: %llu\n", usedBytes); + printf("Free space: %llu\n", totalBytes - usedBytes); + } +} +bool File_Search(const char* directory, const char* fileName) +{ + File Path = SD_MMC.open(directory); + if (!Path) { + printf("Path: <%s> does not exist\r\n",directory); + return false; + } + File file = Path.openNextFile(); + while (file) { + if (strcmp(file.name(), fileName) == 0) { + if (strcmp(directory, "/") == 0) + printf("File '%s%s' found in root directory.\r\n",directory,fileName); + else + printf("File '%s/%s' found in root directory.\r\n",directory,fileName); + Path.close(); + return true; + } + file = Path.openNextFile(); + } + if (strcmp(directory, "/") == 0) + printf("File '%s%s' not found in root directory.\r\n",directory,fileName); + else + printf("File '%s/%s' not found in root directory.\r\n",directory,fileName); + Path.close(); + return false; +} +uint16_t Folder_retrieval(const char* directory, const char* fileExtension, char File_Name[][100],uint16_t maxFiles) +{ + File Path = SD_MMC.open(directory); + if (!Path) { + printf("Path: <%s> does not exist\r\n",directory); + return false; + } + + uint16_t fileCount = 0; + char filePath[100]; + File file = Path.openNextFile(); + while (file && fileCount < maxFiles) { + if (!file.isDirectory() && strstr(file.name(), fileExtension)) { + strncpy(File_Name[fileCount], file.name(), sizeof(File_Name[fileCount])); + if (strcmp(directory, "/") == 0) { + snprintf(filePath, 100, "%s%s", directory, file.name()); + } else { + snprintf(filePath, 100, "%s/%s", directory, file.name()); + } + printf("File found: %s\r\n", filePath); + fileCount++; + } + file = Path.openNextFile(); + } + Path.close(); + if (fileCount > 0) { + printf("Retrieved %d mp3 files\r\n",fileCount); + return fileCount; + } else { + printf("No files with extension '%s' found in directory: %s\r\n", fileExtension, directory); + return 0; + } +} + +void Flash_test() +{ + printf("/********** RAM Test**********/\r\n"); + // Get Flash size + uint32_t flashSize = ESP.getFlashChipSize(); + Flash_Size = flashSize/1024/1024; + printf("Flash size: %d MB \r\n", flashSize/1024/1024); + + printf("/******* RAM Test Over********/\r\n\r\n"); +} \ No newline at end of file diff --git a/src/WS_SD.h b/src/WS_SD.h new file mode 100644 index 0000000..65d103b --- /dev/null +++ b/src/WS_SD.h @@ -0,0 +1,18 @@ +#pragma once +#include "Arduino.h" +#include +#include "FS.h" +#include "SD_MMC.h" + +#define SD_CLK_PIN 48 +#define SD_CMD_PIN 47 +#define SD_D0_PIN 45 + +extern uint16_t SDCard_Size; +extern uint16_t Flash_Size; + +void SD_Init(); +void Flash_test(); + +bool File_Search(const char* directory, const char* fileName); +uint16_t Folder_retrieval(const char* directory, const char* fileExtension, char File_Name[][100],uint16_t maxFiles); diff --git a/src/WS_Serial.cpp b/src/WS_Serial.cpp new file mode 100644 index 0000000..807c248 --- /dev/null +++ b/src/WS_Serial.cpp @@ -0,0 +1,8 @@ +#include "WS_Serial.h" +void Serial_Init() +{ + if(RS485_CAN_Enable) + RS485_Init(); + else + CAN_Init(); +} diff --git a/src/WS_Serial.h b/src/WS_Serial.h new file mode 100644 index 0000000..5ce9570 --- /dev/null +++ b/src/WS_Serial.h @@ -0,0 +1,8 @@ +#pragma once + +#include "WS_Information.h" +#include "WS_RS485.h" +#include "WS_CAN.h" + +void Serial_Init(); // Example Initialize the system serial port and RS485 +void Serial_Loop(); // Read RS485 data, parse and control relays diff --git a/src/WS_TCA9554PWR.cpp b/src/WS_TCA9554PWR.cpp new file mode 100644 index 0000000..4e2f154 --- /dev/null +++ b/src/WS_TCA9554PWR.cpp @@ -0,0 +1,107 @@ +#include "WS_TCA9554PWR.h" + +/***************************************************** Operation register REG ****************************************************/ +uint8_t Read_REG(uint8_t REG) // Read the value of the TCA9554PWR register REG +{ + Wire.beginTransmission(TCA9554_ADDRESS); + Wire.write(REG); + uint8_t result = Wire.endTransmission(); + if (result != 0) { + printf("Data Transfer Failure !!!\r\n"); + } + Wire.requestFrom(TCA9554_ADDRESS, 1); + uint8_t bitsStatus = Wire.read(); + return bitsStatus; +} +uint8_t Write_REG(uint8_t REG,uint8_t Data) // Write Data to the REG register of the TCA9554PWR +{ + Wire.beginTransmission(TCA9554_ADDRESS); + Wire.write(REG); + Wire.write(Data); + uint8_t result = Wire.endTransmission(); + if (result != 0) { + printf("Data write failure!!!\r\n"); + return -1; + } + return 0; +} +/********************************************************** Set EXIO mode **********************************************************/ +void Mode_EXIO(uint8_t Pin,uint8_t State) // Set the mode of the TCA9554PWR Pin. The default is Output mode (output mode or input mode). State: 0= Output mode 1= input mode +{ + uint8_t bitsStatus = Read_REG(TCA9554_CONFIG_REG); + uint8_t Data = (0x01 << (Pin-1)) | bitsStatus; + uint8_t result = Write_REG(TCA9554_CONFIG_REG,Data); + if (result != 0) { + printf("I/O Configuration Failure !!!\r\n"); + } +} +void Mode_EXIOS(uint8_t PinState) // Set the mode of the 7 pins from the TCA9554PWR with PinState +{ + uint8_t result = Write_REG(TCA9554_CONFIG_REG,PinState); + if (result != 0) { + printf("I/O Configuration Failure !!!\r\n"); + } +} +/********************************************************** Read EXIO status **********************************************************/ +uint8_t Read_EXIO(uint8_t Pin) // Read the level of the TCA9554PWR Pin +{ + uint8_t inputBits = Read_REG(TCA9554_INPUT_REG); + uint8_t bitStatus = (inputBits >> (Pin-1)) & 0x01; + return bitStatus; +} +uint8_t Read_EXIOS(uint8_t REG = TCA9554_INPUT_REG) // Read the level of all pins of TCA9554PWR, the default read input level state, want to get the current IO output state, pass the parameter TCA9554_OUTPUT_REG, such as Read_EXIOS(TCA9554_OUTPUT_REG); +{ + uint8_t inputBits = Read_REG(REG); + return inputBits; +} + +/********************************************************** Set the EXIO output status **********************************************************/ +bool Set_EXIO(uint8_t Pin,uint8_t State) // Sets the level state of the Pin without affecting the other pins +{ + uint8_t Data; + if(State < 2 && Pin < 9 && Pin > 0){ + uint8_t bitsStatus = Read_EXIOS(TCA9554_OUTPUT_REG); + if(State == 1) + Data = (0x01 << (Pin-1)) | bitsStatus; + else if(State == 0) + Data = (~(0x01 << (Pin-1))) & bitsStatus; + uint8_t result = Write_REG(TCA9554_OUTPUT_REG,Data); + if (result != 0) { + printf("Failed to set GPIO!!!\r\n"); + return 0; + } + return 1; + } + else + { + printf("Parameter error, please enter the correct parameter!\r\n"); + return 0; + } +} +bool Set_EXIOS(uint8_t PinState) // Set 7 pins to the PinState state such as :PinState=0x23, 0010 0011 state (the highest bit is not used) +{ + uint8_t result = Write_REG(TCA9554_OUTPUT_REG,PinState); + if (result != 0) { + printf("Failed to set GPIO!!!\r\n"); + return 0; + } + return 1; +} +/********************************************************** Flip EXIO state **********************************************************/ +bool Set_Toggle(uint8_t Pin) // Flip the level of the TCA9554PWR Pin +{ + uint8_t bitsStatus = Read_EXIO(Pin); + uint8_t result = Set_EXIO(Pin,(bool)!bitsStatus); + if (!result) { + printf("Failed to Toggle GPIO!!!\r\n"); + return 0; + } + return 1; +} +/********************************************************* TCA9554PWR Initializes the device ***********************************************************/ +void TCA9554PWR_Init(uint8_t PinMode, uint8_t PinState) // Set the seven pins to PinState state, for example :PinState=0x23, 0010 0011 State (Output mode or input mode) 0= Output mode 1= Input mode. The default value is output mode +{ + Set_EXIOS(PinState); + Mode_EXIOS(PinMode); +} + diff --git a/src/WS_TCA9554PWR.h b/src/WS_TCA9554PWR.h new file mode 100644 index 0000000..b8dfb6a --- /dev/null +++ b/src/WS_TCA9554PWR.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include "I2C_Driver.h" + +/****************************************************** The macro defines the TCA9554PWR information ******************************************************/ + +#define TCA9554_ADDRESS 0x20 // TCA9554PWR I2C address +#define TCA9554_INPUT_REG 0x00 // Input register,input level +#define TCA9554_OUTPUT_REG 0x01 // Output register, high and low level output +#define TCA9554_Polarity_REG 0x02 // The Polarity Inversion register (register 2) allows polarity inversion of pins defined as inputs by the Configuration register. +#define TCA9554_CONFIG_REG 0x03 // Configuration register, mode configuration + + +#define Low 0 +#define High 1 +#define EXIO_PIN1 1 +#define EXIO_PIN2 2 +#define EXIO_PIN3 3 +#define EXIO_PIN4 4 +#define EXIO_PIN5 5 +#define EXIO_PIN6 6 +#define EXIO_PIN7 7 +#define EXIO_PIN8 8 + +/***************************************************** Operation register REG ****************************************************/ +uint8_t Read_REG(uint8_t REG); // Read the value of the TCA9554PWR register REG +uint8_t Write_REG(uint8_t REG,uint8_t Data); // Write Data to the REG register of the TCA9554PWR +/********************************************************** Set EXIO mode **********************************************************/ +void Mode_EXIO(uint8_t Pin,uint8_t State); // Set the mode of the TCA9554PWR Pin. The default is Output mode (output mode or input mode). State: 0= Output mode 1= input mode +void Mode_EXIOS(uint8_t PinState); // Set the mode of the 7 pins from the TCA9554PWR with PinState +/********************************************************** Read EXIO status **********************************************************/ +uint8_t Read_EXIO(uint8_t Pin); // Read the level of the TCA9554PWR Pin +uint8_t Read_EXIOS(uint8_t REG); // Read the level of all pins of TCA9554PWR, the default read input level state, want to get the current IO output state, pass the parameter TCA9554_OUTPUT_REG, such as Read_EXIOS(TCA9554_OUTPUT_REG); +/********************************************************** Set the EXIO output status **********************************************************/ +bool Set_EXIO(uint8_t Pin,uint8_t State); // Sets the level state of the Pin without affecting the other pins +bool Set_EXIOS(uint8_t PinState); // Set 7 pins to the PinState state such as :PinState=0x23, 0010 0011 state (the highest bit is not used) +/********************************************************** Flip EXIO state **********************************************************/ +bool Set_Toggle(uint8_t Pin); // Flip the level of the TCA9554PWR Pin +/********************************************************* TCA9554PWR Initializes the device ***********************************************************/ +void TCA9554PWR_Init(uint8_t PinMode = 0x00, uint8_t PinState = 0x00); // Set the seven pins to PinState state, for example :PinState=0x23, 0010 0011 State (the highest bit is not used) (Output mode or input mode) 0= Output mode 1= Input mode. The default value is output mode diff --git a/test/README b/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html