From 9e67714d20be71ef7ff5bc805df0705a62d4c6e1 Mon Sep 17 00:00:00 2001 From: Khoi Hoang <57012152+khoih-prog@users.noreply.github.com> Date: Mon, 19 Apr 2021 04:07:53 -0400 Subject: [PATCH] Major Releases v1.3.0 ### Major Releases v1.3.0 1. Add **LittleFS and SPIFFS** support to new **ESP32-S2** boards (**Arduino ESP32C3_DEV**). Check [HOWTO Install esp32 core for ESP32-S2 (Saola, AI-Thinker ESP-12K) and ESP32-C3 boards into Arduino IDE](#howto-install-esp32-core-for-esp32-s2-saola-ai-thinker-esp-12k-and-esp32-c3-boards-into-arduino-ide). 2. Add **EEPROM and SPIFFS** support to new **ESP32-C3** boards (**Arduino ESP32C3_DEV**). Check [HOWTO Install esp32 core for ESP32-S2 (Saola, AI-Thinker ESP-12K) and ESP32-C3 boards into Arduino IDE](#howto-install-esp32-core-for-esp32-s2-saola-ai-thinker-esp-12k-and-esp32-c3-boards-into-arduino-ide). 3. Fix SSL issue with Blynk Cloud Server 4. Update examples --- README.md | 339 +++++++++++++++--- .../AM2315_ESP32_SSL/AM2315_ESP32_SSL.ino | 4 +- examples/AM2315_ESP32_SSL/defines.h | 31 +- examples/AM2315_ESP8266/AM2315_ESP8266.ino | 4 +- .../Blynk_WM_Template/Blynk_WM_Template.ino | 37 +- examples/DHT11ESP32/DHT11ESP32.ino | 6 +- examples/DHT11ESP32/defines.h | 31 +- examples/DHT11ESP32_SSL/DHT11ESP32_SSL.ino | 6 +- examples/DHT11ESP32_SSL/defines.h | 31 +- examples/DHT11ESP8266/DHT11ESP8266.ino | 6 +- .../DHT11ESP8266_Debug/DHT11ESP8266_Debug.ino | 6 +- .../DHT11ESP8266_SSL/DHT11ESP8266_SSL.ino | 6 +- examples/ESP32WM_Config/ESP32WM_Config.ino | 6 +- examples/ESP32WM_Config/defines.h | 32 +- .../ESP32WM_ForcedConfig.ino | 6 +- examples/ESP32WM_ForcedConfig/defines.h | 31 +- .../ESP32WM_MRD_Config/ESP32WM_MRD_Config.ino | 10 +- examples/ESP32WM_MRD_Config/defines.h | 31 +- .../ESP32WM_MRD_ForcedConfig.ino | 6 +- examples/ESP32WM_MRD_ForcedConfig/defines.h | 32 +- .../ESP8266WM_Config/ESP8266WM_Config.ino | 6 +- examples/ESP8266WM_Config/defines.h | 28 +- .../ESP8266WM_ForcedConfig.ino | 6 +- .../ESP8266WM_MRD_Config.ino | 6 +- .../ESP8266WM_MRD_ForcedConfig.ino | 7 +- pics/Blynk_ESP32_C3_Support.png | Bin 0 -> 99560 bytes src/BlynkSimpleEsp32_SSL_WM.h | 14 +- src/BlynkSimpleEsp32_WM.h | 6 +- src/BlynkSimpleEsp8266_SSL_WM.h | 23 +- src/BlynkSimpleEsp8266_WM.h | 6 +- 30 files changed, 623 insertions(+), 140 deletions(-) create mode 100644 pics/Blynk_ESP32_C3_Support.png diff --git a/README.md b/README.md index f9f28dc..fa2ddb4 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ * [Features](#features) * [Currently supported Boards](#currently-supported-boards) * [Changelog](#changelog) + * [Major Releases v1.3.0](#major-releases-v130) * [Major Releases v1.2.0](#major-releases-v120) * [Releases v1.1.3](#releases-v113) * [Releases v1.1.2](#releases-v112) @@ -34,21 +35,23 @@ * [Installation](#installation) * [I) For Arduino IDE](#i-for-arduino-ide) * [II) For VS Code & PlatformIO:](#ii-for-vs-code--platformio) -* [HOWTO Install esp32-s2 core for ESP32-S2 (Saola, AI-Thinker ESP-12K) boards into Arduino IDE)](#howto-install-esp32-s2-core-for-esp32-s2-saola-ai-thinker-esp-12k-boards-into-arduino-ide) +* [HOWTO Install esp32 core for ESP32-S2 (Saola, AI-Thinker ESP-12K) and ESP32-C3 boards into Arduino IDE](#howto-install-esp32-core-for-esp32-s2-saola-ai-thinker-esp-12k-and-esp32-c3-boards-into-arduino-ide) * [1. Save the original esp32 core](#1-save-the-original-esp32-core) - * [2. Download esp32-s2 core](#2-download-esp32-s2-core) - * [2.1 Download zip](#21-download-zip) - * [2.2 Unzip](#22-unzip) - * [2.3 Update esp32-s2 core directories](#23-update-esp32-s2-core-directories) - * [3. Download tools](#3-download-tools) + * [2. Install esp32 core v1.0.6](#2-install-esp32-core-v106) + * [2.1 Install esp32 core](#21-install-esp32-core) + * [2.2 Download latest zip with esp32-s2 support](#22-download-latest-zip-with-esp32-s2-support) + * [2.3 Unzip](#23-unzip) + * [2.3 Update esp32 core directories](#24-update-esp32-core-directories) + * [3. Download tools for ESP32-S2](#3-download-tools-for-esp32-s2) * [3.1 Download Toolchain for Xtensa (ESP32-S2) based on GCC](#31-download-toolchain-for-xtensa-esp32-s2-based-on-gcc) * [3.2 Download esptool](#32-download-esptool) * [3.3 Unzip](#33-unzip) * [4. Update tools](#4-update-tools) * [4.1 Update Toolchain](#41-update-toolchain) * [4.2 Update esptool](#42-update-esptool) - * [5. esp32-s2 WebServer Library Patch](#5-esp32-s2-webserver-library-patch) -* [Note for Platform IO using ESP32 LittleFS](#note-for-platform-io-using-esp32-littlefs) + * [5. Download tools for ESP32-C3](#5-download-tools-for-esp32-c3) + * [6. esp32-s2 WebServer Library Patch](#6-esp32-s2-webserver-library-patch) +* [Note for Platform IO using ESP32 LittleFS](#note-for-platform-io-using-esp32-littlefs) * [HOWTO Use analogRead() with ESP32 running WiFi and/or BlueTooth (BT/BLE)](#howto-use-analogread-with-esp32-running-wifi-andor-bluetooth-btble) * [1. ESP32 has 2 ADCs, named ADC1 and ADC2](#1--esp32-has-2-adcs-named-adc1-and-adc2) * [2. ESP32 ADCs functions](#2-esp32-adcs-functions) @@ -106,6 +109,8 @@ * [6. ESP8266WM_MRD_ForcedConfig using persistent ConfigPortal virtual button](#6-esp8266wm_mrd_forcedconfig-using-persistent-configportal-virtual-button) * [6.1. Start normally then press persistent ConfigPortal virtual button](#61-start-normally-then-press-persistent-configportal-virtual-button) * [6.2. Enter persistent ConfigPortal](#62-enter-persistent-configportal) + * [7. ESP8266WM_MRD_ForcedConfig using LITTLEFS with SSL on ESP8266_NODEMCU](#7-esp8266wm_mrd_forcedconfig-using-littlefs-with-ssl-on-esp8266_nodemcu) + * [8. ESP32WM_MRD_Config using LITTLEFS with SSL on ESP32S2_DEV](#8-esp32wm_mrd_config-using-littlefs-with-ssl-on-esp32s2_dev) * [Debug](#debug) * [Troubleshooting](#troubleshooting) * [Releases](#releases) @@ -183,6 +188,13 @@ This [**BlynkESP32_BT_WF** library](https://github.com/khoih-prog/BlynkESP32_BT_ ## Changelog +### Major Releases v1.3.0 + +1. Add **LittleFS and SPIFFS** support to new **ESP32-S2** boards (**Arduino ESP32C3_DEV**). Check [HOWTO Install esp32 core for ESP32-S2 (Saola, AI-Thinker ESP-12K) and ESP32-C3 boards into Arduino IDE](#howto-install-esp32-core-for-esp32-s2-saola-ai-thinker-esp-12k-and-esp32-c3-boards-into-arduino-ide). +2. Add **EEPROM and SPIFFS** support to new **ESP32-C3** boards (**Arduino ESP32C3_DEV**). Check [HOWTO Install esp32 core for ESP32-S2 (Saola, AI-Thinker ESP-12K) and ESP32-C3 boards into Arduino IDE](#howto-install-esp32-core-for-esp32-s2-saola-ai-thinker-esp-12k-and-esp32-c3-boards-into-arduino-ide). +3. Fix SSL issue with Blynk Cloud Server +4. Update examples + ### Major Releases v1.2.0 1. Configurable **Customs HTML Headers**, including Customs Style, Customs Head Elements, CORS Header. @@ -264,12 +276,12 @@ Thanks to [Thor Johnson](https://github.com/thorathome) to test, suggest and enc 1. [`Arduino IDE 1.8.13+`](https://www.arduino.cc/en/Main/Software) 2. [`Blynk library 0.6.1+`](https://github.com/blynkkk/blynk-library/releases). [![Latest release](https://img.shields.io/github/release/blynkkk/blynk-library.svg)](https://github.com/blynkkk/blynk-library/releases/latest/) -3. [`ESP32 Core 1.0.5+`](https://github.com/espressif/arduino-esp32) for ESP32-based boards. [![Latest release](https://img.shields.io/github/release/espressif/arduino-esp32.svg)](https://github.com/espressif/arduino-esp32/releases/latest/) -4. [`ESP32S2 Core 1.0.5+`](https://github.com/espressif/arduino-esp32/tree/esp32s2) for ESP32S2-based boards. +3. [`ESP32 Core 1.0.6+`](https://github.com/espressif/arduino-esp32) for ESP32-based boards. [![Latest release](https://img.shields.io/github/release/espressif/arduino-esp32.svg)](https://github.com/espressif/arduino-esp32/releases/latest/) +4. [`ESP32-S2/C3 Core 1.0.6+`](https://github.com/espressif/arduino-esp32) for ESP32-S2/C3-based boards. Must follow [HOWTO Install esp32 core for ESP32-S2 (Saola, AI-Thinker ESP-12K) and ESP32-C3 boards into Arduino IDE](#howto-install-esp32-core-for-esp32-s2-saola-ai-thinker-esp-12k-and-esp32-c3-boards-into-arduino-ide). 5. [`ESP8266 Core 2.7.4+`](https://github.com/esp8266/Arduino) for ESP8266-based boards. [![Latest release](https://img.shields.io/github/release/esp8266/Arduino.svg)](https://github.com/esp8266/Arduino/releases/latest/). To use ESP8266 core 2.7.1+ for LittleFS. 6. [`ESP_DoubleResetDetector library 1.1.1+`](https://github.com/khoih-prog/ESP_DoubleResetDetector) to use DRD feature. To install, check [![arduino-library-badge](https://www.ardu-badge.com/badge/ESP_DoubleResetDetector.svg?)](https://www.ardu-badge.com/ESP_DoubleResetDetector). 7. [`ESP_MultiResetDetector library 1.1.1+`](https://github.com/khoih-prog/ESP_MultiResetDetector) to use MRD feature. To install, check [![arduino-library-badge](https://www.ardu-badge.com/badge/ESP_MultiResetDetector.svg?)](https://www.ardu-badge.com/ESP_MultiResetDetector). -8. [`LittleFS_esp32 v1.0.5+`](https://github.com/lorol/LITTLEFS) for ESP32-based boards using LittleFS. To install, check [![arduino-library-badge](https://www.ardu-badge.com/badge/LittleFS_esp32.svg?)](https://www.ardu-badge.com/LittleFS_esp32). +8. [`LittleFS_esp32 v1.0.6+`](https://github.com/lorol/LITTLEFS) for ESP32-based boards using LittleFS. To install, check [![arduino-library-badge](https://www.ardu-badge.com/badge/LittleFS_esp32.svg?)](https://www.ardu-badge.com/LittleFS_esp32). --- @@ -318,7 +330,7 @@ Thanks to [Thor Johnson](https://github.com/thorathome) to test, suggest and enc --- --- -## HOWTO Install esp32-s2 core for ESP32-S2 (Saola, AI-Thinker ESP-12K) boards into Arduino IDE +## HOWTO Install esp32 core for ESP32-S2 (Saola, AI-Thinker ESP-12K) and ESP32-C3 boards into Arduino IDE These are instructions demonstrating the steps to install esp32-s2 core on Ubuntu machines. For Windows or other OS'es, just follow the the similar principles and steps. @@ -336,27 +348,32 @@ First, copy the whole original esp32 core to another safe place. Then delete all --- -### 2. Download esp32-s2 core -#### 2.1 Download zip +### 2. Install esp32 core v1.0.6 + +#### 2.1 Install esp32 core + +Just use Arduino IDE Board Manager to install [ESP32 Arduino Release 1.0.6 based on ESP-IDF v3.3.5](https://github.com/espressif/arduino-esp32/releases/tag/1.0.6). This official v1.06 core doesn't have esp32-s2/s3 support. You have to download and use the latest master branch. -Download [**esp32-s2 core**](https://github.com/espressif/arduino-esp32/tree/esp32s2) in the `zip` format: -`arduino-esp32-esp32s2.zip` +#### 2.2 Download latest zip with esp32-s2 support -#### 2.2 Unzip +As of **April 16th 2021**, the **esp32-s2/c3** board support has been included in master branch of esp32 core. Download [**esp32 core, master branch**](https://github.com/espressif/arduino-esp32) in the zip format. + +#### 2.3 Unzip

-#### 2.3 Update esp32-s2 core directories +#### 2.4 Update esp32 core directories + +Copy all subdirectories of esp32 core into `/home/your_account/.arduino15/packages/esp32/hardware/esp32/1.0.6` -Copy all subdirectories of esp32-s2 core into `/home/your_account/.arduino15/packages/esp32/hardware/esp32/1.0.4` --- -### 3 Download tools +### 3 Download tools for ESP32-S2 #### 3.1 Download Toolchain for Xtensa (ESP32-S2) based on GCC @@ -389,7 +406,7 @@ Download [esptool](https://github.com/espressif/esptool/releases) int the `zip` #### 4.1 Update Toolchain -Copy whole `xtensa-esp32s2-elf` directory into `/home/your_account/.arduino15/packages/esp32/hardware/esp32/1.0.4/tools` +Copy whole `xtensa-esp32s2-elf` directory into `/home/your_account/.arduino15/packages/esp32/hardware/esp32/1.0.6/tools` #### 4.2 Update esptool @@ -397,7 +414,7 @@ Copy whole `xtensa-esp32s2-elf` directory into `/home/your_account/.arduino15/pa Rename `esptool-3.0` directory to `esptool` -Copy whole `esptool` directory into `/home/your_account/.arduino15/packages/esp32/hardware/esp32/1.0.4/tools` +Copy whole `esptool` directory into `/home/your_account/.arduino15/packages/esp32/hardware/esp32/1.0.6/tools`

@@ -405,7 +422,32 @@ Copy whole `esptool` directory into `/home/your_account/.arduino15/packages/esp3

-### 5. esp32-s2 WebServer Library Patch +### 5 Download tools for ESP32-C3 + +Download [**esp32-c3 Toolchain**](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-guides/tools/idf-tools.html#riscv32-esp-elf) corresponding to your environment (linux-amd64, win64, etc.). + +For example`riscv32-esp-elf-gcc8_4_0-crosstool-ng-1.24.0-123-g64eb9ff-linux-amd64.tar.gz`, then un-archive. + +Then using the similar steps as in + +* [3. Download tools for ESP32-S2](#3-download-tools-for-esp32-s2) + * [3.1 Download Toolchain for Xtensa (ESP32-S2) based on GCC](#31-download-toolchain-for-xtensa-esp32-s2-based-on-gcc) + * [3.2 Download esptool](#32-download-esptool) + * [3.3 Unzip](#33-unzip) +* [4. Update tools](#4-update-tools) + * [4.1 Update Toolchain](#41-update-toolchain) + * [4.2 Update esptool](#42-update-esptool) + +then copy whole `riscv32-esp-elf` directory into `/home/your_account/.arduino15/packages/esp32/hardware/esp32/1.0.6/tools` + +

+ +

+ + +### 6. esp32-s2 WebServer Library Patch + +#### Necessary only for esp32 core v1.0.6- If you haven't installed a new version with [WebServer.handleClient delay PR #4350](https://github.com/espressif/arduino-esp32/pull/4350) or haven't applied the above mentioned PR, you have to use the following patch. @@ -420,13 +462,17 @@ Supposing the esp32-s2 version is 1.0.4, these files `WebServer.h/cpp` must be c --- -That's it. You're now ready to compile and test for ESP32-S2 now +That's it. You're now ready to compile and test for **ESP32-S2 and ESP32-C3** now --- --- ### Note for Platform IO using ESP32 LittleFS +#### Necessary only for esp32 core v1.0.6- + +From esp32 core v1.0.6+, [`LittleFS_esp32 v1.0.6`](https://github.com/lorol/LITTLEFS) has been included and this step is not necessary anymore. + In Platform IO, to fix the error when using [`LittleFS_esp32 v1.0`](https://github.com/lorol/LITTLEFS) for ESP32-based boards with ESP32 core v1.0.4- (ESP-IDF v3.2-), uncomment the following line from @@ -932,7 +978,7 @@ Then click **Save**. The system will auto-restart. You will see the board's buil #include "dynamicParams.h" #include -#include +#include // https://github.com/adafruit/DHT-sensor-library DHT dht(DHT_PIN, DHT_TYPE); BlynkTimer timer; @@ -1184,13 +1230,34 @@ void loop() #### 2. File [defines.h](examples/ESP32WM_MRD_ForcedConfig/defines.h) ```cpp +/* + // To add something similar to this for ESP32-C3 + #if CONFIG_IDF_TARGET_ESP32 + const int8_t esp32_adc2gpio[20] = {36, 37, 38, 39, 32, 33, 34, 35, -1, -1, 4, 0, 2, 15, 13, 12, 14, 27, 25, 26}; + #elif CONFIG_IDF_TARGET_ESP32S2 + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #elif CONFIG_IDF_TARGET_ESP32C3 + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #endif + */ + #ifndef defines_h #define defines_h -#ifndef ESP32 +#if !( defined(ESP32) ) #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting. +#elif ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_ESP32S2_THING_PLUS || ARDUINO_MICROS2 || \ + ARDUINO_METRO_ESP32S2 || ARDUINO_MAGTAG29_ESP32S2 || ARDUINO_FUNHOUSE_ESP32S2 || \ + ARDUINO_ADAFRUIT_FEATHER_ESP32S2_NOPSRAM ) + #define BOARD_TYPE "ESP32-S2" +#elif ( ARDUINO_ESP32C3_DEV ) + // https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-gpio.c + #warning ESP32-C3 boards not fully supported yet. Only SPIFFS and EEPROM OK. Tempo esp32_adc2gpio to be replaced + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #define BOARD_TYPE "ESP32-C3" +#else + #define BOARD_TYPE "ESP32" #endif - #define BLYNK_PRINT Serial #define BLYNK_WM_DEBUG 3 @@ -1235,11 +1302,10 @@ void loop() // (USE_LITTLEFS == false) and (USE_SPIFFS == true) => using SPIFFS for configuration data in WiFiManager // Those above #define's must be placed before #include -#if ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_PROS2 || ARDUINO_MICROS2 ) - // Currently, ESP32-S2 only supporting EEPROM. Will fix to support LittleFS and SPIFFS +#if ( ARDUINO_ESP32C3_DEV ) + // Currently, ESP32-C3 only supporting SPIFFS and EEPROM. Will fix to support LittleFS #define USE_LITTLEFS false - #define USE_SPIFFS false - #warning ESP32-S2 only support supporting EEPROM now. + #define USE_SPIFFS true #else #define USE_LITTLEFS true #define USE_SPIFFS false @@ -1462,7 +1528,7 @@ The following is the sample terminal output when running example [ESP8266WM_MRD_ ``` Starting ESP8266WM_MRD_Config using LittleFS with SSL on ESP8266_NODEMCU -Blynk_WM SSL for ESP8266 v1.2.0 +Blynk_WM SSL for ESP8266 v1.3.0 ESP_MultiResetDetector v1.1.1 LittleFS Flag read = 0xFFFD0002 multiResetDetectorFlag = 0xFFFD0002 @@ -1542,7 +1608,7 @@ BBBBBB ``` Starting ESP8266WM_MRD_Config using LittleFS with SSL on ESP8266_NODEMCU -Blynk_WM SSL for ESP8266 v1.2.0 +Blynk_WM SSL for ESP8266 v1.3.0 ESP_MultiResetDetector v1.1.1 LittleFS Flag read = 0xFFFC0003 multiResetDetectorFlag = 0xFFFC0003 @@ -1604,7 +1670,7 @@ The following is the sample terminal output when running example [DHT11ESP8266_S ``` Starting DHT11ESP8266_SSL using LittleFS with SSL on ESP8266_NODEMCU -Blynk_WM SSL for ESP8266 v1.2.0 +Blynk_WM SSL for ESP8266 v1.3.0 ESP_DoubleResetDetector v1.1.1 [293] Hostname=ESP8266-DHT11-SSL [316] LoadCfgFile @@ -1662,7 +1728,7 @@ The following is the sample terminal output when running example [ESP32WM_MRD_Co ``` Starting ESP32WM_MRD_Config using LITTLEFS without SSL on ESP32_DEV -Blynk_WM for ESP32 v1.2.0 +Blynk_WM for ESP32 v1.3.0 ESP_MultiResetDetector v1.1.1 LittleFS Flag read = 0xFFFE0001 multiResetDetectorFlag = 0xFFFE0001 @@ -1739,7 +1805,7 @@ BBBBBB ``` Starting ESP32WM_MRD_Config using LITTLEFS without SSL on ESP32_DEV -Blynk_WM for ESP32 v1.2.0 +Blynk_WM for ESP32 v1.3.0 ESP_MultiResetDetector v1.1.1 LittleFS Flag read = 0xFFFC0003 multiResetDetectorFlag = 0xFFFC0003 @@ -1797,7 +1863,7 @@ ets Jun 8 2016 00:22:57 ``` Starting ESP32WM_MRD_Config using LITTLEFS without SSL on ESP32_DEV -Blynk_WM for ESP32 v1.2.0 +Blynk_WM for ESP32 v1.3.0 ESP_MultiResetDetector v1.1.1 LittleFS Flag read = 0xFFFE0001 multiResetDetectorFlag = 0xFFFE0001 @@ -1921,7 +1987,7 @@ The following is the sample terminal output when running example [DHT11ESP8266_S ``` Starting DHT11ESP32_SSL using LITTLEFS with SSL on ESP32_DEV -Blynk_WM SSL for ESP32 v1.2.0 +Blynk_WM SSL for ESP32 v1.3.0 ESP_DoubleResetDetector v1.1.1 [346] Hostname=ESP32-DHT11-SSL [385] LoadCfgFile @@ -1985,7 +2051,7 @@ Blynk.resetAndEnterConfigPortal(); ``` Starting ESP8266WM_MRD_ForcedConfig using LittleFS without SSL on ESP8266_NODEMCU -Blynk_WM for ESP8266 v1.2.0 +Blynk_WM for ESP8266 v1.3.0 ESP_MultiResetDetector v1.1.1 LittleFS Flag read = 0xFFFE0001 multiResetDetectorFlag = 0xFFFE0001 @@ -2071,7 +2137,7 @@ Non-Persistent CP will be removed after first reset, even you didn't enter the C ``` Starting ESP8266WM_MRD_ForcedConfig using LittleFS without SSL on ESP8266_NODEMCU -Blynk_WM for ESP8266 v1.2.0 +Blynk_WM for ESP8266 v1.3.0 ESP_MultiResetDetector v1.1.1 LittleFS Flag read = 0xFFFE0001 multiResetDetectorFlag = 0xFFFE0001 @@ -2153,7 +2219,7 @@ Blynk.resetAndEnterConfigPortalPersistent(); ``` Starting ESP8266WM_MRD_ForcedConfig using LittleFS without SSL on ESP8266_NODEMCU -Blynk_WM for ESP8266 v1.2.0 +Blynk_WM for ESP8266 v1.3.0 ESP_MultiResetDetector v1.1.1 LittleFS Flag read = 0xFFFE0001 multiResetDetectorFlag = 0xFFFE0001 @@ -2240,7 +2306,7 @@ Persistent CP will remain after resets. The only way to get rid of Config Portal ``` Starting ESP8266WM_MRD_ForcedConfig using LittleFS without SSL on ESP8266_NODEMCU -Blynk_WM for ESP8266 v1.2.0 +Blynk_WM for ESP8266 v1.3.0 ESP_MultiResetDetector v1.1.1 LittleFS Flag read = 0xFFFE0001 multiResetDetectorFlag = 0xFFFE0001 @@ -2300,6 +2366,182 @@ Saving config file OK ``` +--- + +### 7. ESP8266WM_MRD_ForcedConfig using LITTLEFS with SSL on ESP8266_NODEMCU + +The following is the sample terminal output when running example [ESP8266WM_MRD_ForcedConfig](examples/ESP8266WM_MRD_ForcedConfig) on **ESP8266_NODEMCU**. Please note that this fix the SSL issue with Blynk Cloud Server. + +``` +Starting ESP8266WM_MRD_ForcedConfig using LittleFS with SSL on ESP8266_NODEMCU +Blynk_WM SSL for ESP8266 v1.3.0 +ESP_MultiResetDetector v1.1.1 +[267] Set CustomsStyle to : +[289] Set CustomsHeadElement to : +[296] Set CORS Header to : Your Access-Control-Allow-Origin +LittleFS Flag read = 0xFFFE0001 +multiResetDetectorFlag = 0xFFFE0001 +lowerBytes = 0x0001, upperBytes = 0x0001 +No multiResetDetected, number of times = 1 +LittleFS Flag read = 0xFFFE0001 +Saving config file... +Saving config file OK +[339] Hostname=8266-Master-Controller +[361] LoadCfgFile +[361] OK +[361] ======= Start Stored Config Data ======= +[361] Hdr=SSL_ESP8266,BrdName=ESP8266 +[361] SSID=HueNet1,PW=12345678 +[363] SSID1=HueNet2,PW1=12345678 +[366] Server=blynk-cloud.com,Token=token1 +[372] Server1=blynk-cloud.com,Token1=token2 +[378] Port=9443 +[379] ======= End Config Data ======= +[383] CCSum=0x2fa3,RCSum=0x2fa3 +[390] LoadCredFile +[391] CrR:pdata=default-mqtt-server,len=34 +[391] CrR:pdata=1883,len=6 +[393] CrR:pdata=default-mqtt-username,len=34 +[397] CrR:pdata=default-mqtt-password,len=34 +[401] CrR:pdata=default-mqtt-SubTopic,len=34 +[405] CrR:pdata=default-mqtt-PubTopic,len=34 +[409] OK +[410] CrCCsum=0x29a6,CrRCsum=0x29a6 +[413] Valid Stored Dynamic Data +[416] Hdr=SSL_ESP8266,BrdName=ESP8266 +[420] SSID=HueNet1,PW=12345678 +[423] SSID1=HueNet2,PW1=12345678 +[425] Server=blynk-cloud.com,Token=token1 +[431] Server1=blynk-cloud.com,Token1=token2 +[438] Port=9443 +[439] ======= End Config Data ======= +[442] Check if isForcedCP +[450] LoadCPFile +[450] OK +[450] bg: noConfigPortal = true +[450] Connecting MultiWifi... +[6667] WiFi connected after time: 1 +[6667] SSID: HueNet1, RSSI = -46 +[6667] Channel: 2, IP address: 192.168.2.92 +[6668] bg: WiFi OK. Try Blynk +[6669] + ___ __ __ + / _ )/ /_ _____ / /__ + / _ / / // / _ \/ '_/ + /____/_/\_, /_//_/_/\_\ + /___/ v0.6.1 on NodeMCU + +[22695] NTP time: Mon Apr 19 06:36:31 2021 +[22695] BlynkArduinoClient.connect: Connecting to blynk-cloud.com:9443 +[23153] Ready (ping: 1ms). +[23245] Connected to Blynk Server = blynk-cloud.com, Token = token1 +[23245] bg: WiFi+Blynk OK + +Blynk ESP8266 using LittleFS connected. +Board Name : ESP8266 +Stop multiResetDetecting +Saving config file... +Saving config file OK +B +Your stored Credentials : +MQTT Server = default-mqtt-server +Port = 1883 +MQTT UserName = default-mqtt-username +MQTT PWD = default-mqtt-password +Subs Topics = default-mqtt-SubTopic +Pubs Topics = default-mqtt-PubTopic +BBBB +``` + +--- + +### 8. ESP32WM_MRD_Config using LITTLEFS with SSL on ESP32S2_DEV + +The following is the sample terminal output when running example [ESP32WM_MRD_Config](examples/ESP32WM_MRD_Config) on **ESP8266_NODEMCU**. Please note that this fix the SSL issue with Blynk Cloud Server and runs on new **ESP32-S2 using LittleFS** using esp32 core v1.0.6+ (not official release v1.0.6, but master release as of 2021/04/19). + + +``` +Starting ESP32WM_MRD_Config using LITTLEFS with SSL on ESP32S2_DEV +Blynk_WM SSL for ESP32 v1.3.0 +ESP_MultiResetDetector v1.1.1 +[134394] Set CustomsStyle to : +[134417] Set CustomsHeadElement to : +[134424] Set CORS Header to : Your Access-Control-Allow-Origin +LittleFS Flag read = 0xFFFE0001 +multiResetDetectorFlag = 0xFFFE0001 +lowerBytes = 0x0001, upperBytes = 0x0001 +No multiResetDetected, number of times = 1 +LittleFS Flag read = 0xFFFE0001 +Saving config file... +Saving config file OK +[134657] Hostname=ESP32-Master-Controller +[134695] LoadCfgFile +[134700] OK +[134700] ======= Start Stored Config Data ======= +[134700] Hdr=SSL_ESP32,BrdName=ESP8266 +[134700] SSID=HueNet1,PW=12345678 +[134701] SSID1=HueNet2,PW1=12345678 +[134704] Server=account.duckdns.org,Token=token1 +[134710] Server1=account.duckdns.org,Token1=token2 +[134717] Port=9443 +[134719] ======= End Config Data ======= +[134722] CCSum=0x33eb,RCSum=0x33eb +[134738] LoadCredFile +[134742] CrR:pdata=default-mqtt-server,len=34 +[134743] CrR:pdata=1883,len=6 +[134743] CrR:pdata=default-mqtt-username,len=34 +[134743] CrR:pdata=default-mqtt-password,len=34 +[134747] CrR:pdata=default-mqtt-SubTopic,len=34 +[134751] CrR:pdata=default-mqtt-PubTopic,len=34 +[134755] OK +[134756] CrCCsum=0x29a6,CrRCsum=0x29a6 +[134760] Valid Stored Dynamic Data +[134763] Hdr=SSL_ESP32,BrdName=ESP8266 +[134766] SSID=HueNet1,PW=12345678 +[134769] SSID1=HueNet2,PW1=12345678 +[134773] Server=account.duckdns.org,Token=token1 +[134779] Server1=account.duckdns.org,Token1=token2 +[134786] Port=9443 +[134787] ======= End Config Data ======= +[134791] Check if isForcedCP +[134806] LoadCPFile +[134811] OK +[134811] bg: noConfigPortal = true +[134811] Connecting MultiWifi... +[144534] WiFi connected after time: 1 +[144534] SSID: HueNet1, RSSI = -38 +[144534] Channel: 2, IP address: 192.168.2.157 +[144535] bg: WiFi OK. Try Blynk +[144536] + ___ __ __ + / _ )/ /_ _____ / /__ + / _ / / // / _ \/ '_/ + /____/_/\_, /_//_/_/\_\ + /___/ v0.6.1 on ESP32 + +[145549] NTP time: Mon Apr 19 05:11:59 2021 +[145549] BlynkArduinoClient.connect: Connecting to account.duckdns.org:9443 +[146810] Certificate OK +[146826] Ready (ping: 15ms). +[146895] Connected to Blynk Server = account.duckdns.org, Token = token1 +[146895] bg: WiFi+Blynk OK + +Blynk ESP32 using LittleFS connected +Board Name : ESP8266 +Stop multiResetDetecting +Saving config file... +Saving config file OK +B +Your stored Credentials : +MQTT Server = default-mqtt-server +Port = 1883 +MQTT UserName = default-mqtt-username +MQTT PWD = default-mqtt-password +Subs Topics = default-mqtt-SubTopic +Pubs Topics = default-mqtt-PubTopic +``` + + --- --- @@ -2338,6 +2580,13 @@ Sometimes, the library will only work if you update the board core to the latest ## Releases +### Major Releases v1.3.0 + +1. Add **LittleFS and SPIFFS** support to new **ESP32-S2** boards (**Arduino ESP32C3_DEV**). Check [HOWTO Install esp32 core for ESP32-S2 (Saola, AI-Thinker ESP-12K) and ESP32-C3 boards into Arduino IDE](#howto-install-esp32-core-for-esp32-s2-saola-ai-thinker-esp-12k-and-esp32-c3-boards-into-arduino-ide). +2. Add **EEPROM and SPIFFS** support to new **ESP32-C3** boards (**Arduino ESP32C3_DEV**). Check [HOWTO Install esp32 core for ESP32-S2 (Saola, AI-Thinker ESP-12K) and ESP32-C3 boards into Arduino IDE](#howto-install-esp32-core-for-esp32-s2-saola-ai-thinker-esp-12k-and-esp32-c3-boards-into-arduino-ide). +3. Fix SSL issue with Blynk Cloud Server +4. Update examples + ### Major Releases v1.2.0 1. Configurable **Customs HTML Headers**, including Customs Style, Customs Head Elements, CORS Header. @@ -2518,14 +2767,16 @@ Submit issues to: [Blynk_WM issues](https://github.com/khoih-prog/Blynk_WM/issue 18. Configurable Config Portal Title 19. Re-structure all examples to separate Credentials / Defines / Dynamic Params / Code so that you can change Credentials / Dynamic Params quickly for each device. 20. Add **LittleFS** support to ESP8266 as SPIFFS deprecated since **ESP8266 core 2.7.1.** -21. Add **LittleFS** support to ESP32 using [LITTLEFS](https://github.com/lorol/LITTLEFS) Library.\ +21. Add **LittleFS** support to ESP32 using [LITTLEFS](https://github.com/lorol/LITTLEFS) Library. 22. Add support to MultiDetectDetector and MRD-related examples 23. Clean-up all compiler warnings possible. 24. Add Table of Contents 25. Add Version String 26. Add functions to control Config Portal from software or Virtual Switches. -27. Add support to **ESP32-S2 (ESP32-S2 Saola, AI-Thinker ESP-12K, etc.) using EEPROM** +27. Add support to **ESP32-S2 (ESP32-S2 Saola, AI-Thinker ESP-12K, etc.) using EEPROM, LittleFS and SPIFFS** 28. Configurable **Customs HTML Headers**, including Customs Style, Customs Head Elements, CORS Header +29. Add support to **ESP32-C3 using EEPROM and SPIFFS** +30. Fix SSL issue with Blynk Cloud Server by using SSL in unsecured mode. --- --- diff --git a/examples/AM2315_ESP32_SSL/AM2315_ESP32_SSL.ino b/examples/AM2315_ESP32_SSL/AM2315_ESP32_SSL.ino index 6da6c12..f2c34f7 100644 --- a/examples/AM2315_ESP32_SSL/AM2315_ESP32_SSL.ino +++ b/examples/AM2315_ESP32_SSL/AM2315_ESP32_SSL.ino @@ -7,7 +7,7 @@ Forked from Blynk library v0.6.1 https://github.com/blynkkk/blynk-library/releases Built by Khoi Hoang https://github.com/khoih-prog/Blynk_WM Licensed under MIT license - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -33,6 +33,8 @@ 1.1.2 K Hoang 28/01/2021 Fix Config Portal and Dynamic Params bugs 1.1.3 K Hoang 31/01/2021 To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP 1.2.0 K Hoang 24/02/2021 Add customs HTML header feature and support to ESP32-S2. + 1.3.0 K Hoang 19/04/2021 Add LittleFS and SPIFFS support to ESP32-S2. Add support to ESP32-C3 without LittleFS + Fix SSL issue with Blynk Cloud Server *****************************************************************************************************************************/ #include "defines.h" diff --git a/examples/AM2315_ESP32_SSL/defines.h b/examples/AM2315_ESP32_SSL/defines.h index 3587522..979f9c7 100644 --- a/examples/AM2315_ESP32_SSL/defines.h +++ b/examples/AM2315_ESP32_SSL/defines.h @@ -9,11 +9,33 @@ Licensed under MIT license *****************************************************************************************************************************/ +/* + // To add something similar to this for ESP32-C3 + #if CONFIG_IDF_TARGET_ESP32 + const int8_t esp32_adc2gpio[20] = {36, 37, 38, 39, 32, 33, 34, 35, -1, -1, 4, 0, 2, 15, 13, 12, 14, 27, 25, 26}; + #elif CONFIG_IDF_TARGET_ESP32S2 + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #elif CONFIG_IDF_TARGET_ESP32C3 + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #endif + */ + #ifndef defines_h #define defines_h -#ifndef ESP32 +#if !( defined(ESP32) ) #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting. +#elif ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_ESP32S2_THING_PLUS || ARDUINO_MICROS2 || \ + ARDUINO_METRO_ESP32S2 || ARDUINO_MAGTAG29_ESP32S2 || ARDUINO_FUNHOUSE_ESP32S2 || \ + ARDUINO_ADAFRUIT_FEATHER_ESP32S2_NOPSRAM ) + #define BOARD_TYPE "ESP32-S2" +#elif ( ARDUINO_ESP32C3_DEV ) + // https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-gpio.c + #warning ESP32-C3 boards not fully supported yet. Only SPIFFS and EEPROM OK. Tempo esp32_adc2gpio to be replaced + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #define BOARD_TYPE "ESP32-C3" +#else + #define BOARD_TYPE "ESP32" #endif #define BLYNK_PRINT Serial @@ -28,11 +50,10 @@ // (USE_LITTLEFS == false) and (USE_SPIFFS == true) => using SPIFFS for configuration data in WiFiManager // Those above #define's must be placed before #include -#if ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_PROS2 || ARDUINO_MICROS2 ) - // Currently, ESP32-S2 only supporting EEPROM. Will fix to support LittleFS and SPIFFS +#if ( ARDUINO_ESP32C3_DEV ) + // Currently, ESP32-C3 only supporting SPIFFS and EEPROM. Will fix to support LittleFS #define USE_LITTLEFS false - #define USE_SPIFFS false - #warning ESP32-S2 only support supporting EEPROM now. + #define USE_SPIFFS true #else #define USE_LITTLEFS true #define USE_SPIFFS false diff --git a/examples/AM2315_ESP8266/AM2315_ESP8266.ino b/examples/AM2315_ESP8266/AM2315_ESP8266.ino index a6d6dcf..f7a5cb3 100644 --- a/examples/AM2315_ESP8266/AM2315_ESP8266.ino +++ b/examples/AM2315_ESP8266/AM2315_ESP8266.ino @@ -7,7 +7,7 @@ Forked from Blynk library v0.6.1 https://github.com/blynkkk/blynk-library/releases Built by Khoi Hoang https://github.com/khoih-prog/Blynk_WM Licensed under MIT license - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -33,6 +33,8 @@ 1.1.2 K Hoang 28/01/2021 Fix Config Portal and Dynamic Params bugs 1.1.3 K Hoang 31/01/2021 To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP 1.2.0 K Hoang 24/02/2021 Add customs HTML header feature and support to ESP32-S2. + 1.3.0 K Hoang 19/04/2021 Add LittleFS and SPIFFS support to ESP32-S2. Add support to ESP32-C3 without LittleFS + Fix SSL issue with Blynk Cloud Server *****************************************************************************************************************************/ #include "defines.h" diff --git a/examples/Blynk_WM_Template/Blynk_WM_Template.ino b/examples/Blynk_WM_Template/Blynk_WM_Template.ino index aa72cd8..c18e628 100644 --- a/examples/Blynk_WM_Template/Blynk_WM_Template.ino +++ b/examples/Blynk_WM_Template/Blynk_WM_Template.ino @@ -8,7 +8,7 @@ Forked from Blynk library v0.6.1 https://github.com/blynkkk/blynk-library/releases Built by Khoi Hoang https://github.com/khoih-prog/Blynk_WM Licensed under MIT license - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -34,6 +34,8 @@ 1.1.2 K Hoang 28/01/2021 Fix Config Portal and Dynamic Params bugs 1.1.3 K Hoang 31/01/2021 To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP 1.2.0 K Hoang 24/02/2021 Add customs HTML header feature and support to ESP32-S2. + 1.3.0 K Hoang 19/04/2021 Add LittleFS and SPIFFS support to ESP32-S2. Add support to ESP32-C3 without LittleFS + Fix SSL issue with Blynk Cloud Server *****************************************************************************************************************************/ // Sketch uses Arduino IDE-selected ESP32 and ESP8266 to select compile choices @@ -86,6 +88,32 @@ * the BlynkSimpleEsp... and ...WiFiManager libraries, the ESP32 and ESP8266. */ +/* + // To add something similar to this for ESP32-C3 + #if CONFIG_IDF_TARGET_ESP32 + const int8_t esp32_adc2gpio[20] = {36, 37, 38, 39, 32, 33, 34, 35, -1, -1, 4, 0, 2, 15, 13, 12, 14, 27, 25, 26}; + #elif CONFIG_IDF_TARGET_ESP32S2 + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #elif CONFIG_IDF_TARGET_ESP32C3 + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #endif + */ + +#if !( defined(ESP32) || defined(ESP8266) ) + #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting. +#elif ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_ESP32S2_THING_PLUS || ARDUINO_MICROS2 || \ + ARDUINO_METRO_ESP32S2 || ARDUINO_MAGTAG29_ESP32S2 || ARDUINO_FUNHOUSE_ESP32S2 || \ + ARDUINO_ADAFRUIT_FEATHER_ESP32S2_NOPSRAM ) + #define BOARD_TYPE "ESP32-S2" +#elif ( ARDUINO_ESP32C3_DEV ) + // https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-gpio.c + #warning ESP32-C3 boards not fully supported yet. Only SPIFFS and EEPROM OK. Tempo esp32_adc2gpio to be replaced + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #define BOARD_TYPE "ESP32-C3" +#else + #define BOARD_TYPE "ESP32" +#endif + #define SERIAL_SPEED 230400 #define SKETCH_NAME "Blynk_WM_Template" @@ -176,11 +204,10 @@ // (USE_LITTLEFS == false) and (USE_SPIFFS == true) => using SPIFFS for configuration data in WiFiManager // Those above #define's must be placed before #include - #if ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_PROS2 || ARDUINO_MICROS2 ) - // Currently, ESP32-S2 only supporting EEPROM. Will fix to support LittleFS and SPIFFS + #if ( ARDUINO_ESP32C3_DEV ) + // Currently, ESP32-C3 only supporting SPIFFS and EEPROM. Will fix to support LittleFS #define USE_LITTLEFS false - #define USE_SPIFFS false - #warning ESP32-S2 only support supporting EEPROM now. + #define USE_SPIFFS true #else #define USE_LITTLEFS true #define USE_SPIFFS false diff --git a/examples/DHT11ESP32/DHT11ESP32.ino b/examples/DHT11ESP32/DHT11ESP32.ino index 2482aeb..af59c23 100644 --- a/examples/DHT11ESP32/DHT11ESP32.ino +++ b/examples/DHT11ESP32/DHT11ESP32.ino @@ -7,7 +7,7 @@ Forked from Blynk library v0.6.1 https://github.com/blynkkk/blynk-library/releases Built by Khoi Hoang https://github.com/khoih-prog/Blynk_WM Licensed under MIT license - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -33,12 +33,14 @@ 1.1.2 K Hoang 28/01/2021 Fix Config Portal and Dynamic Params bugs 1.1.3 K Hoang 31/01/2021 To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP 1.2.0 K Hoang 24/02/2021 Add customs HTML header feature and support to ESP32-S2. + 1.3.0 K Hoang 19/04/2021 Add LittleFS and SPIFFS support to ESP32-S2. Add support to ESP32-C3 without LittleFS + Fix SSL issue with Blynk Cloud Server *****************************************************************************************************************************/ #include "defines.h" #include -#include +#include // https://github.com/adafruit/DHT-sensor-library DHT dht(DHT_PIN, DHT_TYPE); BlynkTimer timer; diff --git a/examples/DHT11ESP32/defines.h b/examples/DHT11ESP32/defines.h index f8d0759..669d026 100644 --- a/examples/DHT11ESP32/defines.h +++ b/examples/DHT11ESP32/defines.h @@ -9,11 +9,33 @@ Licensed under MIT license *****************************************************************************************************************************/ +/* + // To add something similar to this for ESP32-C3 + #if CONFIG_IDF_TARGET_ESP32 + const int8_t esp32_adc2gpio[20] = {36, 37, 38, 39, 32, 33, 34, 35, -1, -1, 4, 0, 2, 15, 13, 12, 14, 27, 25, 26}; + #elif CONFIG_IDF_TARGET_ESP32S2 + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #elif CONFIG_IDF_TARGET_ESP32C3 + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #endif + */ + #ifndef defines_h #define defines_h -#ifndef ESP32 +#if !( defined(ESP32) ) #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting. +#elif ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_ESP32S2_THING_PLUS || ARDUINO_MICROS2 || \ + ARDUINO_METRO_ESP32S2 || ARDUINO_MAGTAG29_ESP32S2 || ARDUINO_FUNHOUSE_ESP32S2 || \ + ARDUINO_ADAFRUIT_FEATHER_ESP32S2_NOPSRAM ) + #define BOARD_TYPE "ESP32-S2" +#elif ( ARDUINO_ESP32C3_DEV ) + // https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-gpio.c + #warning ESP32-C3 boards not fully supported yet. Only SPIFFS and EEPROM OK. Tempo esp32_adc2gpio to be replaced + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #define BOARD_TYPE "ESP32-C3" +#else + #define BOARD_TYPE "ESP32" #endif #define BLYNK_PRINT Serial @@ -28,11 +50,10 @@ // (USE_LITTLEFS == false) and (USE_SPIFFS == true) => using SPIFFS for configuration data in WiFiManager // Those above #define's must be placed before #include -#if ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_PROS2 || ARDUINO_MICROS2 ) - // Currently, ESP32-S2 only supporting EEPROM. Will fix to support LittleFS and SPIFFS +#if ( ARDUINO_ESP32C3_DEV ) + // Currently, ESP32-C3 only supporting SPIFFS and EEPROM. Will fix to support LittleFS #define USE_LITTLEFS false - #define USE_SPIFFS false - #warning ESP32-S2 only support supporting EEPROM now. + #define USE_SPIFFS true #else #define USE_LITTLEFS true #define USE_SPIFFS false diff --git a/examples/DHT11ESP32_SSL/DHT11ESP32_SSL.ino b/examples/DHT11ESP32_SSL/DHT11ESP32_SSL.ino index 83f6b2b..39eebbc 100644 --- a/examples/DHT11ESP32_SSL/DHT11ESP32_SSL.ino +++ b/examples/DHT11ESP32_SSL/DHT11ESP32_SSL.ino @@ -7,7 +7,7 @@ Forked from Blynk library v0.6.1 https://github.com/blynkkk/blynk-library/releases Built by Khoi Hoang https://github.com/khoih-prog/Blynk_WM Licensed under MIT license - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -33,12 +33,14 @@ 1.1.2 K Hoang 28/01/2021 Fix Config Portal and Dynamic Params bugs 1.1.3 K Hoang 31/01/2021 To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP 1.2.0 K Hoang 24/02/2021 Add customs HTML header feature and support to ESP32-S2. + 1.3.0 K Hoang 19/04/2021 Add LittleFS and SPIFFS support to ESP32-S2. Add support to ESP32-C3 without LittleFS + Fix SSL issue with Blynk Cloud Server *****************************************************************************************************************************/ #include "defines.h" #include -#include +#include // https://github.com/adafruit/DHT-sensor-library DHT dht(DHT_PIN, DHT_TYPE); BlynkTimer timer; diff --git a/examples/DHT11ESP32_SSL/defines.h b/examples/DHT11ESP32_SSL/defines.h index bdb983e..c3e0cb2 100644 --- a/examples/DHT11ESP32_SSL/defines.h +++ b/examples/DHT11ESP32_SSL/defines.h @@ -9,11 +9,33 @@ Licensed under MIT license *****************************************************************************************************************************/ +/* + // To add something similar to this for ESP32-C3 + #if CONFIG_IDF_TARGET_ESP32 + const int8_t esp32_adc2gpio[20] = {36, 37, 38, 39, 32, 33, 34, 35, -1, -1, 4, 0, 2, 15, 13, 12, 14, 27, 25, 26}; + #elif CONFIG_IDF_TARGET_ESP32S2 + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #elif CONFIG_IDF_TARGET_ESP32C3 + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #endif + */ + #ifndef defines_h #define defines_h -#ifndef ESP32 +#if !( defined(ESP32) ) #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting. +#elif ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_ESP32S2_THING_PLUS || ARDUINO_MICROS2 || \ + ARDUINO_METRO_ESP32S2 || ARDUINO_MAGTAG29_ESP32S2 || ARDUINO_FUNHOUSE_ESP32S2 || \ + ARDUINO_ADAFRUIT_FEATHER_ESP32S2_NOPSRAM ) + #define BOARD_TYPE "ESP32-S2" +#elif ( ARDUINO_ESP32C3_DEV ) + // https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-gpio.c + #warning ESP32-C3 boards not fully supported yet. Only SPIFFS and EEPROM OK. Tempo esp32_adc2gpio to be replaced + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #define BOARD_TYPE "ESP32-C3" +#else + #define BOARD_TYPE "ESP32" #endif #define BLYNK_PRINT Serial @@ -28,11 +50,10 @@ // (USE_LITTLEFS == false) and (USE_SPIFFS == true) => using SPIFFS for configuration data in WiFiManager // Those above #define's must be placed before #include -#if ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_PROS2 || ARDUINO_MICROS2 ) - // Currently, ESP32-S2 only supporting EEPROM. Will fix to support LittleFS and SPIFFS +#if ( ARDUINO_ESP32C3_DEV ) + // Currently, ESP32-C3 only supporting SPIFFS and EEPROM. Will fix to support LittleFS #define USE_LITTLEFS false - #define USE_SPIFFS false - #warning ESP32-S2 only support supporting EEPROM now. + #define USE_SPIFFS true #else #define USE_LITTLEFS true #define USE_SPIFFS false diff --git a/examples/DHT11ESP8266/DHT11ESP8266.ino b/examples/DHT11ESP8266/DHT11ESP8266.ino index 16ac6a7..4964659 100644 --- a/examples/DHT11ESP8266/DHT11ESP8266.ino +++ b/examples/DHT11ESP8266/DHT11ESP8266.ino @@ -7,7 +7,7 @@ Forked from Blynk library v0.6.1 https://github.com/blynkkk/blynk-library/releases Built by Khoi Hoang https://github.com/khoih-prog/Blynk_WM Licensed under MIT license - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -33,12 +33,14 @@ 1.1.2 K Hoang 28/01/2021 Fix Config Portal and Dynamic Params bugs 1.1.3 K Hoang 31/01/2021 To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP 1.2.0 K Hoang 24/02/2021 Add customs HTML header feature and support to ESP32-S2. + 1.3.0 K Hoang 19/04/2021 Add LittleFS and SPIFFS support to ESP32-S2. Add support to ESP32-C3 without LittleFS + Fix SSL issue with Blynk Cloud Server *****************************************************************************************************************************/ #include "defines.h" #include -#include +#include // https://github.com/adafruit/DHT-sensor-library DHT dht(DHT_PIN, DHT_TYPE); BlynkTimer timer; diff --git a/examples/DHT11ESP8266_Debug/DHT11ESP8266_Debug.ino b/examples/DHT11ESP8266_Debug/DHT11ESP8266_Debug.ino index 3d27da7..d92a75e 100644 --- a/examples/DHT11ESP8266_Debug/DHT11ESP8266_Debug.ino +++ b/examples/DHT11ESP8266_Debug/DHT11ESP8266_Debug.ino @@ -7,7 +7,7 @@ Forked from Blynk library v0.6.1 https://github.com/blynkkk/blynk-library/releases Built by Khoi Hoang https://github.com/khoih-prog/Blynk_WM Licensed under MIT license - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -33,11 +33,13 @@ 1.1.2 K Hoang 28/01/2021 Fix Config Portal and Dynamic Params bugs 1.1.3 K Hoang 31/01/2021 To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP 1.2.0 K Hoang 24/02/2021 Add customs HTML header feature and support to ESP32-S2. + 1.3.0 K Hoang 19/04/2021 Add LittleFS and SPIFFS support to ESP32-S2. Add support to ESP32-C3 without LittleFS + Fix SSL issue with Blynk Cloud Server *****************************************************************************************************************************/ #include "defines.h" #include -#include +#include // https://github.com/adafruit/DHT-sensor-library DHT dht(DHT_PIN, DHT_TYPE); BlynkTimer timer; diff --git a/examples/DHT11ESP8266_SSL/DHT11ESP8266_SSL.ino b/examples/DHT11ESP8266_SSL/DHT11ESP8266_SSL.ino index 318efec..e419b37 100644 --- a/examples/DHT11ESP8266_SSL/DHT11ESP8266_SSL.ino +++ b/examples/DHT11ESP8266_SSL/DHT11ESP8266_SSL.ino @@ -7,7 +7,7 @@ Forked from Blynk library v0.6.1 https://github.com/blynkkk/blynk-library/releases Built by Khoi Hoang https://github.com/khoih-prog/Blynk_WM Licensed under MIT license - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -33,12 +33,14 @@ 1.1.2 K Hoang 28/01/2021 Fix Config Portal and Dynamic Params bugs 1.1.3 K Hoang 31/01/2021 To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP 1.2.0 K Hoang 24/02/2021 Add customs HTML header feature and support to ESP32-S2. + 1.3.0 K Hoang 19/04/2021 Add LittleFS and SPIFFS support to ESP32-S2. Add support to ESP32-C3 without LittleFS + Fix SSL issue with Blynk Cloud Server *****************************************************************************************************************************/ #include "defines.h" #include -#include +#include // https://github.com/adafruit/DHT-sensor-library DHT dht(DHT_PIN, DHT_TYPE); BlynkTimer timer; diff --git a/examples/ESP32WM_Config/ESP32WM_Config.ino b/examples/ESP32WM_Config/ESP32WM_Config.ino index b1552de..3114764 100644 --- a/examples/ESP32WM_Config/ESP32WM_Config.ino +++ b/examples/ESP32WM_Config/ESP32WM_Config.ino @@ -7,7 +7,7 @@ Forked from Blynk library v0.6.1 https://github.com/blynkkk/blynk-library/releases Built by Khoi Hoang https://github.com/khoih-prog/Blynk_WM Licensed under MIT license - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -33,6 +33,8 @@ 1.1.2 K Hoang 28/01/2021 Fix Config Portal and Dynamic Params bugs 1.1.3 K Hoang 31/01/2021 To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP 1.2.0 K Hoang 24/02/2021 Add customs HTML header feature and support to ESP32-S2. + 1.3.0 K Hoang 19/04/2021 Add LittleFS and SPIFFS support to ESP32-S2. Add support to ESP32-C3 without LittleFS + Fix SSL issue with Blynk Cloud Server *****************************************************************************************************************************/ #include "defines.h" @@ -40,7 +42,7 @@ #include "dynamicParams.h" #include -#include +#include // https://github.com/adafruit/DHT-sensor-library DHT dht(DHT_PIN, DHT_TYPE); BlynkTimer timer; diff --git a/examples/ESP32WM_Config/defines.h b/examples/ESP32WM_Config/defines.h index 28fdd30..a16e62b 100644 --- a/examples/ESP32WM_Config/defines.h +++ b/examples/ESP32WM_Config/defines.h @@ -9,11 +9,33 @@ Licensed under MIT license *****************************************************************************************************************************/ +/* + // To add something similar to this for ESP32-C3 + #if CONFIG_IDF_TARGET_ESP32 + const int8_t esp32_adc2gpio[20] = {36, 37, 38, 39, 32, 33, 34, 35, -1, -1, 4, 0, 2, 15, 13, 12, 14, 27, 25, 26}; + #elif CONFIG_IDF_TARGET_ESP32S2 + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #elif CONFIG_IDF_TARGET_ESP32C3 + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #endif + */ + #ifndef defines_h #define defines_h -#ifndef ESP32 +#if !( defined(ESP32) ) #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting. +#elif ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_ESP32S2_THING_PLUS || ARDUINO_MICROS2 || \ + ARDUINO_METRO_ESP32S2 || ARDUINO_MAGTAG29_ESP32S2 || ARDUINO_FUNHOUSE_ESP32S2 || \ + ARDUINO_ADAFRUIT_FEATHER_ESP32S2_NOPSRAM ) + #define BOARD_TYPE "ESP32-S2" +#elif ( ARDUINO_ESP32C3_DEV ) + // https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-gpio.c + #warning ESP32-C3 boards not fully supported yet. Only SPIFFS and EEPROM OK. Tempo esp32_adc2gpio to be replaced + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #define BOARD_TYPE "ESP32-C3" +#else + #define BOARD_TYPE "ESP32" #endif #define BLYNK_PRINT Serial @@ -25,17 +47,15 @@ // (USE_LITTLEFS == false) and (USE_SPIFFS == true) => using SPIFFS for configuration data in WiFiManager // Those above #define's must be placed before #include -#if ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_PROS2 || ARDUINO_MICROS2 ) - // Currently, ESP32-S2 only supporting EEPROM. Will fix to support LittleFS and SPIFFS +#if ( ARDUINO_ESP32C3_DEV ) + // Currently, ESP32-C3 only supporting SPIFFS and EEPROM. Will fix to support LittleFS #define USE_LITTLEFS false - #define USE_SPIFFS false - #warning ESP32-S2 only support supporting EEPROM now. + #define USE_SPIFFS true #else #define USE_LITTLEFS true #define USE_SPIFFS false #endif - #if !( USE_SPIFFS || USE_LITTLEFS) // EEPROM_SIZE must be <= 2048 and >= CONFIG_DATA_SIZE (currently 172 bytes) #define EEPROM_SIZE (2 * 1024) diff --git a/examples/ESP32WM_ForcedConfig/ESP32WM_ForcedConfig.ino b/examples/ESP32WM_ForcedConfig/ESP32WM_ForcedConfig.ino index 7a1abce..04b16fd 100644 --- a/examples/ESP32WM_ForcedConfig/ESP32WM_ForcedConfig.ino +++ b/examples/ESP32WM_ForcedConfig/ESP32WM_ForcedConfig.ino @@ -7,7 +7,7 @@ Forked from Blynk library v0.6.1 https://github.com/blynkkk/blynk-library/releases Built by Khoi Hoang https://github.com/khoih-prog/Blynk_WM Licensed under MIT license - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -33,6 +33,8 @@ 1.1.2 K Hoang 28/01/2021 Fix Config Portal and Dynamic Params bugs 1.1.3 K Hoang 31/01/2021 To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP 1.2.0 K Hoang 24/02/2021 Add customs HTML header feature and support to ESP32-S2. + 1.3.0 K Hoang 19/04/2021 Add LittleFS and SPIFFS support to ESP32-S2. Add support to ESP32-C3 without LittleFS + Fix SSL issue with Blynk Cloud Server *****************************************************************************************************************************/ #include "defines.h" @@ -40,7 +42,7 @@ #include "dynamicParams.h" #include -#include +#include // https://github.com/adafruit/DHT-sensor-library DHT dht(DHT_PIN, DHT_TYPE); BlynkTimer timer; diff --git a/examples/ESP32WM_ForcedConfig/defines.h b/examples/ESP32WM_ForcedConfig/defines.h index ad67495..7910f7a 100644 --- a/examples/ESP32WM_ForcedConfig/defines.h +++ b/examples/ESP32WM_ForcedConfig/defines.h @@ -9,11 +9,33 @@ Licensed under MIT license *****************************************************************************************************************************/ +/* + // To add something similar to this for ESP32-C3 + #if CONFIG_IDF_TARGET_ESP32 + const int8_t esp32_adc2gpio[20] = {36, 37, 38, 39, 32, 33, 34, 35, -1, -1, 4, 0, 2, 15, 13, 12, 14, 27, 25, 26}; + #elif CONFIG_IDF_TARGET_ESP32S2 + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #elif CONFIG_IDF_TARGET_ESP32C3 + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #endif + */ + #ifndef defines_h #define defines_h -#ifndef ESP32 +#if !( defined(ESP32) ) #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting. +#elif ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_ESP32S2_THING_PLUS || ARDUINO_MICROS2 || \ + ARDUINO_METRO_ESP32S2 || ARDUINO_MAGTAG29_ESP32S2 || ARDUINO_FUNHOUSE_ESP32S2 || \ + ARDUINO_ADAFRUIT_FEATHER_ESP32S2_NOPSRAM ) + #define BOARD_TYPE "ESP32-S2" +#elif ( ARDUINO_ESP32C3_DEV ) + // https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-gpio.c + #warning ESP32-C3 boards not fully supported yet. Only SPIFFS and EEPROM OK. Tempo esp32_adc2gpio to be replaced + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #define BOARD_TYPE "ESP32-C3" +#else + #define BOARD_TYPE "ESP32" #endif #define BLYNK_PRINT Serial @@ -26,11 +48,10 @@ // (USE_LITTLEFS == false) and (USE_SPIFFS == true) => using SPIFFS for configuration data in WiFiManager // Those above #define's must be placed before #include -#if ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_PROS2 || ARDUINO_MICROS2 ) - // Currently, ESP32-S2 only supporting EEPROM. Will fix to support LittleFS and SPIFFS +#if ( ARDUINO_ESP32C3_DEV ) + // Currently, ESP32-C3 only supporting SPIFFS and EEPROM. Will fix to support LittleFS #define USE_LITTLEFS false - #define USE_SPIFFS false - #warning ESP32-S2 only support supporting EEPROM now. + #define USE_SPIFFS true #else #define USE_LITTLEFS true #define USE_SPIFFS false diff --git a/examples/ESP32WM_MRD_Config/ESP32WM_MRD_Config.ino b/examples/ESP32WM_MRD_Config/ESP32WM_MRD_Config.ino index 3fedf8b..5ce3565 100644 --- a/examples/ESP32WM_MRD_Config/ESP32WM_MRD_Config.ino +++ b/examples/ESP32WM_MRD_Config/ESP32WM_MRD_Config.ino @@ -7,7 +7,7 @@ Forked from Blynk library v0.6.1 https://github.com/blynkkk/blynk-library/releases Built by Khoi Hoang https://github.com/khoih-prog/Blynk_WM Licensed under MIT license - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -33,6 +33,8 @@ 1.1.2 K Hoang 28/01/2021 Fix Config Portal and Dynamic Params bugs 1.1.3 K Hoang 31/01/2021 To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP 1.2.0 K Hoang 24/02/2021 Add customs HTML header feature and support to ESP32-S2. + 1.3.0 K Hoang 19/04/2021 Add LittleFS and SPIFFS support to ESP32-S2. Add support to ESP32-C3 without LittleFS + Fix SSL issue with Blynk Cloud Server *****************************************************************************************************************************/ #include "defines.h" @@ -40,7 +42,7 @@ #include "dynamicParams.h" #include -#include +#include // https://github.com/adafruit/DHT-sensor-library DHT dht(DHT_PIN, DHT_TYPE); BlynkTimer timer; @@ -126,7 +128,11 @@ void setup() Serial.begin(115200); while (!Serial); +#if ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_PROS2 || ARDUINO_MICROS2 ) + delay(2000); +#else delay(200); +#endif #if (USE_LITTLEFS) Serial.print(F("\nStarting ESP32WM_MRD_Config using LITTLEFS")); diff --git a/examples/ESP32WM_MRD_Config/defines.h b/examples/ESP32WM_MRD_Config/defines.h index 0ccc5db..cb5bf06 100644 --- a/examples/ESP32WM_MRD_Config/defines.h +++ b/examples/ESP32WM_MRD_Config/defines.h @@ -9,11 +9,33 @@ Licensed under MIT license ********************************************************************************************************************************/ +/* + // To add something similar to this for ESP32-C3 + #if CONFIG_IDF_TARGET_ESP32 + const int8_t esp32_adc2gpio[20] = {36, 37, 38, 39, 32, 33, 34, 35, -1, -1, 4, 0, 2, 15, 13, 12, 14, 27, 25, 26}; + #elif CONFIG_IDF_TARGET_ESP32S2 + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #elif CONFIG_IDF_TARGET_ESP32C3 + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #endif + */ + #ifndef defines_h #define defines_h -#ifndef ESP32 +#if !( defined(ESP32) ) #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting. +#elif ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_ESP32S2_THING_PLUS || ARDUINO_MICROS2 || \ + ARDUINO_METRO_ESP32S2 || ARDUINO_MAGTAG29_ESP32S2 || ARDUINO_FUNHOUSE_ESP32S2 || \ + ARDUINO_ADAFRUIT_FEATHER_ESP32S2_NOPSRAM ) + #define BOARD_TYPE "ESP32-S2" +#elif ( ARDUINO_ESP32C3_DEV ) + // https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-gpio.c + #warning ESP32-C3 boards not fully supported yet. Only SPIFFS and EEPROM OK. Tempo esp32_adc2gpio to be replaced + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #define BOARD_TYPE "ESP32-C3" +#else + #define BOARD_TYPE "ESP32" #endif #define BLYNK_PRINT Serial @@ -60,11 +82,10 @@ // (USE_LITTLEFS == false) and (USE_SPIFFS == true) => using SPIFFS for configuration data in WiFiManager // Those above #define's must be placed before #include -#if ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_PROS2 || ARDUINO_MICROS2 ) - // Currently, ESP32-S2 only supporting EEPROM. Will fix to support LittleFS and SPIFFS +#if ( ARDUINO_ESP32C3_DEV ) + // Currently, ESP32-C3 only supporting SPIFFS and EEPROM. Will fix to support LittleFS #define USE_LITTLEFS false - #define USE_SPIFFS false - #warning ESP32-S2 only support supporting EEPROM now. + #define USE_SPIFFS true #else #define USE_LITTLEFS true #define USE_SPIFFS false diff --git a/examples/ESP32WM_MRD_ForcedConfig/ESP32WM_MRD_ForcedConfig.ino b/examples/ESP32WM_MRD_ForcedConfig/ESP32WM_MRD_ForcedConfig.ino index 2b8a28d..13a7d85 100644 --- a/examples/ESP32WM_MRD_ForcedConfig/ESP32WM_MRD_ForcedConfig.ino +++ b/examples/ESP32WM_MRD_ForcedConfig/ESP32WM_MRD_ForcedConfig.ino @@ -7,7 +7,7 @@ Forked from Blynk library v0.6.1 https://github.com/blynkkk/blynk-library/releases Built by Khoi Hoang https://github.com/khoih-prog/Blynk_WM Licensed under MIT license - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -33,6 +33,8 @@ 1.1.2 K Hoang 28/01/2021 Fix Config Portal and Dynamic Params bugs 1.1.3 K Hoang 31/01/2021 To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP 1.2.0 K Hoang 24/02/2021 Add customs HTML header feature and support to ESP32-S2. + 1.3.0 K Hoang 19/04/2021 Add LittleFS and SPIFFS support to ESP32-S2. Add support to ESP32-C3 without LittleFS + Fix SSL issue with Blynk Cloud Server *****************************************************************************************************************************/ #include "defines.h" @@ -40,7 +42,7 @@ #include "dynamicParams.h" #include -#include +#include // https://github.com/adafruit/DHT-sensor-library DHT dht(DHT_PIN, DHT_TYPE); BlynkTimer timer; diff --git a/examples/ESP32WM_MRD_ForcedConfig/defines.h b/examples/ESP32WM_MRD_ForcedConfig/defines.h index 0ccc5db..bfa21a8 100644 --- a/examples/ESP32WM_MRD_ForcedConfig/defines.h +++ b/examples/ESP32WM_MRD_ForcedConfig/defines.h @@ -9,13 +9,34 @@ Licensed under MIT license ********************************************************************************************************************************/ +/* + // To add something similar to this for ESP32-C3 + #if CONFIG_IDF_TARGET_ESP32 + const int8_t esp32_adc2gpio[20] = {36, 37, 38, 39, 32, 33, 34, 35, -1, -1, 4, 0, 2, 15, 13, 12, 14, 27, 25, 26}; + #elif CONFIG_IDF_TARGET_ESP32S2 + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #elif CONFIG_IDF_TARGET_ESP32C3 + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #endif + */ + #ifndef defines_h #define defines_h -#ifndef ESP32 +#if !( defined(ESP32) ) #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting. +#elif ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_ESP32S2_THING_PLUS || ARDUINO_MICROS2 || \ + ARDUINO_METRO_ESP32S2 || ARDUINO_MAGTAG29_ESP32S2 || ARDUINO_FUNHOUSE_ESP32S2 || \ + ARDUINO_ADAFRUIT_FEATHER_ESP32S2_NOPSRAM ) + #define BOARD_TYPE "ESP32-S2" +#elif ( ARDUINO_ESP32C3_DEV ) + // https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-gpio.c + #warning ESP32-C3 boards not fully supported yet. Only SPIFFS and EEPROM OK. Tempo esp32_adc2gpio to be replaced + const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + #define BOARD_TYPE "ESP32-C3" +#else + #define BOARD_TYPE "ESP32" #endif - #define BLYNK_PRINT Serial #define BLYNK_WM_DEBUG 3 @@ -60,11 +81,10 @@ // (USE_LITTLEFS == false) and (USE_SPIFFS == true) => using SPIFFS for configuration data in WiFiManager // Those above #define's must be placed before #include -#if ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_PROS2 || ARDUINO_MICROS2 ) - // Currently, ESP32-S2 only supporting EEPROM. Will fix to support LittleFS and SPIFFS +#if ( ARDUINO_ESP32C3_DEV ) + // Currently, ESP32-C3 only supporting SPIFFS and EEPROM. Will fix to support LittleFS #define USE_LITTLEFS false - #define USE_SPIFFS false - #warning ESP32-S2 only support supporting EEPROM now. + #define USE_SPIFFS true #else #define USE_LITTLEFS true #define USE_SPIFFS false diff --git a/examples/ESP8266WM_Config/ESP8266WM_Config.ino b/examples/ESP8266WM_Config/ESP8266WM_Config.ino index 4761ff6..f3b65b9 100644 --- a/examples/ESP8266WM_Config/ESP8266WM_Config.ino +++ b/examples/ESP8266WM_Config/ESP8266WM_Config.ino @@ -7,7 +7,7 @@ Forked from Blynk library v0.6.1 https://github.com/blynkkk/blynk-library/releases Built by Khoi Hoang https://github.com/khoih-prog/Blynk_WM Licensed under MIT license - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -33,6 +33,8 @@ 1.1.2 K Hoang 28/01/2021 Fix Config Portal and Dynamic Params bugs 1.1.3 K Hoang 31/01/2021 To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP 1.2.0 K Hoang 24/02/2021 Add customs HTML header feature and support to ESP32-S2. + 1.3.0 K Hoang 19/04/2021 Add LittleFS and SPIFFS support to ESP32-S2. Add support to ESP32-C3 without LittleFS + Fix SSL issue with Blynk Cloud Server *****************************************************************************************************************************/ #include "defines.h" @@ -40,7 +42,7 @@ #include "dynamicParams.h" #include -#include +#include // https://github.com/adafruit/DHT-sensor-library DHT dht(DHT_PIN, DHT_TYPE); BlynkTimer timer; diff --git a/examples/ESP8266WM_Config/defines.h b/examples/ESP8266WM_Config/defines.h index 809d478..3827e85 100644 --- a/examples/ESP8266WM_Config/defines.h +++ b/examples/ESP8266WM_Config/defines.h @@ -13,7 +13,7 @@ #define defines_h #ifndef ESP8266 - #error This code is intended to run on the ESP8266 platform! Please check your Tools->Board setting. +#error This code is intended to run on the ESP8266 platform! Please check your Tools->Board setting. #endif #define BLYNK_PRINT Serial @@ -32,22 +32,22 @@ #define USE_SPIFFS false #if USE_LITTLEFS - //LittleFS has higher priority - #define CurrentFileFS "LittleFS" - #ifdef USE_SPIFFS - #undef USE_SPIFFS - #endif - #define USE_SPIFFS false +//LittleFS has higher priority +#define CurrentFileFS "LittleFS" +#ifdef USE_SPIFFS +#undef USE_SPIFFS +#endif +#define USE_SPIFFS false #elif USE_SPIFFS - #define CurrentFileFS "SPIFFS" +#define CurrentFileFS "SPIFFS" #endif #if !( USE_LITTLEFS || USE_SPIFFS) - // EEPROM_SIZE must be <= 4096 and >= CONFIG_DATA_SIZE (currently 172 bytes) - #define EEPROM_SIZE (4 * 1024) - // EEPROM_START + CONFIG_DATA_SIZE must be <= EEPROM_SIZE - #define EEPROM_START 768 +// EEPROM_SIZE must be <= 4096 and >= CONFIG_DATA_SIZE (currently 172 bytes) +#define EEPROM_SIZE (4 * 1024) +// EEPROM_START + CONFIG_DATA_SIZE must be <= EEPROM_SIZE +#define EEPROM_START 768 #endif ///////////////////////////////////////////// @@ -75,9 +75,9 @@ #define USE_SSL false #if USE_SSL - #include +#include #else - #include +#include #endif #define PIN_LED 2 // Pin D4 mapped to pin GPIO2/TXD1 of ESP8266, NodeMCU and WeMoS, control on-board LED diff --git a/examples/ESP8266WM_ForcedConfig/ESP8266WM_ForcedConfig.ino b/examples/ESP8266WM_ForcedConfig/ESP8266WM_ForcedConfig.ino index fda1a3f..9da7c62 100644 --- a/examples/ESP8266WM_ForcedConfig/ESP8266WM_ForcedConfig.ino +++ b/examples/ESP8266WM_ForcedConfig/ESP8266WM_ForcedConfig.ino @@ -7,7 +7,7 @@ Forked from Blynk library v0.6.1 https://github.com/blynkkk/blynk-library/releases Built by Khoi Hoang https://github.com/khoih-prog/Blynk_WM Licensed under MIT license - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -33,6 +33,8 @@ 1.1.2 K Hoang 28/01/2021 Fix Config Portal and Dynamic Params bugs 1.1.3 K Hoang 31/01/2021 To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP 1.2.0 K Hoang 24/02/2021 Add customs HTML header feature and support to ESP32-S2. + 1.3.0 K Hoang 19/04/2021 Add LittleFS and SPIFFS support to ESP32-S2. Add support to ESP32-C3 without LittleFS + Fix SSL issue with Blynk Cloud Server *****************************************************************************************************************************/ #include "defines.h" @@ -40,7 +42,7 @@ #include "dynamicParams.h" #include -#include +#include // https://github.com/adafruit/DHT-sensor-library DHT dht(DHT_PIN, DHT_TYPE); BlynkTimer timer; diff --git a/examples/ESP8266WM_MRD_Config/ESP8266WM_MRD_Config.ino b/examples/ESP8266WM_MRD_Config/ESP8266WM_MRD_Config.ino index ec0c172..3d07a9c 100644 --- a/examples/ESP8266WM_MRD_Config/ESP8266WM_MRD_Config.ino +++ b/examples/ESP8266WM_MRD_Config/ESP8266WM_MRD_Config.ino @@ -7,7 +7,7 @@ Forked from Blynk library v0.6.1 https://github.com/blynkkk/blynk-library/releases Built by Khoi Hoang https://github.com/khoih-prog/Blynk_WM Licensed under MIT license - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -33,6 +33,8 @@ 1.1.2 K Hoang 28/01/2021 Fix Config Portal and Dynamic Params bugs 1.1.3 K Hoang 31/01/2021 To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP 1.2.0 K Hoang 24/02/2021 Add customs HTML header feature and support to ESP32-S2. + 1.3.0 K Hoang 19/04/2021 Add LittleFS and SPIFFS support to ESP32-S2. Add support to ESP32-C3 without LittleFS + Fix SSL issue with Blynk Cloud Server ********************************************************************************************************************************/ #include "defines.h" @@ -40,7 +42,7 @@ #include "dynamicParams.h" #include -#include +#include // https://github.com/adafruit/DHT-sensor-library DHT dht(DHT_PIN, DHT_TYPE); BlynkTimer timer; diff --git a/examples/ESP8266WM_MRD_ForcedConfig/ESP8266WM_MRD_ForcedConfig.ino b/examples/ESP8266WM_MRD_ForcedConfig/ESP8266WM_MRD_ForcedConfig.ino index 7abd1e1..4d7a0c5 100644 --- a/examples/ESP8266WM_MRD_ForcedConfig/ESP8266WM_MRD_ForcedConfig.ino +++ b/examples/ESP8266WM_MRD_ForcedConfig/ESP8266WM_MRD_ForcedConfig.ino @@ -7,7 +7,7 @@ Forked from Blynk library v0.6.1 https://github.com/blynkkk/blynk-library/releases Built by Khoi Hoang https://github.com/khoih-prog/Blynk_WM Licensed under MIT license - Version: 1.1.3 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -32,6 +32,9 @@ 1.1.1 K Hoang 16/01/2021 Add functions to control Config Portal from software or Virtual Switches 1.1.2 K Hoang 28/01/2021 Fix Config Portal and Dynamic Params bugs 1.1.3 K Hoang 31/01/2021 To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP + 1.2.0 K Hoang 24/02/2021 Add customs HTML header feature and support to ESP32-S2. + 1.3.0 K Hoang 19/04/2021 Add LittleFS and SPIFFS support to ESP32-S2. Add support to ESP32-C3 without LittleFS + Fix SSL issue with Blynk Cloud Server ********************************************************************************************************************************/ #include "defines.h" @@ -39,7 +42,7 @@ #include "dynamicParams.h" #include -#include +#include // https://github.com/adafruit/DHT-sensor-library DHT dht(DHT_PIN, DHT_TYPE); BlynkTimer timer; diff --git a/pics/Blynk_ESP32_C3_Support.png b/pics/Blynk_ESP32_C3_Support.png new file mode 100644 index 0000000000000000000000000000000000000000..d8d1b2264859fd5e41b0a8921eb520feeff2ce5b GIT binary patch literal 99560 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 literal 0 HcmV?d00001 diff --git a/src/BlynkSimpleEsp32_SSL_WM.h b/src/BlynkSimpleEsp32_SSL_WM.h index 211d933..5bde197 100644 --- a/src/BlynkSimpleEsp32_SSL_WM.h +++ b/src/BlynkSimpleEsp32_SSL_WM.h @@ -16,7 +16,7 @@ @date Jan 2015 @brief - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -42,6 +42,8 @@ 1.1.2 K Hoang 28/01/2021 Fix Config Portal and Dynamic Params bugs 1.1.3 K Hoang 31/01/2021 To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP 1.2.0 K Hoang 24/02/2021 Add customs HTML header feature and support to ESP32-S2. + 1.3.0 K Hoang 19/04/2021 Add LittleFS and SPIFFS support to ESP32-S2. Add support to ESP32-C3 without LittleFS + Fix SSL issue with Blynk Cloud Server ********************************************************************************************************************************/ #ifndef BlynkSimpleEsp32_SSL_WM_h @@ -51,7 +53,7 @@ #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting. #endif -#define BLYNK_WM_VERSION "Blynk_WM SSL for ESP32 v1.2.0" +#define BLYNK_WM_VERSION "Blynk_WM SSL for ESP32 v1.3.0" #if defined(BLYNK_SSL_USE_LETSENCRYPT) static const char BLYNK_DEFAULT_ROOT_CA[] = @@ -243,6 +245,14 @@ class BlynkArduinoClientSecure BLYNK_LOG2("NTP time: ", ntpTime); this->client->setCACert(caCert); + + ///////////////////////////////////////// + // KH, New v1.3.0 + if (String(this->domain) == BLYNK_DEFAULT_DOMAIN) + { + this->client->setInsecure(); + } + ///////////////////////////////////////// if (BlynkArduinoClientGen::connect()) { diff --git a/src/BlynkSimpleEsp32_WM.h b/src/BlynkSimpleEsp32_WM.h index d949cd2..d12e6b3 100644 --- a/src/BlynkSimpleEsp32_WM.h +++ b/src/BlynkSimpleEsp32_WM.h @@ -16,7 +16,7 @@ @date Jan 2015 @brief - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -42,6 +42,8 @@ 1.1.2 K Hoang 28/01/2021 Fix Config Portal and Dynamic Params bugs 1.1.3 K Hoang 31/01/2021 To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP 1.2.0 K Hoang 24/02/2021 Add customs HTML header feature and support to ESP32-S2. + 1.3.0 K Hoang 19/04/2021 Add LittleFS and SPIFFS support to ESP32-S2. Add support to ESP32-C3 without LittleFS + Fix SSL issue with Blynk Cloud Server ********************************************************************************************************************************/ #ifndef BlynkSimpleEsp32_WM_h @@ -51,7 +53,7 @@ #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting. #endif -#define BLYNK_WM_VERSION "Blynk_WM for ESP32 v1.2.0" +#define BLYNK_WM_VERSION "Blynk_WM for ESP32 v1.3.0" #define BLYNK_SEND_ATOMIC diff --git a/src/BlynkSimpleEsp8266_SSL_WM.h b/src/BlynkSimpleEsp8266_SSL_WM.h index 6870481..22d71c7 100644 --- a/src/BlynkSimpleEsp8266_SSL_WM.h +++ b/src/BlynkSimpleEsp8266_SSL_WM.h @@ -16,7 +16,7 @@ @date Jan 2015 @brief - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -42,6 +42,8 @@ 1.1.2 K Hoang 28/01/2021 Fix Config Portal and Dynamic Params bugs 1.1.3 K Hoang 31/01/2021 To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP 1.2.0 K Hoang 24/02/2021 Add customs HTML header feature and support to ESP32-S2. + 1.3.0 K Hoang 19/04/2021 Add LittleFS and SPIFFS support to ESP32-S2. Add support to ESP32-C3 without LittleFS + Fix SSL issue with Blynk Cloud Server ********************************************************************************************************************************/ #ifndef BlynkSimpleEsp8266_SSL_WM_h @@ -51,7 +53,7 @@ #error This code is intended to run on the ESP8266 platform! Please check your Tools->Board setting. #endif -#define BLYNK_WM_VERSION "Blynk_WM SSL for ESP8266 v1.2.0" +#define BLYNK_WM_VERSION "Blynk_WM SSL for ESP8266 v1.3.0" #include @@ -61,6 +63,7 @@ // Fingerprint is not used by default //#define BLYNK_DEFAULT_FINGERPRINT "FD C0 7D 8D 47 97 F7 E3 07 05 D3 4E E3 BB 8E 3D C0 EA BE 1C" +//#define BLYNK_DEFAULT_FINGERPRINT "32 35 C9 6C 05 1B 73 2C 37 E8 31 0C 70 EE 67 10 1F D6 07 6A" #if defined(BLYNK_SSL_USE_LETSENCRYPT) static const unsigned char BLYNK_DEFAULT_CERT_DER[] PROGMEM = @@ -238,7 +241,7 @@ class BlynkArduinoClientSecure if (this->connected()) return true; - // Synchronize time useing SNTP. This is necessary to verify that + // Synchronize time using SNTP. This is necessary to verify that // the TLS certificates offered by the server are currently valid. configTime(0, 0, "pool.ntp.org", "time.nist.gov"); time_t now = time(nullptr); @@ -256,9 +259,18 @@ class BlynkArduinoClientSecure ntpTime.trim(); BLYNK_LOG2("NTP time: ", ntpTime); + ///////////////////////////////////////// + // KH, New v1.3.0 + if (String(this->domain) == BLYNK_DEFAULT_DOMAIN) + { + this->client->setInsecure(); + } + ///////////////////////////////////////// + + // Now try connecting if (BlynkArduinoClientGen::connect()) - { + { if (fingerprint && this->client->verify(fingerprint, this->domain)) { BLYNK_LOG1(BLYNK_F("Fingerprint OK")); @@ -510,8 +522,7 @@ class BlynkWifi void begin(const char *iHostname = "", const char* fingerprint = NULL) { _fingerprint = fingerprint; - - + #define TIMEOUT_CONNECT_WIFI 30000 //Turn OFF diff --git a/src/BlynkSimpleEsp8266_WM.h b/src/BlynkSimpleEsp8266_WM.h index eda8bc5..331428c 100644 --- a/src/BlynkSimpleEsp8266_WM.h +++ b/src/BlynkSimpleEsp8266_WM.h @@ -16,7 +16,7 @@ @date Jan 2015 @brief - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -42,6 +42,8 @@ 1.1.2 K Hoang 28/01/2021 Fix Config Portal and Dynamic Params bugs 1.1.3 K Hoang 31/01/2021 To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP 1.2.0 K Hoang 24/02/2021 Add customs HTML header feature and support to ESP32-S2. + 1.3.0 K Hoang 19/04/2021 Add LittleFS and SPIFFS support to ESP32-S2. Add support to ESP32-C3 without LittleFS + Fix SSL issue with Blynk Cloud Server ********************************************************************************************************************************/ @@ -52,7 +54,7 @@ #error This code is intended to run on the ESP8266 platform! Please check your Tools->Board setting. #endif -#define BLYNK_WM_VERSION "Blynk_WM for ESP8266 v1.2.0" +#define BLYNK_WM_VERSION "Blynk_WM for ESP8266 v1.3.0" #include