diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index 60e6f2e..ab64b14 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -1,4 +1,4 @@ -name: Examples +name: CI Examples on: workflow_dispatch: # Manually start a workflow @@ -12,7 +12,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-22.04, windows-2022, macos-14] + os: [ubuntu-24.04, windows-2022, macos-15] example: - "examples/arduino-blink" - "examples/arduino-rmt-blink" @@ -23,6 +23,7 @@ jobs: - "examples/tasmota" - "examples/espidf-arduino-h2zero-BLE_scan" #- "examples/espidf-arduino-matter-light" + - "examples/arduino-matter-light" - "examples/espidf-arduino-blink" - "examples/espidf-arduino-littlefs" - "examples/espidf-blink" @@ -44,37 +45,16 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.11" - - name: Install Windows dependencies + python-version: "3.13" + - name: Install dependencies run: | python -m pip install --upgrade pip pip install wheel - pip install -U https://github.com/platformio/platformio/archive/develop.zip + pip install -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.17b2.zip pio pkg install --global --platform file://. - if: "matrix.os == 'windows-2022'" - env: - PLATFORMIO_CORE_DIR: C:\plat - PLATFORMIO_PACKAGES_DIR: C:\plat\pack - PLATFORMIO_PLATFORMS_DIR: C:\plat\plat - - name: Build Windows examples - run: pio run -d ${{ matrix.example }} - if: "matrix.example != 'examples/tasmota' && matrix.os == 'windows-2022'" - env: - PLATFORMIO_CORE_DIR: C:\plat - PLATFORMIO_PACKAGES_DIR: C:\plat\pack - PLATFORMIO_PLATFORMS_DIR: C:\plat\plat - - name: Install Ubuntu Mac dependencies - run: | - python -m pip install --upgrade pip - pip install wheel - pip install -U https://github.com/platformio/platformio/archive/develop.zip - pio pkg install --global --platform file://. - if: "matrix.os != 'windows-2022'" - name: git clone Tasmota and add to examples run: | git clone -b development --depth 1 https://github.com/arendst/Tasmota.git examples/tasmota cp examples/tasmota_platformio_override.ini examples/tasmota/platformio_override.ini - if: "matrix.example == 'examples/tasmota' && matrix.os != 'windows-2022'" - - name: Build Ubuntu Mac examples + - name: Build examples run: pio run -d ${{ matrix.example }} - if: "matrix.os != 'windows-2022'" diff --git a/README.md b/README.md index 8e67248..718d3aa 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ESP32 is a series of low-cost, low-power system on a chip microcontrollers with integrated Wi-Fi and Bluetooth. ESP32 integrates an antenna switch, RF balun, power amplifier, low-noise receive amplifier, filters, and power management modules. -* Issues with boards (wrong / missing). All issues caused from boards will **not** be fixed from the maintainer(s). A PR needs to be provided against branch `develop` to solve. +* Issues with boards (wrong / missing). All issues caused from boards will not be fixed from the maintainer(s). A PR needs to be provided against branch `develop` to solve. ## IDE Preparation @@ -19,8 +19,8 @@ ESP32 is a series of low-cost, low-power system on a chip microcontrollers with 1. Setup new VSCode pioarduino project. 1. Configure a platform option in platformio.ini file: -### Stable version -currently espressif Arduino 3.1.1 and IDF 5.3.2.241224 +### Stable Arduino +currently espressif Arduino 3.1.2 and IDF 5.3.2.250210 ```ini [env:stable] @@ -29,7 +29,7 @@ board = ... ... ``` -### Development version +### Development Arduino espressif Arduino repo branch master and latest compiled Arduino libs ```ini @@ -39,4 +39,21 @@ board = ... ... ``` +### ESP32-solo1 and ESP32-C2 Arduino support (with pioarduino only feature: *Hybrid compile*) +Example configuration: + +```ini +[env:esp32solo1] +platform = https://github.com/pioarduino/platform-espressif32.git#develop +framework = arduino +board = esp32-solo1 +monitor_speed = 115200 + +[env:esp32-c2-devkitm-1] +platform = https://github.com/pioarduino/platform-espressif32.git#develop +framework = arduino +board = esp32-c2-devkitm-1 +monitor_speed = 115200 +``` + Looking for sponsor button? There is none. If you want to donate, please spend a litte to a charity organization. diff --git a/boards/lolin_s3_mini.json b/boards/lolin_s3_mini.json index 7f55f0b..c68309a 100644 --- a/boards/lolin_s3_mini.json +++ b/boards/lolin_s3_mini.json @@ -1,18 +1,18 @@ { "build": { "arduino": { - "ldscript": "esp32s3_out.ld", "memory_type": "qio_qspi" }, "core": "esp32", "extra_flags": [ "-DBOARD_HAS_PSRAM", "-DARDUINO_LOLIN_S3_MINI", - "-DARDUINO_USB_MODE=1" + "-DARDUINO_USB_CDC_ON_BOOT=1" ], "f_cpu": "240000000L", "f_flash": "80000000L", "flash_mode": "qio", + "psram_type" : "qio", "hwids": [ [ "0x303A", diff --git a/boards/lolin_s3_mini_pro.json b/boards/lolin_s3_mini_pro.json new file mode 100644 index 0000000..3afcb49 --- /dev/null +++ b/boards/lolin_s3_mini_pro.json @@ -0,0 +1,47 @@ +{ + "build": { + "arduino": { + "memory_type": "qio_qspi" + }, + "core": "esp32", + "extra_flags": [ + "-DBOARD_HAS_PSRAM", + "-DARDUINO_LOLIN_S3_MINI_PRO", + "-DARDUINO_USB_CDC_ON_BOOT=1" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "psram_type" : "qio", + "hwids": [ + [ + "0x303A", + "0x8167" + ] + ], + "mcu": "esp32s3", + "variant": "lolin_s3_mini_pro" + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "WEMOS LOLIN S3 Mini Pro", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://www.wemos.cc/en/latest/s3/index.html", + "vendor": "WEMOS" +} + \ No newline at end of file diff --git a/boards/waveshare_esp32s3_touch_lcd_128.json b/boards/waveshare_esp32s3_touch_lcd_128.json new file mode 100644 index 0000000..d619940 --- /dev/null +++ b/boards/waveshare_esp32s3_touch_lcd_128.json @@ -0,0 +1,52 @@ +{ + "build": { + "arduino":{ + "memory_type": "qio_qspi", + "partitions": "default.csv" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_WAVESHARE_ESP32S3_TOUCH_LCD_128", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [ + [ + "0x1a86", + "0x55d3" + ] + ], + "mcu": "esp32s3", + "variant": "waveshare_esp32s3_touch_lcd_128" + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": [ + "esp-builtin" + ], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Waveshare ESP32-S3-Touch-LCD-1.28 (16 MB QD, 2MB PSRAM)", + "upload": { + "flash_size": "16MB", + "maximum_ram_size": 327680, + "maximum_size": 16777216, + "require_upload_port": true, + "speed": 921600 + }, + "url": "https://www.waveshare.com/wiki/ESP32-S3-Touch-LCD-1.28", + "vendor": "Waveshare" + } diff --git a/builder/frameworks/arduino.py b/builder/frameworks/arduino.py index b58527f..96fbff6 100644 --- a/builder/frameworks/arduino.py +++ b/builder/frameworks/arduino.py @@ -26,10 +26,12 @@ import subprocess import json import semantic_version import os +import sys import shutil from os.path import join from SCons.Script import COMMAND_LINE_TARGETS, DefaultEnvironment, SConscript +from platformio import fs from platformio.package.version import pepver_to_semver from platformio.project.config import ProjectConfig from platformio.package.manager.tool import ToolPackageManager @@ -43,6 +45,7 @@ mcu = board.get("build.mcu", "esp32") board_sdkconfig = board.get("espidf.custom_sdkconfig", "") entry_custom_sdkconfig = "\n" flag_custom_sdkconfig = False +IS_WINDOWS = sys.platform.startswith("win") if config.has_option("env:"+env["PIOENV"], "custom_sdkconfig"): entry_custom_sdkconfig = env.GetProjectOption("custom_sdkconfig") @@ -55,6 +58,8 @@ extra_flags = (''.join([element for element in board.get("build.extra_flags", "" framework_reinstall = False flag_any_custom_sdkconfig = False +FRAMEWORK_LIB_DIR = platform.get_package_dir("framework-arduinoespressif32-libs") + SConscript("_embed_files.py", exports="env") flag_any_custom_sdkconfig = os.path.exists(join(platform.get_package_dir("framework-arduinoespressif32-libs"),"sdkconfig")) @@ -171,11 +176,65 @@ def check_reinstall_frwrk(): framework_reinstall = True return framework_reinstall + +FRAMEWORK_SDK_DIR = fs.to_unix_path( + os.path.join( + FRAMEWORK_LIB_DIR, + mcu, + "include", + ) +) + +IS_INTEGRATION_DUMP = env.IsIntegrationDump() + + +def is_framework_subfolder(potential_subfolder): + if not os.path.isabs(potential_subfolder): + return False + if ( + os.path.splitdrive(FRAMEWORK_SDK_DIR)[0] + != os.path.splitdrive(potential_subfolder)[0] + ): + return False + return os.path.commonpath([FRAMEWORK_SDK_DIR]) == os.path.commonpath( + [FRAMEWORK_SDK_DIR, potential_subfolder] + ) + + +def shorthen_includes(env, node): + if IS_INTEGRATION_DUMP: + # Don't shorten include paths for IDE integrations + return node + + includes = [fs.to_unix_path(inc) for inc in env.get("CPPPATH", [])] + shortened_includes = [] + generic_includes = [] + for inc in includes: + if is_framework_subfolder(inc): + shortened_includes.append( + "-iwithprefix/" + + fs.to_unix_path(os.path.relpath(inc, FRAMEWORK_SDK_DIR)) + ) + else: + generic_includes.append(inc) + + return env.Object( + node, + CPPPATH=generic_includes, + CCFLAGS=env["CCFLAGS"] + + ["-iprefix", FRAMEWORK_SDK_DIR] + + shortened_includes, + ASFLAGS=env["ASFLAGS"] + + ["-iprefix", FRAMEWORK_SDK_DIR] + + shortened_includes, + ) + def call_compile_libs(): if mcu == "esp32c2": ARDUINO_FRMWRK_C2_LIB_DIR = join(platform.get_package_dir("framework-arduinoespressif32-libs"),mcu) - ARDUINO_C2_DIR = join(platform.get_package_dir("framework-arduino-c2-skeleton-lib"),mcu) - shutil.copytree(ARDUINO_C2_DIR, ARDUINO_FRMWRK_C2_LIB_DIR, dirs_exist_ok=True) + if not os.path.exists(ARDUINO_FRMWRK_C2_LIB_DIR): + ARDUINO_C2_DIR = join(platform.get_package_dir("framework-arduino-c2-skeleton-lib"),mcu) + shutil.copytree(ARDUINO_C2_DIR, ARDUINO_FRMWRK_C2_LIB_DIR, dirs_exist_ok=True) print("*** Compile Arduino IDF libs for %s ***" % env["PIOENV"]) SConscript("espidf.py") @@ -192,6 +251,8 @@ if flag_custom_sdkconfig == True and flag_any_custom_sdkconfig == False: call_compile_libs() if "arduino" in env.subst("$PIOFRAMEWORK") and "espidf" not in env.subst("$PIOFRAMEWORK") and env.subst("$ARDUINO_LIB_COMPILE_FLAG") in ("Inactive", "True"): + if IS_WINDOWS: + env.AddBuildMiddleware(shorthen_includes) if os.path.exists(join(platform.get_package_dir( "framework-arduinoespressif32"), "tools", "platformio-build.py")): PIO_BUILD = "platformio-build.py" diff --git a/builder/frameworks/espidf.py b/builder/frameworks/espidf.py index a1ff9c2..aa32f05 100644 --- a/builder/frameworks/espidf.py +++ b/builder/frameworks/espidf.py @@ -1585,11 +1585,37 @@ def get_idf_venv_dir(): def ensure_python_venv_available(): + def _get_idf_venv_python_version(): + try: + version = subprocess.check_output( + [ + get_python_exe(), + "-c", + "import sys;print('{0}.{1}.{2}-{3}.{4}'.format(*list(sys.version_info)))" + ], text=True + ) + return version.strip() + except subprocess.CalledProcessError as e: + print("Failed to extract Python version from IDF virtual env!") + return None + def _is_venv_outdated(venv_data_file): try: with open(venv_data_file, "r", encoding="utf8") as fp: venv_data = json.load(fp) if venv_data.get("version", "") != IDF_ENV_VERSION: + print( + "Warning! IDF virtual environment version changed!" + ) + return True + if ( + venv_data.get("python_version", "") + != _get_idf_venv_python_version() + ): + print( + "Warning! Python version in the IDF virtual environment" + " differs from the current Python!" + ) return True return False except: @@ -1604,7 +1630,7 @@ def ensure_python_venv_available(): if os.path.isdir(venv_dir): try: - print("Removing an oudated IDF virtual environment") + print("Removing an outdated IDF virtual environment") shutil.rmtree(venv_dir) except OSError: print( @@ -1629,8 +1655,12 @@ def ensure_python_venv_available(): venv_data_file = os.path.join(venv_dir, "pio-idf-venv.json") if not os.path.isfile(venv_data_file) or _is_venv_outdated(venv_data_file): _create_venv(venv_dir) + install_python_deps() with open(venv_data_file, "w", encoding="utf8") as fp: - venv_info = {"version": IDF_ENV_VERSION} + venv_info = { + "version": IDF_ENV_VERSION, + "python_version": _get_idf_venv_python_version() + } json.dump(venv_info, fp, indent=2) @@ -1649,11 +1679,10 @@ def get_python_exe(): # -# ESP-IDF requires Python packages with specific versions in a virtual environment +# Ensure Python environment contains everything required for IDF # ensure_python_venv_available() -install_python_deps() # ESP-IDF package doesn't contain .git folder, instead package version is specified # in a special file "version.h" in the root folder of the package @@ -1859,7 +1888,15 @@ libs = find_lib_deps( # Extra flags which need to be explicitly specified in LINKFLAGS section because SCons # cannot merge them correctly extra_flags = filter_args( - link_args["LINKFLAGS"], ["-T", "-u", "-Wl,--start-group", "-Wl,--end-group"] + link_args["LINKFLAGS"], + [ + "-T", + "-u", + "-Wl,--start-group", + "-Wl,--end-group", + "-Wl,--whole-archive", + "-Wl,--no-whole-archive", + ], ) link_args["LINKFLAGS"] = sorted(list(set(link_args["LINKFLAGS"]) - set(extra_flags))) @@ -2079,6 +2116,7 @@ if "arduino" in env.get("PIOFRAMEWORK") and "espidf" not in env.get("PIOFRAMEWOR shutil.move(join(lib_dst,"libfreertos.a"),join(mem_var,"libfreertos.a")) shutil.move(join(lib_dst,"libbootloader_support.a"),join(mem_var,"libbootloader_support.a")) shutil.move(join(lib_dst,"libesp_hw_support.a"),join(mem_var,"libesp_hw_support.a")) + shutil.move(join(lib_dst,"libesp_lcd.a"),join(mem_var,"libesp_lcd.a")) shutil.copyfile(sdkconfig_h_path,join(mem_var,"include","sdkconfig.h")) if not bool(os.path.isfile(join(arduino_libs,mcu,"sdkconfig.orig"))): diff --git a/examples/arduino-blink/platformio.ini b/examples/arduino-blink/platformio.ini index bd12d55..26bd6f1 100644 --- a/examples/arduino-blink/platformio.ini +++ b/examples/arduino-blink/platformio.ini @@ -31,7 +31,6 @@ platform = espressif32 framework = arduino board = esp32-c2-devkitm-1 monitor_speed = 115200 -custom_sdkconfig = 'CONFIG_IDF_TARGET="esp32c2"' custom_component_remove = espressif/esp_hosted espressif/esp_wifi_remote espressif/esp-dsp diff --git a/examples/arduino-matter-light/include/README b/examples/arduino-matter-light/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/examples/arduino-matter-light/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/examples/arduino-matter-light/lib/README b/examples/arduino-matter-light/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/examples/arduino-matter-light/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 executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, 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 + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/examples/arduino-matter-light/platformio.ini b/examples/arduino-matter-light/platformio.ini new file mode 100644 index 0000000..9c624da --- /dev/null +++ b/examples/arduino-matter-light/platformio.ini @@ -0,0 +1,17 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter, extra scripting +; Upload options: custom port, speed and extra flags +; Library options: dependencies, extra library storages +; +; Please visit documentation for the other options and examples +; http://docs.platformio.org/page/projectconf.html + + +[env:esp32-c6-devkitc-1] +platform = espressif32 +framework = arduino +board_build.partitions = huge_app.csv +build_flags = -DCHIP_HAVE_CONFIG_H +board = esp32-c6-devkitc-1 +monitor_speed = 115200 diff --git a/examples/arduino-matter-light/src/.gitignore b/examples/arduino-matter-light/src/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/examples/arduino-matter-light/src/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/examples/arduino-matter-light/src/MatterColorLight.ino b/examples/arduino-matter-light/src/MatterColorLight.ino new file mode 100644 index 0000000..dd1724f --- /dev/null +++ b/examples/arduino-matter-light/src/MatterColorLight.ino @@ -0,0 +1,180 @@ +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Matter Manager +#include +#include +#include + +// List of Matter Endpoints for this Node +// Color Light Endpoint +MatterColorLight ColorLight; + +// WiFi is manually set and started +const char *ssid = "your-ssid"; // Change this to your WiFi SSID +const char *password = "your-password"; // Change this to your WiFi password + +// it will keep last OnOff & HSV Color state stored, using Preferences +Preferences matterPref; +const char *onOffPrefKey = "OnOff"; +const char *hsvColorPrefKey = "HSV"; + +// set your board RGB LED pin here +#ifdef RGB_BUILTIN +const uint8_t ledPin = RGB_BUILTIN; +#else +const uint8_t ledPin = 2; // Set your pin here if your board has not defined LED_BUILTIN +#warning "Do not forget to set the RGB LED pin" +#endif + +// set your board USER BUTTON pin here +const uint8_t buttonPin = BOOT_PIN; // Set your pin here. Using BOOT Button. + +// Button control +uint32_t button_time_stamp = 0; // debouncing control +bool button_state = false; // false = released | true = pressed +const uint32_t debouceTime = 250; // button debouncing time (ms) +const uint32_t decommissioningTimeout = 5000; // keep the button pressed for 5s, or longer, to decommission + +// Set the RGB LED Light based on the current state of the Color Light +bool setLightState(bool state, espHsvColor_t colorHSV) { + + if (state) { +#ifdef RGB_BUILTIN + espRgbColor_t rgbColor = espHsvColorToRgbColor(colorHSV); + // set the RGB LED + rgbLedWrite(ledPin, rgbColor.r, rgbColor.g, rgbColor.b); +#else + // No Color RGB LED, just use the HSV value (brightness) to control the LED + analogWrite(ledPin, colorHSV.v); +#endif + } else { + digitalWrite(ledPin, LOW); + } + // store last HSV Color and OnOff state for when the Light is restarted / power goes off + matterPref.putBool(onOffPrefKey, state); + matterPref.putUInt(hsvColorPrefKey, colorHSV.h << 16 | colorHSV.s << 8 | colorHSV.v); + // This callback must return the success state to Matter core + return true; +} + +void setup() { + // Initialize the USER BUTTON (Boot button) GPIO that will act as a toggle switch + pinMode(buttonPin, INPUT_PULLUP); + // Initialize the LED (light) GPIO and Matter End Point + pinMode(ledPin, OUTPUT); + + Serial.begin(115200); + + // We start by connecting to a WiFi network + Serial.print("Connecting to "); + Serial.println(ssid); + // Manually connect to WiFi + WiFi.begin(ssid, password); + // Wait for connection + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println("\r\nWiFi connected"); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + delay(500); + + // Initialize Matter EndPoint + matterPref.begin("MatterPrefs", false); + // default OnOff state is ON if not stored before + bool lastOnOffState = matterPref.getBool(onOffPrefKey, true); + // default HSV color is blue HSV(169, 254, 254) + uint32_t prefHsvColor = matterPref.getUInt(hsvColorPrefKey, 169 << 16 | 254 << 8 | 254); + espHsvColor_t lastHsvColor = {uint8_t(prefHsvColor >> 16), uint8_t(prefHsvColor >> 8), uint8_t(prefHsvColor)}; + ColorLight.begin(lastOnOffState, lastHsvColor); + // set the callback function to handle the Light state change + ColorLight.onChange(setLightState); + + // lambda functions are used to set the attribute change callbacks + ColorLight.onChangeOnOff([](bool state) { + Serial.printf("Light OnOff changed to %s\r\n", state ? "ON" : "OFF"); + return true; + }); + ColorLight.onChangeColorHSV([](HsvColor_t hsvColor) { + Serial.printf("Light HSV Color changed to (%d,%d,%d)\r\n", hsvColor.h, hsvColor.s, hsvColor.v); + return true; + }); + + // Matter beginning - Last step, after all EndPoints are initialized + Matter.begin(); + // This may be a restart of a already commissioned Matter accessory + if (Matter.isDeviceCommissioned()) { + Serial.println("Matter Node is commissioned and connected to Wi-Fi. Ready for use."); + Serial.printf( + "Initial state: %s | RGB Color: (%d,%d,%d) \r\n", ColorLight ? "ON" : "OFF", ColorLight.getColorRGB().r, ColorLight.getColorRGB().g, + ColorLight.getColorRGB().b + ); + // configure the Light based on initial on-off state and its color + ColorLight.updateAccessory(); + } +} + +void loop() { + // Check Matter Light Commissioning state, which may change during execution of loop() + if (!Matter.isDeviceCommissioned()) { + Serial.println(""); + Serial.println("Matter Node is not commissioned yet."); + Serial.println("Initiate the device discovery in your Matter environment."); + Serial.println("Commission it to your Matter hub with the manual pairing code or QR code"); + Serial.printf("Manual pairing code: %s\r\n", Matter.getManualPairingCode().c_str()); + Serial.printf("QR code URL: %s\r\n", Matter.getOnboardingQRCodeUrl().c_str()); + // waits for Matter Light Commissioning. + uint32_t timeCount = 0; + while (!Matter.isDeviceCommissioned()) { + delay(100); + if ((timeCount++ % 50) == 0) { // 50*100ms = 5 sec + Serial.println("Matter Node not commissioned yet. Waiting for commissioning."); + } + } + Serial.printf( + "Initial state: %s | RGB Color: (%d,%d,%d) \r\n", ColorLight ? "ON" : "OFF", ColorLight.getColorRGB().r, ColorLight.getColorRGB().g, + ColorLight.getColorRGB().b + ); + // configure the Light based on initial on-off state and its color + ColorLight.updateAccessory(); + Serial.println("Matter Node is commissioned and connected to Wi-Fi. Ready for use."); + } + + // A button is also used to control the light + // Check if the button has been pressed + if (digitalRead(buttonPin) == LOW && !button_state) { + // deals with button debouncing + button_time_stamp = millis(); // record the time while the button is pressed. + button_state = true; // pressed. + } + + // Onboard User Button is used as a Light toggle switch or to decommission it + uint32_t time_diff = millis() - button_time_stamp; + if (digitalRead(buttonPin) == HIGH && button_state && time_diff > debouceTime) { + // Toggle button is released - toggle the light + Serial.println("User button released. Toggling Light!"); + ColorLight.toggle(); // Matter Controller also can see the change + button_state = false; // released + } + + // Onboard User Button is kept pressed for longer than 5 seconds in order to decommission matter node + if (button_state && time_diff > decommissioningTimeout) { + Serial.println("Decommissioning the Light Matter Accessory. It shall be commissioned again."); + ColorLight = false; // turn the light off + Matter.decommission(); + button_time_stamp = millis(); // avoid running decommissining again, reboot takes a second or so + } +} diff --git a/examples/arduino-matter-light/test/README b/examples/arduino-matter-light/test/README new file mode 100644 index 0000000..df5066e --- /dev/null +++ b/examples/arduino-matter-light/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PIO Unit Testing 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 PIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html diff --git a/platform.json b/platform.json index d0378a7..5989566 100644 --- a/platform.json +++ b/platform.json @@ -18,7 +18,7 @@ "type": "git", "url": "https://github.com/pioarduino/platform-espressif32.git" }, - "version": "53.03.11", + "version": "53.03.12", "frameworks": { "arduino": { "script": "builder/frameworks/arduino.py" @@ -33,13 +33,13 @@ "type": "framework", "optional": true, "owner": "espressif", - "version": "https://github.com/espressif/arduino-esp32/releases/download/3.1.1/esp32-3.1.1.zip" + "version": "https://github.com/espressif/arduino-esp32/releases/download/3.1.2/esp32-3.1.2.zip" }, "framework-arduinoespressif32-libs": { "type": "framework", "optional": true, "owner": "espressif", - "version": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-cfea4f7c-v1.zip" + "version": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip" }, "framework-arduino-c2-skeleton-lib": { "type": "framework", @@ -51,7 +51,7 @@ "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.2.241224/esp-idf-v5.3.2.zip" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.3.2.250210/esp-idf-v5.3.2.zip" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", @@ -86,7 +86,7 @@ "tool-esptoolpy": { "type": "uploader", "owner": "pioarduino", - "version": "https://github.com/pioarduino/esptool/releases/download/v4.8.5/esptool.zip" + "version": "https://github.com/pioarduino/esptool/releases/download/v4.8.6/esptool.zip" }, "tool-dfuutil-arduino": { "type": "uploader", @@ -117,10 +117,25 @@ "owner": "platformio", "version": "~2.230.0" }, + "tool-cppcheck": { + "optional": true, + "owner": "platformio", + "version": "~1.21100" + }, + "tool-clangtidy": { + "optional": true, + "owner": "platformio", + "version": "^1.190100.0" + }, + "tool-pvs-studio": { + "optional": true, + "owner": "platformio", + "version": "^7.18.59866" + }, "tool-cmake": { "optional": true, "owner": "platformio", - "version": "~3.21.0" + "version": "~3.30.2" }, "tool-ninja": { "optional": true, diff --git a/platform.py b/platform.py index 625a98d..e1b3273 100644 --- a/platform.py +++ b/platform.py @@ -53,6 +53,11 @@ class Espressif32Platform(PlatformBase): if mcu == "esp32c2": self.packages["framework-arduino-c2-skeleton-lib"]["optional"] = False + # Enable check tools only when "check_tool" is active + for p in self.packages: + if p in ("tool-cppcheck", "tool-clangtidy", "tool-pvs-studio"): + self.packages[p]["optional"] = False if str(variables.get("check_tool")).strip("['']") in p else True + if "buildfs" in targets: filesystem = variables.get("board_build.filesystem", "littlefs") if filesystem == "littlefs":