├── .codespellrc ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── dependabot.yml ├── stale.yml └── workflows │ ├── auto-github-actions.yml │ ├── report-size-deltas.yml │ └── spell-check.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── changelog.md ├── esp32s2_WebServer_Patch ├── WebServer.cpp └── WebServer.h ├── examples ├── ESP_WiFi │ ├── Credentials.h │ ├── ESP_WiFi.ino │ ├── defines.h │ └── dynamicParams.h └── ESP_WiFi_MQTT │ ├── Credentials.h │ ├── ESP_WiFi_MQTT.ino │ ├── defines.h │ └── dynamicParams.h ├── keywords.txt ├── library.json ├── library.properties ├── pics ├── Input.png ├── Input_With_Scan.png ├── MQTT.png ├── Main.png └── Save.png ├── platformio └── platformio.ini ├── src ├── ESP_WiFiManager_Lite.h └── ESP_WiFiManager_Lite_Debug.h └── utils ├── astyle_library.conf └── restyle.sh /.codespellrc: -------------------------------------------------------------------------------- 1 | # See: https://github.com/codespell-project/codespell#using-a-config-file 2 | [codespell] 3 | # In the event of a false positive, add the problematic word, in all lowercase, to a comma-separated list here: 4 | ignore-words-list = , 5 | check-filenames = 6 | check-hidden = 7 | skip = ./.git,./src,./examples,./Packages_Patches,./LibraryPatches 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### Describe the bug 11 | 12 | A clear and concise description of what the bug is. 13 | 14 | ### Steps to Reproduce 15 | 16 | Steps to reproduce the behavior. Including the [MRE](https://stackoverflow.com/help/minimal-reproducible-example) sketches 17 | 18 | ### Expected behavior 19 | 20 | A clear and concise description of what you expected to happen. 21 | 22 | ### Actual behavior 23 | 24 | A clear and concise description of what you expected to happen. 25 | 26 | ### Debug and AT-command log (if applicable) 27 | 28 | A clear and concise description of what you expected to happen. 29 | 30 | ### Screenshots 31 | 32 | If applicable, add screenshots to help explain your problem. 33 | 34 | --- 35 | 36 | ### Information 37 | 38 | Please ensure to specify the following: 39 | 40 | * Arduino IDE version (e.g. 1.8.19) or Platform.io version 41 | * `ESP8266` or `ESP32` Core Version (e.g. ESP8266 core v3.1.1 or ESP32 v2.0.6) 42 | * Contextual information (e.g. what you were trying to achieve) 43 | * Simplest possible steps to reproduce 44 | * Anything that might be relevant in your opinion, such as: 45 | * Operating system (Windows, Ubuntu, etc.) and the output of `uname -a` 46 | * Network configuration 47 | 48 | Please be educated, civilized and constructive as you've always been. Disrespective posts against [GitHub Code of Conduct](https://docs.github.com/en/site-policy/github-terms/github-event-code-of-conduct) will be ignored and deleted. 49 | 50 | --- 51 | 52 | ### Example 53 | 54 | ``` 55 | Arduino IDE version: 1.8.19 56 | ESP8266 Core Version 3.1.1 57 | OS: Ubuntu 20.04 LTS 58 | Linux xy-Inspiron-3593 5.15.0-58-generic #64~20.04.1-Ubuntu SMP Fri Jan 6 16:42:31 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux 59 | 60 | Context: 61 | I encountered a crash while trying to use the library 62 | 63 | Steps to reproduce: 64 | 1. ... 65 | 2. ... 66 | 3. ... 67 | 4. ... 68 | ``` 69 | 70 | --- 71 | 72 | ### Sending Feature Requests 73 | 74 | Feel free to post feature requests. It's helpful if you can explain exactly why the feature would be useful. 75 | 76 | There are usually some outstanding feature requests in the [existing issues list](https://github.com/khoih-prog/ESP_WiFiManager_Lite/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement), feel free to add comments to them. 77 | 78 | --- 79 | 80 | ### Sending Pull Requests 81 | 82 | Pull Requests with changes and fixes are also welcome! 83 | 84 | Please use the `astyle` to reformat the updated library code as follows (demo for Ubuntu Linux) 85 | 86 | 1. Change directory to the library GitHub 87 | 88 | ``` 89 | xy@xy-Inspiron-3593:~$ cd Arduino/xy/ESP_WiFiManager_Lite_GitHub/ 90 | xy@xy-Inspiron-3593:~/Arduino/xy/ESP_WiFiManager_Lite_GitHub$ 91 | ``` 92 | 93 | 2. Issue astyle command 94 | 95 | ``` 96 | xy@xy-Inspiron-3593:~/Arduino/xy/ESP_WiFiManager_Lite_GitHub$ bash utils/restyle.sh 97 | ``` 98 | 99 | 100 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### Is your feature request related to a problem? Please describe. 11 | 12 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 13 | 14 | ### Describe the solution you'd like 15 | 16 | A clear and concise description of what you want to happen. 17 | 18 | ### Describe alternatives you've considered 19 | A clear and concise description of any alternative solutions or features you've considered. 20 | 21 | ### Additional context 22 | 23 | Add any other context or screenshots about the feature request here. 24 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # See: https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates#about-the-dependabotyml-file 2 | version: 2 3 | 4 | updates: 5 | # Configure check for outdated GitHub Actions actions in workflows. 6 | # See: https://docs.github.com/en/github/administering-a-repository/keeping-your-actions-up-to-date-with-dependabot 7 | - package-ecosystem: github-actions 8 | directory: / # Check the repository's workflows under /.github/workflows/ 9 | schedule: 10 | interval: daily 11 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-stale - https://github.com/probot/stale 2 | 3 | daysUntilStale: 60 4 | daysUntilClose: 14 5 | limitPerRun: 30 6 | staleLabel: stale 7 | exemptLabels: 8 | - pinned 9 | - security 10 | - "to be implemented" 11 | - "for reference" 12 | - "move to PR" 13 | - "enhancement" 14 | 15 | only: issues 16 | onlyLabels: [] 17 | exemptProjects: false 18 | exemptMilestones: false 19 | exemptAssignees: false 20 | 21 | markComment: > 22 | [STALE_SET] This issue has been automatically marked as stale because it has not had 23 | recent activity. It will be closed in 14 days if no further activity occurs. Thank you 24 | for your contributions. 25 | 26 | unmarkComment: > 27 | [STALE_CLR] This issue has been removed from the stale queue. Please ensure activity to keep it opening the future. 28 | 29 | closeComment: > 30 | [STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions. 31 | 32 | -------------------------------------------------------------------------------- /.github/workflows/auto-github-actions.yml: -------------------------------------------------------------------------------- 1 | name: auto-github-actions 2 | on: [push] 3 | jobs: 4 | check-bats-version: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v3 8 | - uses: actions/setup-node@v3 9 | with: 10 | node-version: '14' 11 | - run: npm install -g bats 12 | - run: bats -v 13 | -------------------------------------------------------------------------------- /.github/workflows/report-size-deltas.yml: -------------------------------------------------------------------------------- 1 | name: Report Size Deltas 2 | 3 | on: 4 | schedule: 5 | - cron: '*/5 * * * *' 6 | 7 | jobs: 8 | report: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Comment size deltas reports to PRs 13 | uses: arduino/report-size-deltas@v1 14 | with: 15 | # The name of the workflow artifact created by the "Compile Examples" workflow 16 | sketches-reports-source: sketches-reports 17 | -------------------------------------------------------------------------------- /.github/workflows/spell-check.yml: -------------------------------------------------------------------------------- 1 | name: Spell Check 2 | 3 | on: 4 | pull_request: 5 | push: 6 | schedule: 7 | # run every Tuesday at 3 AM UTC 8 | - cron: "0 3 * * 2" 9 | workflow_dispatch: 10 | repository_dispatch: 11 | 12 | jobs: 13 | spellcheck: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@v3 19 | 20 | # See: https://github.com/codespell-project/actions-codespell/blob/master/README.md 21 | - name: Spell check 22 | uses: codespell-project/actions-codespell@master 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | .vscode/ 35 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing to ESP_WiFiManager_Lite 2 | 3 | ### Reporting Bugs 4 | 5 | Please report bugs in [ESP_WiFiManager_Lite](https://github.com/khoih-prog/ESP_WiFiManager_Lite/issues/new) if you find them. 6 | 7 | However, before reporting a bug please check through the following: 8 | 9 | * [Existing Open Issues](https://github.com/khoih-prog/ESP_WiFiManager_Lite/issues) - someone might have already encountered this. 10 | 11 | If you don't find anything, please [open a new issue](https://github.com/khoih-prog/ESP_WiFiManager_Lite/issues/new). 12 | 13 | --- 14 | 15 | ### How to submit a bug report 16 | 17 | Please ensure to specify the following: 18 | 19 | * Arduino IDE version (e.g. 1.8.19) or Platform.io version 20 | * `ESP8266` or `ESP32` Core Version (e.g. ESP8266 core v3.1.1 or ESP32 v2.0.6) 21 | * Contextual information (e.g. what you were trying to achieve) 22 | * Simplest possible steps to reproduce 23 | * Anything that might be relevant in your opinion, such as: 24 | * Operating system (Windows, Ubuntu, etc.) and the output of `uname -a` 25 | * Network configuration 26 | 27 | Please be educated, civilized and constructive as you've always been. Disrespective posts against [GitHub Code of Conduct](https://docs.github.com/en/site-policy/github-terms/github-event-code-of-conduct) will be ignored and deleted. 28 | 29 | --- 30 | 31 | ### Example 32 | 33 | ``` 34 | Arduino IDE version: 1.8.19 35 | ESP8266 Core Version 3.1.1 36 | OS: Ubuntu 20.04 LTS 37 | Linux xy-Inspiron-3593 5.15.0-58-generic #64~20.04.1-Ubuntu SMP Fri Jan 6 16:42:31 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux 38 | 39 | Context: 40 | I encountered a crash while trying to use the library 41 | 42 | Steps to reproduce: 43 | 1. ... 44 | 2. ... 45 | 3. ... 46 | 4. ... 47 | ``` 48 | 49 | --- 50 | 51 | ### Sending Feature Requests 52 | 53 | Feel free to post feature requests. It's helpful if you can explain exactly why the feature would be useful. 54 | 55 | There are usually some outstanding feature requests in the [existing issues list](https://github.com/khoih-prog/ESP_WiFiManager_Lite/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement), feel free to add comments to them. 56 | 57 | --- 58 | 59 | ### Sending Pull Requests 60 | 61 | Pull Requests with changes and fixes are also welcome! 62 | 63 | Please use the `astyle` to reformat the updated library code as follows (demo for Ubuntu Linux) 64 | 65 | 1. Change directory to the library GitHub 66 | 67 | ``` 68 | xy@xy-Inspiron-3593:~$ cd Arduino/xy/ESP_WiFiManager_Lite_GitHub/ 69 | xy@xy-Inspiron-3593:~/Arduino/xy/ESP_WiFiManager_Lite_GitHub$ 70 | ``` 71 | 72 | 2. Issue astyle command 73 | 74 | ``` 75 | xy@xy-Inspiron-3593:~/Arduino/xy/ESP_WiFiManager_Lite_GitHub$ bash utils/restyle.sh 76 | ``` 77 | 78 | 79 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Khoi Hoang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## ESP_WiFiManager_Lite (Light Weight Credentials / WiFiManager for ESP32/ESP8266) 2 | 3 | [![arduino-library-badge](https://www.ardu-badge.com/badge/ESP_WiFiManager_Lite.svg?)](https://www.ardu-badge.com/ESP_WiFiManager_Lite) 4 | [![GitHub release](https://img.shields.io/github/release/khoih-prog/ESP_WiFiManager_Lite.svg)](https://github.com/khoih-prog/ESP_WiFiManager_Lite/releases) 5 | [![GitHub](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/khoih-prog/ESP_WiFiManager_Lite/blob/main/LICENSE) 6 | [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](#Contributing) 7 | [![GitHub issues](https://img.shields.io/github/issues/khoih-prog/ESP_WiFiManager_Lite.svg)](http://github.com/khoih-prog/ESP_WiFiManager_Lite/issues) 8 | 9 | Donate to my libraries using BuyMeACoffee 10 | 11 | 12 | --- 13 | --- 14 | 15 | ## Table of Contents 16 | 17 | * [Important Change from v1.9.0](#Important-Change-from-v190) 18 | * [For v1.9.0 and up](#For-v190-and-up) 19 | * [Why do we need this ESP_WiFiManager_Lite library](#why-do-we-need-this-esp_wifimanager_lite-library) 20 | * [Features](#features) 21 | * [Currently supported Boards](#currently-supported-boards) 22 | * [Changelog](changelog.md) 23 | * [Prerequisites](#prerequisites) 24 | * [Installation](#installation) 25 | * [Use Arduino Library Manager](#use-arduino-library-manager) 26 | * [Manual Install](#manual-install) 27 | * [VS Code & PlatformIO](#vs-code--platformio) 28 | * [Note for Platform IO using ESP32 LittleFS](#note-for-platform-io-using-esp32-littlefs) 29 | * [HOWTO Use analogRead() with ESP32 running WiFi and/or BlueTooth (BT/BLE)](#howto-use-analogread-with-esp32-running-wifi-andor-bluetooth-btble) 30 | * [1. ESP32 has 2 ADCs, named ADC1 and ADC2](#1-esp32-has-2-adcs-named-adc1-and-adc2) 31 | * [2. ESP32 ADCs functions](#2-esp32-adcs-functions) 32 | * [3. ESP32 WiFi uses ADC2 for WiFi functions](#3-esp32-wifi-uses-adc2-for-wifi-functions) 33 | * [How It Works](#how-it-works) 34 | * [How to use](#how-to-use) 35 | * [1. Basic usage](#1-basic-usage) 36 | * [2. Add custom parameters](#2-add-custom-parameters) 37 | * [3. Not using custom parameters](#3-not-using-custom-parameters) 38 | * [4. To open Config Portal](#4-to-open-config-portal) 39 | * [5. To use different AP WiFi Channel](#5-to-use-different-ap-wifi-channel) 40 | * [6. To use different static AP IP from default](#6-to-use-different-static-ap-ip-from-default) 41 | * [7. To use custom DHCP HostName](#7-to-use-custom-dhcp-hostname) 42 | * [8. To use custom HTML Style](#8-to-use-custom-html-style) 43 | * [9. To use custom Head Elements](#9-to-use-custom-head-elements) 44 | * [10. To use CORS Header](#10-to-use-cors-header) 45 | * [11. To use and input only one set of WiFi SSID and PWD](#11-to-use-and-input-only-one-set-of-wifi-ssid-and-pwd) 46 | * [11.1 If you need to use and input only one set of WiFi SSID/PWD](#111-if-you-need-to-use-and-input-only-one-set-of-wifi-ssidpwd) 47 | * [11.2 If you need to use both sets of WiFi SSID/PWD](#112-if-you-need-to-use-both-sets-of-wifi-ssidpwd) 48 | * [12. To enable auto-scan of WiFi networks for selection in Configuration Portal](#12-to-enable-auto-scan-of-wifi-networks-for-selection-in-configuration-portal) 49 | * [12.1 Enable auto-scan of WiFi networks for selection in Configuration Portal](#121-enable-auto-scan-of-wifi-networks-for-selection-in-configuration-portal) 50 | * [12.2 Disable manually input SSIDs](#122-disable-manually-input-ssids) 51 | * [12.3 Select maximum number of SSIDs in the list](#123-select-maximum-number-of-ssids-in-the-list) 52 | * [13. To avoid blocking in loop when WiFi is lost](#13-To-avoid-blocking-in-loop-when-wifi-is-lost) 53 | * [13.1 Max times to try WiFi per loop](#131-max-times-to-try-wifi-per-loop) 54 | * [13.2 Interval between reconnection WiFi if lost](#132-interval-between-reconnection-wifi-if-lost) 55 | * [14. Not using Board_Name on Config_Portal](#14-Not-using-Board_Name-on-Config_Portal) 56 | * [Examples](#examples) 57 | * [ 1. ESP_WiFi](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi) 58 | * [ 2. ESP_WiFi_MQTT](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi_MQTT) 59 | * [So, how it works?](#so-how-it-works) 60 | * [Important Notes](#important-notes) 61 | * [How to use default Credentials and have them pre-loaded onto Config Portal](#how-to-use-default-credentials-and-have-them-pre-loaded-onto-config-portal) 62 | * [1. To always load Default Credentials and override Config Portal data](#1-to-always-load-default-credentials-and-override-config-portal-data) 63 | * [2. To load Default Credentials when there is no valid Credentials](#2-to-load-default-credentials-when-there-is-no-valid-credentials) 64 | * [3. Example of Default Credentials](#3-example-of-default-credentials) 65 | * [How to add dynamic parameters from sketch](#how-to-add-dynamic-parameters-from-sketch) 66 | * [Important Notes for using Dynamic Parameters' ids](#important-notes-for-using-dynamic-parameters-ids) 67 | * [Example ESP_WiFi](#example-esp_wifi) 68 | * [1. File ESP_WiFi.ino](#1-file-esp_wifiino) 69 | * [2. File defines.h](#2-file-definesh) 70 | * [3. File Credentials.h](#3-file-credentialsh) 71 | * [4. File dynamicParams.h](#4-file-dynamicparamsh) 72 | * [Debug Terminal Output Samples](#debug-terminal-output-samples) 73 | * [1. ESP_WiFi on ESP32_DEV](#1-esp_wifi-on-esp32_dev) 74 | * [1.1 MRD/DRD => Open Config Portal](#11-mrddrd--open-config-portal) 75 | * [1.2 Got valid Credentials from Config Portal then connected to WiFi](#12-got-valid-credentials-from-config-portal-then-connected-to-wifi) 76 | * [1.3 Lost a WiFi and autoconnect to another WiFi AP](#13-lost-a-wifi-and-autoconnect-to-another-wifi-ap) 77 | * [2. ESP_WiFi_MQTT on ESP8266_NODEMCU](#2-esp_wifi_mqtt-on-esp8266_nodemcu) 78 | * [2.1 No Config Data => Open Config Portal](#21-no-config-data--open-config-portal) 79 | * [2.2 Got valid Credentials from Config Portal then connected to WiFi](#22-got-valid-credentials-from-config-portal-then-connected-to-wifi) 80 | * [2.3 Lost a WiFi and autoconnect to another WiFi AP](#23-lost-a-wifi-and-autoconnect-to-another-wifi-ap) 81 | * [3. ESP_WiFi_MQTT on ESP32S2_DEV](#3-esp_wifi_mqtt-on-esp32s2_dev) 82 | * [3.1 No Config Data => Open Config Portal](#31-no-config-data--open-config-portal) 83 | * [3.2 Got valid Credentials from Config Portal then connected to WiFi](#32-got-valid-credentials-from-config-portal-then-connected-to-wifi) 84 | * [3.3 Lost a WiFi and autoconnect to another WiFi AP](#33-lost-a-wifi-and-autoconnect-to-another-wifi-ap) 85 | * [4. ESP_WiFi_MQTT on ESP32S2_DEV to demo MultiResetDetector](#4-esp_wifi_mqtt-on-esp32s2_dev-to-demo-multiresetdetector) 86 | * [4.1 MultiResetDetected => Open Config Portal](#41-multiresetdetected--open-config-portal) 87 | * [4.2 Got valid Credentials from Config Portal then connected to WiFi](#42-got-valid-credentials-from-config-portal-then-connected-to-wifi) 88 | * [5. ESP_WiFi_MQTT on ESP32_DEV to demo WiFi Scan](#5-esp_wifi_mqtt-on-esp32_dev-to-demo-wifi-scan) 89 | * [5.1 MRD/DRD => Open Config Portal](#51-mrddrd--open-config-portal) 90 | * [5.2 Config Data Saved => Connection to Adafruit MQTT](#52-config-data-saved--connection-to-adafruit-mqtt) 91 | * [6. ESP_WiFi on ESP32S3_DEV](#6-ESP_WiFi-on-ESP32S3_DEV) **New** 92 | * [7. ESP_WiFi on ESP32C3_DEV using LittleFS](#7-ESP_WiFi-on-ESP32C3_DEV-using-LittleFS) **New** 93 | * [Debug](#debug) 94 | * [Troubleshooting](#troubleshooting) 95 | * [Issues](#issues) 96 | * [TO DO](#to-do) 97 | * [DONE](#done) 98 | * [Contributions and Thanks](#contributions-and-thanks) 99 | * [Contributing](#contributing) 100 | * [License](#license) 101 | * [Copyright](#copyright) 102 | 103 | --- 104 | --- 105 | 106 | ### Important Change from v1.9.0 107 | 108 | #### For v1.9.0 and up 109 | 110 | ESP32 `chipID` is now correct and unique. The previous releases' 32-bit wrong `chipID` is mainly the 24-bit `Organizational Unique Identifier` (OUI) plus 8 bits from the correct chipID. That's why `ESP_getChipId()` function can return duplicated values if the boards are from the same batch. 111 | 112 | For example 113 | 114 | ``` 115 | Chip_ID_64 : 0x98F4AB085288 116 | chipOUI : 0x98F4AB 117 | chipId : 0x85288 118 | getEfuseMac: 0x885208ABF498 119 | ``` 120 | 121 | --- 122 | --- 123 | 124 | ### Why do we need this [ESP_WiFiManager_Lite library](https://github.com/khoih-prog/ESP_WiFiManager_Lite) 125 | 126 | #### Features 127 | 128 | If you have used one of the full-fledge WiFiManagers such as : 129 | 130 | 1. [`Tzapu WiFiManager`](https://github.com/tzapu/WiFiManager) 131 | 2. [`Ken Taylor WiFiManager`](https://github.com/kentaylor/WiFiManager) 132 | 3. [`Khoi Hoang ESP_WiFiManager`](https://github.com/khoih-prog/ESP_WiFiManager) 133 | 134 | and have to write **complicated callback functions** to save custom parameters in SPIFFS/LittleFS/EEPROM, you'd appreciate the simplicity of this Light-Weight Credentials / WiFiManager. 135 | 136 | This is a Credentials / WiFi Connection Manager for ESP32 and ESP8266 boards, permitting the addition of custom parameters to be configured in Config Portal. The parameters then will be saved automatically, **without the complicated callback functions** to handle data saving / retrieving. 137 | 138 | You can also specify DHCP HostName, static AP and STA IP. Use much less memory compared to full-fledge WiFiManager. Config Portal will be auto-adjusted to match the number of dynamic custom parameters. Credentials are saved in LittleFS, SPIFFS or EEPROM. 139 | 140 | The web configuration portal, served from the `ESP32/ESP8266 WiFi` is operating as an access point (AP) with configurable static IP address or use default IP Address of 192.168.4.1 141 | 142 | New recent features: 143 | 144 | - **MultiWiFi** feature for configuring/auto(re)connecting **ESP32/ESP8266 WiFi** to the available MultiWiFi APs at runtime. 145 | - **Multi/DoubleDetectDetector** feature to force Config Portal when multi/double reset is detected within predetermined time, default 10s. 146 | - **Powerful-yet-simple-to-use feature to enable adding dynamic custom parameters** from sketch and input using the same Config Portal. Config Portal will be auto-adjusted to match the number of dynamic parameters. 147 | - Optional default **Credentials as well as Dynamic parameters to be optionally autoloaded into Config Portal** to use or change instead of manually input. 148 | - Dynamic custom parameters to be saved **automatically in non-volatile memory, such as LittleFS, SPIFFS or EEPROM.**. 149 | - Configurable **Config Portal Title** to be either BoardName or default undistinguishable names. 150 | - Examples are designed to separate Credentials / Defines / Dynamic Params / Code so that you can change Credentials / Dynamic Params quickly for each device. 151 | - Control Config Portal from software or Virtual Switches 152 | - To permit autoreset after configurable timeout if DRD/MRD or non-persistent forced-CP 153 | - Use new ESP32 LittleFS features 154 | - **Scan WiFi networks** for selection in Configuration Portal 155 | 156 | 157 | #### Currently supported Boards 158 | 159 | This [**ESP_WiFiManager_Lite** library](https://github.com/khoih-prog/ESP_WiFiManager_Lite) currently supports these following boards: 160 | 161 | 1. **ESP8266 and ESP32-based boards using EEPROM, SPIFFS or LittleFS**. 162 | 2. **ESP32-S2 (ESP32-S2 Saola, AI-Thinker ESP-12K, etc.) using EEPROM, SPIFFS or LittleFS**. 163 | 3. **ESP32-C3 (ARDUINO_ESP32C3_DEV) using EEPROM, SPIFFS or LittleFS**. 164 | 4. **ESP32-S3 (ESP32S3_DEV, ESP32_S3_BOX, UM TINYS3, UM PROS3, UM FEATHERS3, etc.) using EEPROM, SPIFFS or LittleFS**. 165 | 166 | --- 167 | --- 168 | 169 | ## Prerequisites 170 | 171 | 1. [`Arduino IDE 1.8.19+` for Arduino](https://github.com/arduino/Arduino). [![GitHub release](https://img.shields.io/github/release/arduino/Arduino.svg)](https://github.com/arduino/Arduino/releases/latest) 172 | 2. [`ESP32 Core 2.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/) 173 | 3. [`ESP8266 Core 3.1.1+`](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/). SPIFFS is deprecated from ESP8266 core 2.7.1+, to use LittleFS. 174 | 4. [`ESP_DoubleResetDetector v1.3.2+`](https://github.com/khoih-prog/ESP_DoubleResetDetector) if using DRD feature. To install, check [![arduino-library-badge](https://www.ardu-badge.com/badge/ESP_DoubleResetDetector.svg?)](https://www.ardu-badge.com/ESP_DoubleResetDetector). 175 | 5. [`ESP_MultiResetDetector v1.3.2+`](https://github.com/khoih-prog/ESP_MultiResetDetector) if using MRD feature. To install, check [![arduino-library-badge](https://www.ardu-badge.com/badge/ESP_MultiResetDetector.svg?)](https://www.ardu-badge.com/ESP_MultiResetDetector). 176 | 6. [`LittleFS_esp32 v1.0.6+`](https://github.com/lorol/LITTLEFS) for ESP32-based boards using LittleFS with ESP32 core **v1.0.5-**. To install, check [![arduino-library-badge](https://www.ardu-badge.com/badge/LittleFS_esp32.svg?)](https://www.ardu-badge.com/LittleFS_esp32). **Notice**: This [`LittleFS_esp32 library`](https://github.com/lorol/LITTLEFS) has been integrated to Arduino [ESP32 core v1.0.6+](https://github.com/espressif/arduino-esp32/tree/master/libraries/LITTLEFS) and **you don't need to install it if using ESP32 core v1.0.6+** 177 | 178 | --- 179 | 180 | ## Installation 181 | 182 | ### Use Arduino Library Manager 183 | 184 | The best and easiest way is to use `Arduino Library Manager`. Search for [**ESP_WiFiManager_Lite**](https://github.com/khoih-prog/ESP_WiFiManager_Lite), then select / install the latest version. 185 | You can also use this link [![arduino-library-badge](https://www.ardu-badge.com/badge/ESP_WiFiManager_Lite.svg?)](https://www.ardu-badge.com/ESP_WiFiManager_Lite) for more detailed instructions. 186 | 187 | ### Manual Install 188 | 189 | 1. Navigate to [**ESP_WiFiManager_Lite**](https://github.com/khoih-prog/ESP_WiFiManager_Lite) page. 190 | 2. Download the latest release `ESP_WiFiManager_Lite-main.zip`. 191 | 3. Extract the zip file to `ESP_WiFiManager_Lite-main` directory 192 | 4. Copy the whole 193 | - `ESP_WiFiManager_Lite-main` folder to Arduino libraries' directory such as `~/Arduino/libraries/`. 194 | 195 | ### VS Code & PlatformIO: 196 | 197 | 1. Install [VS Code](https://code.visualstudio.com/) 198 | 2. Install [PlatformIO](https://platformio.org/platformio-ide) 199 | 3. Install [**ESP_WiFiManager_Lite** library](https://registry.platformio.org/libraries/khoih-prog/ESP_WiFiManager_Lite) by using [Library Manager](https://registry.platformio.org/libraries/khoih-prog/ESP_WiFiManager_Lite/installation). Search for **ESP_WiFiManager_Lite** in [Platform.io Author's Libraries](https://platformio.org/lib/search?query=author:%22Khoi%20Hoang%22) 200 | 4. Use included [platformio.ini](platformio/platformio.ini) file from examples to ensure that all dependent libraries will installed automatically. Please visit documentation for the other options and examples at [Project Configuration File](https://docs.platformio.org/page/projectconf.html) 201 | 202 | 203 | --- 204 | --- 205 | 206 | 207 | ### Note for Platform IO using ESP32 LittleFS 208 | 209 | #### Necessary only for esp32 core v1.0.6- 210 | 211 | 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. 212 | 213 | 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 214 | 215 | from 216 | 217 | ```cpp 218 | //#define CONFIG_LITTLEFS_FOR_IDF_3_2 /* For old IDF - like in release 1.0.4 */ 219 | ``` 220 | 221 | to 222 | 223 | ```cpp 224 | #define CONFIG_LITTLEFS_FOR_IDF_3_2 /* For old IDF - like in release 1.0.4 */ 225 | ``` 226 | 227 | It's advisable to use the latest [`LittleFS_esp32 v1.0.5+`](https://github.com/lorol/LITTLEFS) to avoid the issue. 228 | 229 | Thanks to [Roshan](https://github.com/solroshan) to report the issue in [Error esp_littlefs.c 'utime_p'](https://github.com/khoih-prog/ESPAsync_WiFiManager/issues/28) 230 | 231 | --- 232 | --- 233 | 234 | ### HOWTO Use analogRead() with ESP32 running WiFi and/or BlueTooth (BT/BLE) 235 | 236 | Please have a look at [**ESP_WiFiManager Issue 39: Not able to read analog port when using the autoconnect example**](https://github.com/khoih-prog/ESP_WiFiManager/issues/39) to have more detailed description and solution of the issue. 237 | 238 | #### 1. ESP32 has 2 ADCs, named ADC1 and ADC2 239 | 240 | #### 2. ESP32 ADCs functions 241 | 242 | - `ADC1` controls ADC function for pins **GPIO32-GPIO39** 243 | - `ADC2` controls ADC function for pins **GPIO0, 2, 4, 12-15, 25-27** 244 | 245 | #### 3.. ESP32 WiFi uses ADC2 for WiFi functions 246 | 247 | Look in file [**adc_common.c**](https://github.com/espressif/esp-idf/blob/master/components/driver/adc_common.c#L61) 248 | 249 | > In `ADC2`, there're two locks used for different cases: 250 | > 1. lock shared with app and Wi-Fi: 251 | > ESP32: 252 | > When Wi-Fi using the `ADC2`, we assume it will never stop, so app checks the lock and returns immediately if failed. 253 | > ESP32S2: 254 | > The controller's control over the `ADC` is determined by the arbiter. There is no need to control by lock. 255 | > 256 | > 2. lock shared between tasks: 257 | > when several tasks sharing the `ADC2`, we want to guarantee 258 | > all the requests will be handled. 259 | > Since conversions are short (about 31us), app returns the lock very soon, 260 | > we use a spinlock to stand there waiting to do conversions one by one. 261 | > 262 | > adc2_spinlock should be acquired first, then adc2_wifi_lock or rtc_spinlock. 263 | 264 | 265 | - In order to use `ADC2` for other functions, we have to **acquire complicated firmware locks and very difficult to do** 266 | - So, it's not advisable to use `ADC2` with WiFi/BlueTooth (BT/BLE). 267 | - Use `ADC1`, and pins GPIO32-GPIO39 268 | - If somehow it's a must to use those pins serviced by `ADC2` (**GPIO0, 2, 4, 12, 13, 14, 15, 25, 26 and 27**), use the **fix mentioned at the end** of [**ESP_WiFiManager Issue 39: Not able to read analog port when using the autoconnect example**](https://github.com/khoih-prog/ESP_WiFiManager/issues/39) to work with ESP32 WiFi/BlueTooth (BT/BLE). 269 | 270 | 271 | --- 272 | --- 273 | 274 | ## How It Works 275 | 276 | - The [**ESP_WiFi**](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi) example shows how it works and should be used as the basis for a sketch that uses this library. 277 | - The concept of [**ESP_WiFi**](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi) is that a new `ESP32/ESP8266 WiFi` will start a WiFi configuration portal when powered up, but has no valid stored Credentials or can't connect to WiFi APs after a pre-determined time. 278 | - There are 6 more custom parameters added in the sketch which you can use in your program later. In the example, they are: 2 sets of Blynk Servers and Tokens, Blynk Port and MQTT Server. 279 | - Using any WiFi enabled device with a browser (computer, phone, tablet) connect to the newly created AP and type in the configurable AP IP address (default 192.168.4.1). The Config Portal AP channel (default 10) is also configurable to avoid conflict with other APs. 280 | - The Config Portal is **auto-adjusted** to fix the 4 static parameters (WiFi SSIDs/PWDs) as well as 6 more dynamic custom parameters. 281 | - After the custom data entered, and **Save** button pressed, the configuration data will be saved in host's non-volatile memory, then the board reboots. 282 | - If there is valid stored Credentials, it'll go directly to connect to one of the **MultiWiFi APs** without starting / using the Config Portal. 283 | - `ESP32/ESP8266 WiFi` will try to connect. If successful, the dynamic DHCP and/or configured static IP address will be displayed in the configuration portal. 284 | - The `ESP32/ESP8266 WiFi` Config Portal network and Web Server will shutdown to return control to the sketch code. 285 | - In the operation, if the current WiFi connection is lost because of any reason, the system will **auto(Re)connect** to the remaining WiFi AP. 286 | - **If system can't connect to any of the 2 WiFi APs, the Config Portal will start**, after some pre-determined time, to permit user to update the Credentials. 287 | 288 | --- 289 | --- 290 | 291 | ### How to use 292 | 293 | #### 1. Basic usage 294 | 295 | - Include in your sketch 296 | 297 | ```cpp 298 | // Must be before #include 299 | #include 300 | 301 | ESP_WiFiManager_Lite* ESP_WiFiManager; 302 | ``` 303 | 304 | #### 2. Add custom parameters 305 | 306 | - To add custom parameters, just add 307 | 308 | ```cpp 309 | #include "defines.h" 310 | 311 | // USE_DYNAMIC_PARAMETERS defined in defined.h 312 | 313 | /////////////// Start dynamic Credentials /////////////// 314 | 315 | //Defined in 316 | /************************************** 317 | #define MAX_ID_LEN 5 318 | #define MAX_DISPLAY_NAME_LEN 16 319 | 320 | typedef struct 321 | { 322 | char id [MAX_ID_LEN + 1]; 323 | char displayName [MAX_DISPLAY_NAME_LEN + 1]; 324 | char *pdata; 325 | uint8_t maxlen; 326 | } MenuItem; 327 | **************************************/ 328 | 329 | #if USE_DYNAMIC_PARAMETERS 330 | 331 | #define MAX_BLYNK_SERVER_LEN 34 332 | #define MAX_BLYNK_TOKEN_LEN 34 333 | 334 | char Blynk_Server1 [MAX_BLYNK_SERVER_LEN + 1] = "account.duckdns.org"; 335 | char Blynk_Token1 [MAX_BLYNK_TOKEN_LEN + 1] = "token1"; 336 | 337 | char Blynk_Server2 [MAX_BLYNK_SERVER_LEN + 1] = "account.ddns.net"; 338 | char Blynk_Token2 [MAX_BLYNK_TOKEN_LEN + 1] = "token2"; 339 | 340 | #define MAX_BLYNK_PORT_LEN 6 341 | char Blynk_Port [MAX_BLYNK_PORT_LEN + 1] = "8080"; 342 | 343 | #define MAX_MQTT_SERVER_LEN 34 344 | char MQTT_Server [MAX_MQTT_SERVER_LEN + 1] = "mqtt.duckdns.org"; 345 | 346 | MenuItem myMenuItems [] = 347 | { 348 | { "sv1", "Blynk Server1", Blynk_Server1, MAX_BLYNK_SERVER_LEN }, 349 | { "tk1", "Token1", Blynk_Token1, MAX_BLYNK_TOKEN_LEN }, 350 | { "sv2", "Blynk Server2", Blynk_Server2, MAX_BLYNK_SERVER_LEN }, 351 | { "tk2", "Token2", Blynk_Token2, MAX_BLYNK_TOKEN_LEN }, 352 | { "prt", "Port", Blynk_Port, MAX_BLYNK_PORT_LEN }, 353 | { "mqt", "MQTT Server", MQTT_Server, MAX_MQTT_SERVER_LEN }, 354 | }; 355 | 356 | uint16_t NUM_MENU_ITEMS = sizeof(myMenuItems) / sizeof(MenuItem); //MenuItemSize; 357 | 358 | #else 359 | 360 | MenuItem myMenuItems [] = {}; 361 | 362 | uint16_t NUM_MENU_ITEMS = 0; 363 | 364 | #endif //USE_DYNAMIC_PARAMETERS 365 | 366 | ``` 367 | 368 | #### 3. Not using custom parameters 369 | 370 | - If you don't need to add dynamic parameters, use the following in sketch 371 | 372 | ```cpp 373 | #define USE_DYNAMIC_PARAMETERS false 374 | ``` 375 | 376 | #### 4. To open Config Portal 377 | 378 | - When you want to open a config portal, just add 379 | 380 | ```cpp 381 | ESP_WiFiManager = new ESP_WiFiManager_Lite(); 382 | ESP_WiFiManager->begin(); 383 | ``` 384 | 385 | #### 5. To use different AP WiFi Channel 386 | 387 | - To not use default AP WiFi Channel 10 to avoid conflict with other WiFi APs : 388 | 389 | ```cpp 390 | ESP_WiFiManager->setConfigPortalChannel(newChannel); 391 | ``` 392 | 393 | - To use random AP WiFi Channel to avoid conflict with other WiFi APs : 394 | 395 | ```cpp 396 | ESP_WiFiManager->setConfigPortalChannel(0); 397 | ``` 398 | 399 | #### 6. To use different static AP IP from default 400 | 401 | - To use different static AP IP (not use default `192.168.4.1`), call 402 | 403 | ```cpp 404 | ESP_WiFiManager->setConfigPortalIP(IPAddress(xxx,xxx,xxx,xxx)); 405 | ``` 406 | 407 | #### 7. To use custom DHCP HostName 408 | 409 | - To set custom DHCP HostName : 410 | 411 | ```cpp 412 | // Set customized DHCP HostName 413 | ESP_WiFiManager->begin("ESP32-WIFI_ABCDEF"); 414 | ``` 415 | 416 | or just use the default Hostname, for example "ESP_ABCDEF" 417 | 418 | ```cpp 419 | //Or use default Hostname "ESPC_ABCDEF" 420 | ESP_WiFiManager->begin(); 421 | ``` 422 | 423 | #### 8. To use custom HTML Style 424 | 425 | ```cpp 426 | const char NewCustomsStyle[] /*PROGMEM*/ = ""; 428 | 429 | ... 430 | 431 | ESP_WiFiManager->setCustomsStyle(NewCustomsStyle); 432 | ``` 433 | 434 | #### 9. To use custom Head Elements 435 | 436 | 437 | ```cpp 438 | ESP_WiFiManager->setCustomsHeadElement(""); 439 | ``` 440 | 441 | #### 10. To use CORS Header 442 | 443 | ```cpp 444 | ESP_WiFiManager->setCORSHeader("Your Access-Control-Allow-Origin"); 445 | ``` 446 | 447 | 448 | While in AP mode, connect to it using its `SSID` (ESP_ABCDEF) / `Password` ("MyESP_ABCDEF"), then open a browser to the Portal AP IP, default `192.168.4.1`, configure wifi then click **Save**. The Credentials / WiFi connection information will be saved in non-volatile memory. It will then autoconnect. 449 | 450 | 451 | Once Credentials / WiFi network information is saved in the host non-volatile memory, it will try to autoconnect to WiFi every time it is started, without requiring any function calls in the sketch. 452 | 453 | 454 | #### 11. To use and input only one set of WiFi SSID and PWD 455 | 456 | #### 11.1 If you need to use and input only one set of WiFi SSID/PWD 457 | 458 | ```cpp 459 | // Permit input only one set of WiFi SSID/PWD. The other can be "NULL or "blank" 460 | // Default is false (if not defined) => must input 2 sets of SSID/PWD 461 | #define REQUIRE_ONE_SET_SSID_PW true 462 | ``` 463 | But it's always advisable to use and input both sets for reliability. 464 | 465 | #### 11.2 If you need to use both sets of WiFi SSID/PWD 466 | 467 | ```cpp 468 | // Permit input only one set of WiFi SSID/PWD. The other can be "NULL or "blank" 469 | // Default is false (if not defined) => must input 2 sets of SSID/PWD 470 | #define REQUIRE_ONE_SET_SSID_PW false 471 | ``` 472 | 473 | #### 12. To enable auto-scan of WiFi networks for selection in Configuration Portal 474 | 475 | #### 12.1 Enable auto-scan of WiFi networks for selection in Configuration Portal 476 | 477 | 478 | ```cpp 479 | #define SCAN_WIFI_NETWORKS true 480 | ``` 481 | 482 | The manual input of SSIDs is default enabled, so that users can input arbitrary SSID, not only from the scanned list. This is for the sample use-cases in which users can input the known SSIDs of another place, then send the boards to that place. The boards can connect to WiFi without users entering Config Portal to re-configure. 483 | 484 | #### 12.2 Disable manually input SSIDs 485 | 486 | ```cpp 487 | // To disable manually input SSID, only from a scanned SSID lists 488 | #define MANUAL_SSID_INPUT_ALLOWED false 489 | ``` 490 | 491 | This is for normal use-cases in which users can only select an SSID from a scanned list of SSIDs to avoid typo mistakes and/or security. 492 | 493 | #### 12.3 Select maximum number of SSIDs in the list 494 | 495 | The maximum number of SSIDs in the list is seletable from 2 to 15. If invalid number of SSIDs is selected, the default number of 10 will be used. 496 | 497 | 498 | ```cpp 499 | // From 2-15 500 | #define MAX_SSID_IN_LIST 8 501 | ``` 502 | 503 | #### 13. To avoid blocking in loop when WiFi is lost 504 | 505 | #### 13.1 Max times to try WiFi per loop 506 | 507 | To define max times to try WiFi per loop() iteration. To avoid blocking issue in loop() 508 | 509 | Default is 1 if not defined, and minimum is forced to be 1. 510 | 511 | To use, uncomment in `defines.h`. 512 | 513 | Check [retries block the main loop #18](https://github.com/khoih-prog/WiFiManager_NINA_Lite/issues/18#issue-1094004380) 514 | 515 | ```cpp 516 | #define MAX_NUM_WIFI_RECON_TRIES_PER_LOOP 2 517 | ``` 518 | 519 | #### 13.2 Interval between reconnection WiFi if lost 520 | 521 | Default is no interval between reconnection WiFi times if lost WiFi. Max permitted interval will be 10mins. 522 | 523 | Uncomment to use. Be careful, WiFi reconnection will be delayed if using this method. 524 | 525 | Only use whenever urgent tasks in loop() can't be delayed. But if so, it's better you have to rewrite your code, e.g. using higher priority tasks. 526 | 527 | Check [retries block the main loop #18](https://github.com/khoih-prog/WiFiManager_NINA_Lite/issues/18#issuecomment-1006197561) 528 | 529 | ```cpp 530 | #define WIFI_RECON_INTERVAL 30000 // 30s 531 | ``` 532 | 533 | #### 14. Not using Board_Name on Config_Portal 534 | 535 | Default is `true`. Just change to `false` to not using `Board_Name` on Config_Portal 536 | 537 | https://github.com/khoih-prog/ESP_WiFiManager_Lite/blob/ce798e201dc1e895ca952ca212123b7091323a99/examples/ESP_WiFi/defines.h#L125-L130 538 | 539 | 540 | --- 541 | --- 542 | 543 | ### Examples 544 | 545 | 1. [ESP_WiFi](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi) 546 | 2. [ESP_WiFi_MQTT](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi_MQTT) 547 | 548 | --- 549 | --- 550 | 551 | ## So, how it works? 552 | 553 | In `Configuration Portal Mode`, it starts an AP called `ESP_ABCDEF`. Connect to it using the `configurable password` you can define in the code. For example, `MyESP_ABCDEF` (see examples): 554 | 555 | After you connected, please, go to http://192.168.4.1 or newly configured AP IP, you'll see this `Main` page: 556 | 557 |

558 | 559 |

560 | 561 | Enter your credentials, 562 | 563 | ### 1. Without SCAN_WIFI_NETWORKS 564 | 565 | Enter your credentials, 566 | 567 |

568 | 569 |

570 | 571 | or 572 | 573 |

574 | 575 |

576 | 577 | ### 2. With SCAN_WIFI_NETWORKS 578 | 579 | 580 |

581 | 582 |

583 | 584 | 585 | then click `Save`. 586 | 587 |

588 | 589 |

590 | 591 | The WiFi Credentials will be saved and the board connect to the selected WiFi AP. 592 | 593 | If you're already connected to a listed WiFi AP and don't want to change anything, just select `Exit` from the `Main` page to reboot the board and connect to the previously-stored AP. The WiFi Credentials are still intact. 594 | 595 | --- 596 | 597 | ### Important Notes 598 | 599 | 1. Now you can use special chars such as **~, !, @, #, $, %, ^, &, _, -, space,etc.** thanks to [brondolin](https://github.com/brondolin) to provide the amazing fix in [**No save the char # at end of the wifi password**](https://github.com/khoih-prog/Blynk_WM/issues/3) to permit input special chars such as **%** and **#** into data fields. 600 | 2. The SSIDs, Passwords must be input (or to make them different from **blank**). Otherwise, the Config Portal will re-open until those fields have been changed. If you don't need any field, just input anything or use duplicated data from similar field. 601 | 3. WiFi password min length now is 8, max length is 63 chars according to WPA2 standard. 602 | 603 | --- 604 | 605 | ### How to use default Credentials and have them pre-loaded onto Config Portal 606 | 607 | See this example and modify as necessary 608 | 609 | #### 1. To always load [Default Credentials](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples//Credentials.h) and override Config Portal data 610 | 611 | ```cpp 612 | // Used mostly for development and debugging. FORCES default values to be loaded each run. 613 | // Config Portal data input will be ignored and overridden by DEFAULT_CONFIG_DATA 614 | bool LOAD_DEFAULT_CONFIG_DATA = true; 615 | ``` 616 | 617 | #### 2. To load [Default Credentials](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples//Credentials.h) when there is no valid Credentials. 618 | 619 | Config Portal data input will be override DEFAULT_CONFIG_DATA 620 | 621 | ```cpp 622 | // Used mostly once debugged. Assumes good data already saved in device. 623 | // Config Portal data input will be override DEFAULT_CONFIG_DATA 624 | bool LOAD_DEFAULT_CONFIG_DATA = false; 625 | ``` 626 | 627 | #### 3. Example of [Default Credentials](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi/Credentials.h) 628 | 629 | ```cpp 630 | /// Start Default Config Data ////////////////// 631 | 632 | /* 633 | #define SSID_MAX_LEN 32 634 | //From v1.0.3, WPA2 passwords can be up to 63 characters long. 635 | #define PASS_MAX_LEN 64 636 | 637 | typedef struct 638 | { 639 | char wifi_ssid[SSID_MAX_LEN]; 640 | char wifi_pw [PASS_MAX_LEN]; 641 | } WiFi_Credentials; 642 | 643 | #define NUM_WIFI_CREDENTIALS 2 644 | 645 | // Configurable items besides fixed Header, just add board_name 646 | #define NUM_CONFIGURABLE_ITEMS ( ( 2 * NUM_WIFI_CREDENTIALS ) + 1 ) 647 | //////////////// 648 | 649 | typedef struct Configuration 650 | { 651 | char header [16]; 652 | WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS]; 653 | char board_name [24]; 654 | int checkSum; 655 | } ESP_WM_LITE_Configuration; 656 | */ 657 | 658 | #define TO_LOAD_DEFAULT_CONFIG_DATA false 659 | 660 | #if TO_LOAD_DEFAULT_CONFIG_DATA 661 | 662 | // This feature is primarily used in development to force a known set of values as Config Data 663 | // It will NOT force the Config Portal to activate. Use DRD or erase Config Data with ESP_WiFiManager.clearConfigData() 664 | 665 | // Used mostly for development and debugging. FORCES default values to be loaded each run. 666 | // Config Portal data input will be ignored and overridden by DEFAULT_CONFIG_DATA 667 | //bool LOAD_DEFAULT_CONFIG_DATA = true; 668 | 669 | // Used mostly once debugged. Assumes good data already saved in device. 670 | // Config Portal data input will be override DEFAULT_CONFIG_DATA 671 | bool LOAD_DEFAULT_CONFIG_DATA = false; 672 | 673 | 674 | ESP_WM_LITE_Configuration defaultConfig = 675 | { 676 | //char header[16], dummy, not used 677 | #if ESP8266 678 | "ESP8266", 679 | #else 680 | "ESP32", 681 | #endif 682 | 683 | // WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS]; 684 | // WiFi_Credentials.wifi_ssid and WiFi_Credentials.wifi_pw 685 | "SSID1", "password1", 686 | "SSID2", "password2", 687 | //char board_name [24]; 688 | 689 | #if ESP8266 690 | "ESP8266-Control", 691 | #else 692 | "ESP32-Control", 693 | #endif 694 | 695 | // terminate the list 696 | //int checkSum, dummy, not used 697 | 0 698 | /////////// End Default Config Data ///////////// 699 | }; 700 | 701 | #else 702 | 703 | bool LOAD_DEFAULT_CONFIG_DATA = false; 704 | 705 | ESP_WM_LITE_Configuration defaultConfig; 706 | 707 | #endif // TO_LOAD_DEFAULT_CONFIG_DATA 708 | 709 | /////////// End Default Config Data ///////////// 710 | ``` 711 | 712 | ### How to add dynamic parameters from sketch 713 | 714 | Example of [Default dynamicParams](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi/dynamicParams.h) 715 | 716 | - To add custom parameters, just modify the example below 717 | 718 | ```cpp 719 | #include "defines.h" 720 | 721 | // USE_DYNAMIC_PARAMETERS defined in defined.h 722 | 723 | /////////////// Start dynamic Credentials /////////////// 724 | 725 | //Defined in 726 | /************************************** 727 | #define MAX_ID_LEN 5 728 | #define MAX_DISPLAY_NAME_LEN 16 729 | 730 | typedef struct 731 | { 732 | char id [MAX_ID_LEN + 1]; 733 | char displayName [MAX_DISPLAY_NAME_LEN + 1]; 734 | char *pdata; 735 | uint8_t maxlen; 736 | } MenuItem; 737 | **************************************/ 738 | 739 | #if USE_DYNAMIC_PARAMETERS 740 | 741 | #define MAX_BLYNK_SERVER_LEN 34 742 | #define MAX_BLYNK_TOKEN_LEN 34 743 | 744 | char Blynk_Server1 [MAX_BLYNK_SERVER_LEN + 1] = "account.duckdns.org"; 745 | char Blynk_Token1 [MAX_BLYNK_TOKEN_LEN + 1] = "token1"; 746 | 747 | char Blynk_Server2 [MAX_BLYNK_SERVER_LEN + 1] = "account.ddns.net"; 748 | char Blynk_Token2 [MAX_BLYNK_TOKEN_LEN + 1] = "token2"; 749 | 750 | #define MAX_BLYNK_PORT_LEN 6 751 | char Blynk_Port [MAX_BLYNK_PORT_LEN + 1] = "8080"; 752 | 753 | #define MAX_MQTT_SERVER_LEN 34 754 | char MQTT_Server [MAX_MQTT_SERVER_LEN + 1] = "mqtt.duckdns.org"; 755 | 756 | MenuItem myMenuItems [] = 757 | { 758 | { "sv1", "Blynk Server1", Blynk_Server1, MAX_BLYNK_SERVER_LEN }, 759 | { "tk1", "Token1", Blynk_Token1, MAX_BLYNK_TOKEN_LEN }, 760 | { "sv2", "Blynk Server2", Blynk_Server2, MAX_BLYNK_SERVER_LEN }, 761 | { "tk2", "Token2", Blynk_Token2, MAX_BLYNK_TOKEN_LEN }, 762 | { "prt", "Port", Blynk_Port, MAX_BLYNK_PORT_LEN }, 763 | { "mqt", "MQTT Server", MQTT_Server, MAX_MQTT_SERVER_LEN }, 764 | }; 765 | 766 | uint16_t NUM_MENU_ITEMS = sizeof(myMenuItems) / sizeof(MenuItem); //MenuItemSize; 767 | 768 | #else 769 | 770 | MenuItem myMenuItems [] = {}; 771 | 772 | uint16_t NUM_MENU_ITEMS = 0; 773 | 774 | #endif //USE_DYNAMIC_PARAMETERS 775 | 776 | ``` 777 | - If you don't need to add dynamic parameters, use the following in sketch 778 | 779 | ```cpp 780 | #define USE_DYNAMIC_PARAMETERS false 781 | ``` 782 | 783 | or 784 | 785 | ```cpp 786 | /////////////// Start dynamic Credentials /////////////// 787 | 788 | MenuItem myMenuItems [] = {}; 789 | 790 | uint16_t NUM_MENU_ITEMS = 0; 791 | /////// // End dynamic Credentials /////////// 792 | 793 | ``` 794 | --- 795 | 796 | ### Important Notes for using Dynamic Parameters' ids 797 | 798 | 1. These ids (such as "mqtt" in example) must be **unique**. 799 | 800 | Please be noted that the following **reserved names are already used in library**: 801 | 802 | ``` 803 | "id" for WiFi SSID 804 | "pw" for WiFi PW 805 | "id1" for WiFi1 SSID 806 | "pw1" for WiFi1 PW 807 | "nm" for Board Name 808 | ``` 809 | --- 810 | --- 811 | 812 | ### Example [ESP_WiFi](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi) 813 | 814 | Please take a look at other examples, as well. 815 | 816 | #### 1. File [ESP_WiFi.ino](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi/ESP_WiFi.ino) 817 | 818 | https://github.com/khoih-prog/ESP_WiFiManager_Lite/blob/bc8fb7ed5159e78f4cba35e07bf8cb18a7925320/examples/ESP_WiFi/ESP_WiFi.ino#L13-L156 819 | 820 | 821 | --- 822 | 823 | #### 2. File [defines.h](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi/defines.h) 824 | 825 | https://github.com/khoih-prog/ESP_WiFiManager_Lite/blob/bc8fb7ed5159e78f4cba35e07bf8cb18a7925320/examples/ESP_WiFi/defines.h#L13-L150 826 | 827 | --- 828 | 829 | #### 3. File [Credentials.h](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi/Credentials.h) 830 | 831 | https://github.com/khoih-prog/ESP_WiFiManager_Lite/blob/bc8fb7ed5159e78f4cba35e07bf8cb18a7925320/examples/ESP_WiFi/Credentials.h#L13-L100 832 | 833 | 834 | --- 835 | 836 | #### 4. File [dynamicParams.h](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi/dynamicParams.h) 837 | 838 | https://github.com/khoih-prog/ESP_WiFiManager_Lite/blob/bc8fb7ed5159e78f4cba35e07bf8cb18a7925320/examples/ESP_WiFi/dynamicParams.h#L13-L74 839 | 840 | --- 841 | --- 842 | 843 | 844 | ### Debug Terminal output Samples 845 | 846 | ### 1. [ESP_WiFi](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi) on ESP32_DEV 847 | 848 | This is the terminal output when running [**ESP_WiFi**](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi) example on **ESP32_DEV**: 849 | 850 | #### 1.1. MRD/DRD => Open Config Portal 851 | 852 | ```cpp 853 | Starting ESP_WiFi using LittleFS on ESP32_DEV 854 | ESP_WiFiManager_Lite v1.10.5 855 | ESP_MultiResetDetector v1.3.2 856 | LittleFS Flag read = 0xFFFC0003 857 | multiResetDetectorFlag = 0xFFFC0003 858 | lowerBytes = 0x0003, upperBytes = 0x0003 859 | multiResetDetected, number of times = 3 860 | Saving config file... 861 | Saving config file OK 862 | [WML] Multi or Double Reset Detected 863 | [WML] Hostname=ESP32-Controller 864 | [WML] LoadCfgFile 865 | [WML] OK 866 | [WML] ======= Start Stored Config Data ======= 867 | [WML] Hdr=ESP_WM_LITE,SSID=HueNet1,PW=12345678 868 | [WML] SSID1=HueNet2,PW1=12345678 869 | [WML] BName=ESP32_WM_Lite 870 | [WML] i=0,id=sv1,data=account.duckdns.org 871 | [WML] i=1,id=tk1,data=token1 872 | [WML] i=2,id=sv2,data=account.ddns.net 873 | [WML] i=3,id=tk2,data=token2 874 | [WML] i=4,id=prt,data=8080 875 | [WML] i=5,id=mqt,data=mqtt.duckdns.org 876 | [WML] CCSum=0x137c,RCSum=0x137c 877 | [WML] LoadCredFile 878 | [WML] CrR:pdata=new.duckdns.org,len=34 879 | [WML] CrR:pdata=token1,len=34 880 | [WML] CrR:pdata=new.ddns.net,len=34 881 | [WML] CrR:pdata=token2,len=34 882 | [WML] CrR:pdata=8080,len=6 883 | [WML] CrR:pdata=mqtt.duckdns.org,len=34 884 | [WML] OK 885 | [WML] CrCCsum=0x163b,CrRCsum=0x163b 886 | [WML] Valid Stored Dynamic Data 887 | [WML] Hdr=ESP_WM_LITE,SSID=HueNet1,PW=12345678 888 | [WML] SSID1=HueNet2,PW1=12345678 889 | [WML] BName=ESP32_WM_Lite 890 | [WML] i=0,id=sv1,data=new.duckdns.org 891 | [WML] i=1,id=tk1,data=token1 892 | [WML] i=2,id=sv2,data=new.ddns.net 893 | [WML] i=3,id=tk2,data=token2 894 | [WML] i=4,id=prt,data=8080 895 | [WML] i=5,id=mqt,data=mqtt.duckdns.org 896 | [WML] Check if isForcedCP 897 | [WML] LoadCPFile 898 | [WML] OK 899 | [WML] bg: isForcedConfigPortal = false 900 | [WML] bg:Stay forever in CP:DRD/MRD 901 | [WML] clearForcedCP 902 | [WML] SaveCPFile 903 | [WML] OK 904 | [WML] SaveBkUpCPFile 905 | [WML] OK 906 | [WML] 907 | stConf:SSID=ESP_9ABF498,PW=MyESP_9ABF498 908 | [WML] IP=192.168.4.1,ch=10 909 | [WML] s:millis() = 1014, configTimeout = 121014 910 | C 911 | Your stored Credentials : 912 | Blynk Server1 = new.duckdns.org 913 | Token1 = token1 914 | Blynk Server2 = new.ddns.net 915 | Token2 = token2 916 | Port = 8080 917 | MQTT Server = mqtt.duckdns.org 918 | CCCCCCCCC 919 | ``` 920 | 921 | #### 1.2. Got valid Credentials from Config Portal then connected to WiFi 922 | 923 | ```cpp 924 | Starting ESP_WiFi using LittleFS on ESP32_DEV 925 | ESP_WiFiManager_Lite v1.10.5 926 | ESP_MultiResetDetector v1.3.2 927 | LittleFS Flag read = 0xFFFE0001 928 | multiResetDetectorFlag = 0xFFFE0001 929 | lowerBytes = 0x0001, upperBytes = 0x0001 930 | No multiResetDetected, number of times = 1 931 | LittleFS Flag read = 0xFFFE0001 932 | Saving config file... 933 | Saving config file OK 934 | [WML] LoadCfgFile 935 | [WML] OK 936 | [WML] ======= Start Stored Config Data ======= 937 | [WML] Hdr=ESP_WM_LITE,SSID=HueNet1,PW=12345678 938 | [WML] SSID1=HueNet2,PW1=12345678 939 | [WML] BName=ESP32_WM_Lite 940 | [WML] i=0,id=sv1,data=account.duckdns.org 941 | [WML] i=1,id=tk1,data=token1 942 | [WML] i=2,id=sv2,data=account.ddns.net 943 | [WML] i=3,id=tk2,data=token2 944 | [WML] i=4,id=prt,data=8080 945 | [WML] i=5,id=mqt,data=mqtt.duckdns.org 946 | [WML] LoadCredFile 947 | [WML] OK 948 | [WML] Valid Stored Dynamic Data 949 | [WML] Hdr=ESP_WM_LITE,SSID=HueNet1,PW=12345678 950 | [WML] SSID1=HueNet2,PW1=12345678 951 | [WML] BName=ESP32_WM_Lite 952 | [WML] i=0,id=sv1,data=new.duckdns.org 953 | [WML] i=1,id=tk1,data=token1 954 | [WML] i=2,id=sv2,data=new.ddns.net 955 | [WML] i=3,id=tk2,data=token2 956 | [WML] i=4,id=prt,data=8080 957 | [WML] i=5,id=mqt,data=mqtt.duckdns.org 958 | [WML] LoadCPFile 959 | [WML] OK 960 | H 961 | Your stored Credentials : 962 | Blynk Server1 = new.duckdns.org 963 | Token1 = token1 964 | Blynk Server2 = new.ddns.net 965 | Token2 = token2 966 | Port = 8080 967 | MQTT Server = mqtt.duckdns.org 968 | Stop multiResetDetecting 969 | Saving config file... 970 | Saving config file OK 971 | HHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHH 972 | ``` 973 | 974 | #### 1.3. Lost a WiFi and autoconnect to another WiFi AP 975 | 976 | ```cpp 977 | [WML] run: WiFi lost. Reconnect WiFi 978 | [WML] Connecting MultiWifi... 979 | [WML] WiFi connected after time: 2 980 | [WML] SSID=HueNet2,RSSI=-54 981 | [WML] Channel=4,IP=192.168.2.82 982 | [WML] run: WiFi reconnected 983 | H 984 | HHHHHHHHHH HHHHHHHHHH 985 | ``` 986 | 987 | --- 988 | 989 | ### 2. [ESP_WiFi_MQTT](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi_MQTT) on ESP8266_NODEMCU 990 | 991 | This is the terminal output when running [**ESP_WiFi_MQTT**](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi_MQTT) example on **ESP8266_NODEMCU**: 992 | 993 | #### 2.1. No Config Data => Open Config Portal 994 | 995 | ```cpp 996 | Starting ESP_WiFi_MQTT using LittleFS on ESP8266_NODEMCU 997 | ESP_WiFiManager_Lite v1.10.5 998 | ESP_MultiResetDetector v1.3.2 999 | LittleFS Flag read = 0xFFFE0001 1000 | multiResetDetectorFlag = 0xFFFE0001 1001 | lowerBytes = 0x0001, upperBytes = 0x0001 1002 | No multiResetDetected, number of times = 1 1003 | LittleFS Flag read = 0xFFFE0001 1004 | Saving config file... 1005 | Saving config file OK 1006 | [WML] Hostname=ESP8266-Controller 1007 | [WML] LoadCfgFile 1008 | [WML] OK 1009 | [WML] ======= Start Stored Config Data ======= 1010 | [WML] Hdr=ESP_WM_LITE,SSID=HueNet1,PW=12345678 1011 | [WML] SSID1=HueNet2,PW1=12345678 1012 | [WML] BName=ESP8266_WM_Lite 1013 | [WML] i=0,id=svr,data=io.adafruit.com 1014 | [WML] i=1,id=prt,data=1883 1015 | [WML] i=2,id=usr,data=private 1016 | [WML] i=3,id=key,data=private 1017 | [WML] i=4,id=pub,data=/feeds/Temperature 1018 | [WML] i=5,id=sub,data=/feeds/LED_Control 1019 | [WML] LoadCredFile 1020 | [WML] OK 1021 | [WML] Invalid Stored Dynamic Data. Ignored 1022 | [WML] InitCfgFile,sz=236 1023 | [WML] SaveCfgFile 1024 | [WML] WCSum=0xda0 1025 | [WML] OK 1026 | [WML] SaveBkUpCfgFile 1027 | [WML] OK 1028 | [WML] SaveCredFile 1029 | [WML] OK 1030 | [WML] CrWCSum=0xc30 1031 | [WML] SaveBkUpCredFile 1032 | [WML] OK 1033 | [WML] LoadCPFile 1034 | [WML] OK 1035 | [WML] bg:Stay forever in CP:No ConfigDat 1036 | [WML] SaveCPFile 1037 | [WML] OK 1038 | [WML] SaveBkUpCPFile 1039 | [WML] OK 1040 | C 1041 | Your stored Credentials : 1042 | AIO_SERVER = blank 1043 | AIO_SERVERPORT = blank 1044 | AIO_USERNAME = blank 1045 | AIO_KEY = blank 1046 | AIO_PUB_TOPIC = blank 1047 | AIO_SUB_TOPIC = blank 1048 | NStop multiResetDetecting 1049 | Saving config file... 1050 | Saving config file OK 1051 | CCC 1052 | ``` 1053 | 1054 | #### 2.2. Got valid Credentials from Config Portal then connected to WiFi 1055 | 1056 | ```cpp 1057 | [WML] h:UpdLittleFS 1058 | [WML] SaveCfgFile 1059 | [WML] WCSum=0x13a5 1060 | [WML] OK 1061 | [WML] SaveBkUpCfgFile 1062 | [WML] OK 1063 | [WML] SaveCredFile 1064 | [WML] OK 1065 | [WML] CrWCSum=0x2236 1066 | [WML] SaveBkUpCredFile 1067 | [WML] OK 1068 | [WML] h:Rst 1069 | ... 1070 | 1071 | Starting ESP_WiFi_MQTT using LittleFS on ESP8266_NODEMCU 1072 | ESP_WiFiManager_Lite v1.10.5 1073 | ESP_MultiResetDetector v1.3.2 1074 | LittleFS Flag read = 0xFFFE0001 1075 | multiResetDetectorFlag = 0xFFFE0001 1076 | lowerBytes = 0x0001, upperBytes = 0x0001 1077 | No multiResetDetected, number of times = 1 1078 | LittleFS Flag read = 0xFFFE0001 1079 | Saving config file... 1080 | Saving config file OK 1081 | [WML] Hostname=ESP8266-Controller 1082 | [WML] LoadCfgFile 1083 | [WML] OK 1084 | [WML] ======= Start Stored Config Data ======= 1085 | [WML] Hdr=ESP_WM_LITE,SSID=HueNet1,PW=12345678 1086 | [WML] SSID1=HueNet2,PW1=12345678 1087 | [WML] BName=ESP8266_WM_MQTT 1088 | [WML] i=0,id=svr,data=io.adafruit.com 1089 | [WML] i=1,id=prt,data=1883 1090 | [WML] i=2,id=usr,data=private 1091 | [WML] i=3,id=key,data=private 1092 | [WML] i=4,id=pub,data=/feeds/Temperature 1093 | [WML] i=5,id=sub,data=/feeds/LED_Control 1094 | [WML] LoadCredFile 1095 | [WML] OK 1096 | [WML] Valid Stored Dynamic Data 1097 | [WML] Hdr=ESP_WM_LITE,SSID=HueNet1,PW=12345678 1098 | [WML] SSID1=HueNet2,PW1=12345678 1099 | [WML] BName=ESP8266_WM_MQTT 1100 | [WML] i=0,id=svr,data=io.adafruit.com 1101 | [WML] i=1,id=prt,data=1883 1102 | [WML] i=2,id=usr,data=user_name 1103 | [WML] i=3,id=key,data=aio_key 1104 | [WML] i=4,id=pub,data=/feeds/Temperature 1105 | [WML] i=5,id=sub,data=/feeds/LED_Control 1106 | [WML] LoadCPFile 1107 | [WML] OK 1108 | [WML] Connecting MultiWifi... 1109 | [WML] WiFi connected after time: 1 1110 | [WML] SSID=HueNet1,RSSI=-43 1111 | [WML] Channel=2,IP=192.168.2.98 1112 | [WML] bg: WiFi OK. 1113 | 1114 | Creating new WiFi client object OK 1115 | Creating new MQTT object OK 1116 | AIO_SERVER = io.adafruit.com, AIO_SERVERPORT = 1883 1117 | AIO_USERNAME = user_name, AIO_KEY = aio_key 1118 | Creating new MQTT_Pub_Topic, Temperature = user_name/feeds/Temperature 1119 | Creating new Temperature object OK 1120 | Temperature MQTT_Pub_Topic = user_name/feeds/Temperature 1121 | Creating new AIO_SUB_TOPIC, LED_Control = user_name/feeds/LED_Control 1122 | Creating new LED_Control object OK 1123 | LED_Control AIO_SUB_TOPIC = user_name/feeds/LED_Control 1124 | 1125 | Connecting to WiFi MQTT (3 attempts)... 1126 | WiFi MQTT connection successful! 1127 | TW 1128 | Your stored Credentials : 1129 | AIO_SERVER = io.adafruit.com 1130 | AIO_SERVERPORT = 1883 1131 | AIO_USERNAME = user_name 1132 | AIO_KEY = aio_key 1133 | AIO_PUB_TOPIC = /feeds/Temperature 1134 | AIO_SUB_TOPIC = /feeds/LED_Control 1135 | Stop multiResetDetecting 1136 | Saving config file... 1137 | Saving config file OK 1138 | TWTWTWTW TW 1139 | ``` 1140 | 1141 | #### 2.3. Lost a WiFi and autoconnect to another WiFi AP 1142 | 1143 | ```cpp 1144 | [WML] run: WiFi lost. Reconnect WiFi 1145 | [WML] Connecting MultiWifi... 1146 | [WML] WiFi connected after time: 1 1147 | [WML] SSID=HueNet2,RSSI=-54 1148 | [WML] Channel=4,IP=192.168.2.98 1149 | [WML] run: WiFi reconnected 1150 | H 1151 | ``` 1152 | 1153 | --- 1154 | --- 1155 | 1156 | ### 3. [ESP_WiFi_MQTT](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi_MQTT) on ESP32S2_DEV 1157 | 1158 | This is the terminal output when running [**ESP_WiFi_MQTT**](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi_MQTT) example on **ESP32S2_DEV**: 1159 | 1160 | #### 3.1. No Config Data => Open Config Portal 1161 | 1162 | ```cpp 1163 | Starting ESP_WiFi_MQTT using LittleFS on ESP32S2_DEV 1164 | ESP_WiFiManager_Lite v1.10.5 1165 | ESP_MultiResetDetector v1.3.2 1166 | LittleFS Flag read = 0xFFFE0001 1167 | multiResetDetectorFlag = 0xFFFE0001 1168 | lowerBytes = 0x0001, upperBytes = 0x0001 1169 | No multiResetDetected, number of times = 1 1170 | LittleFS Flag read = 0xFFFE0001 1171 | Saving config file... 1172 | Saving config file OK 1173 | [WML] Hostname=ESP32-Controller 1174 | [WML] Check if isForcedCP 1175 | [WML] LoadCPFile 1176 | [WML] OK 1177 | [WML] bg: isForcedConfigPortal = false 1178 | [WML] bg:Stay forever in CP:No ConfigDat 1179 | [WML] clearForcedCP 1180 | [WML] SaveCPFile 1181 | [WML] OK 1182 | [WML] SaveBkUpCPFile 1183 | [WML] OK 1184 | [WML] 1185 | stConf:SSID=ESP_8A1DF7C,PW=MyESP_8A1DF7C 1186 | [WML] IP=192.168.4.1,ch=1 1187 | [WML] s:configTimeout = 0 1188 | C 1189 | Your stored Credentials : 1190 | AIO_SERVER = io.adafruit.com 1191 | AIO_SERVERPORT = 1883 1192 | AIO_USERNAME = private 1193 | AIO_KEY = private 1194 | AIO_PUB_TOPIC = /feeds/Temperature 1195 | AIO_SUB_TOPIC = /feeds/LED_Control 1196 | NStop multiResetDetecting 1197 | Saving config file... 1198 | Saving config file OK 1199 | CCC C 1200 | ``` 1201 | 1202 | #### 3.2. Got valid Credentials from Config Portal then connected to WiFi 1203 | 1204 | ```cpp 1205 | [WML] h: Init menuItemUpdated 1206 | [WML] h:repl id 1207 | [WML] h:items updated =1 1208 | [WML] h:key =id, value =HueNet1 1209 | [WML] h:repl pw 1210 | [WML] h:items updated =2 1211 | [WML] h:key =pw, value =12345678 1212 | [WML] h:repl id1 1213 | [WML] h:items updated =3 1214 | [WML] h:key =id1, value =HueNet2 1215 | [WML] h:repl pw1 1216 | [WML] h:items updated =4 1217 | [WML] h:key =pw1, value =12345678 1218 | [WML] h:repl nm 1219 | [WML] h:items updated =5 1220 | [WML] h:key =nm, value =ESP32_S2 1221 | [WML] h:svr=io.adafruit.com 1222 | [WML] h:items updated =6 1223 | [WML] h:key =svr, value =io.adafruit.com 1224 | [WML] h:prt=1883 1225 | [WML] h:items updated =7 1226 | [WML] h:key =prt, value =1883 1227 | [WML] h:usr=user_name 1228 | [WML] h:items updated =8 1229 | [WML] h:key =usr, value =user_name 1230 | [WML] h:key=aio_key 1231 | [WML] h:items updated =9 1232 | [WML] h:key =key, value =aio_key 1233 | [WML] h:pub=/feeds/Temperature 1234 | [WML] h:items updated =10 1235 | [WML] h:key =pub, value =/feeds/Temperature 1236 | [WML] h:sub=/feeds/LED_Control 1237 | [WML] h:items updated =11 1238 | [WML] h:key =sub, value =/feeds/LED_Control 1239 | [WML] h:UpdLittleFS 1240 | [WML] SaveCfgFile 1241 | [WML] WCSum=0x1170 1242 | [WML] OK 1243 | [WML] SaveBkUpCfgFile 1244 | [WML] OK 1245 | [WML] SaveCredFile 1246 | [WML] CW1:pdata=io.adafruit.com,len=20 1247 | [WML] CW1:pdata=1883,len=6 1248 | [WML] CW1:pdata=user_name,len=20 1249 | [WML] CW1:pdata=aio_key,len=40 1250 | [WML] CW1:pdata=/feeds/Temperature,len=40 1251 | [WML] CW1:pdata=/feeds/LED_Control,len=40 1252 | [WML] OK 1253 | [WML] CrWCSum=0x2236 1254 | [WML] SaveBkUpCredFile 1255 | [WML] CW2:pdata=io.adafruit.com,len=20 1256 | [WML] CW2:pdata=1883,len=6 1257 | [WML] CW2:pdata=user_name,len=20 1258 | [WML] CW2:pdata=aio_key,len=40 1259 | [WML] CW2:pdata=/feeds/Temperature,len=40 1260 | [WML] CW2:pdata=/feeds/LED_Control,len=40 1261 | [WML] OK 1262 | [WML] h:Rst 1263 | ESP-ROM:esp32s2-rc4-20191025 1264 | Build:Oct 25 2019 1265 | rst:0x3 (RTC_SW_SYS_RST),boot:0x8 (SPI_FAST_FLASH_BOOT) 1266 | Saved PC:0x40025f35 1267 | SPIWP:0xee 1268 | mode:DIO, clock div:1 1269 | load:0x3ffe6100,len:0x8 1270 | load:0x3ffe6108,len:0x608 1271 | load:0x4004c000,len:0xa38 1272 | load:0x40050000,len:0x2848 1273 | entry 0x4004c190 1274 | ... 1275 | 1276 | Starting ESP_WiFi_MQTT using LittleFS on ESP32S2_DEV 1277 | ESP_WiFiManager_Lite v1.10.5 1278 | ESP_MultiResetDetector v1.3.2 1279 | LittleFS Flag read = 0xFFFE0001 1280 | multiResetDetectorFlag = 0xFFFE0001 1281 | lowerBytes = 0x0001, upperBytes = 0x0001 1282 | No multiResetDetected, number of times = 1 1283 | LittleFS Flag read = 0xFFFE0001 1284 | Saving config file... 1285 | Saving config file OK 1286 | [WML] Hostname=ESP32-Controller 1287 | [WML] LoadCfgFile 1288 | [WML] OK 1289 | [WML] ======= Start Stored Config Data ======= 1290 | [WML] Hdr=ESP_WM_LITE,SSID=HueNet1,PW=12345678 1291 | [WML] SSID1=HueNet2,PW1=12345678 1292 | [WML] BName=ESP32_S2 1293 | [WML] i=0,id=svr,data=io.adafruit.com 1294 | [WML] i=1,id=prt,data=1883 1295 | [WML] i=2,id=usr,data=private 1296 | [WML] i=3,id=key,data=private 1297 | [WML] i=4,id=pub,data=/feeds/Temperature 1298 | [WML] i=5,id=sub,data=/feeds/LED_Control 1299 | [WML] CCSum=0x1170,RCSum=0x1170 1300 | [WML] LoadCredFile 1301 | [WML] CrR:pdata=io.adafruit.com,len=20 1302 | [WML] CrR:pdata=1883,len=6 1303 | [WML] CrR:pdata=user_name,len=20 1304 | [WML] CrR:pdata=aio_key,len=40 1305 | [WML] CrR:pdata=/feeds/Temperature,len=40 1306 | [WML] CrR:pdata=/feeds/LED_Control,len=40 1307 | [WML] OK 1308 | [WML] CrCCsum=0x2236,CrRCsum=0x2236 1309 | [WML] Valid Stored Dynamic Data 1310 | [WML] Hdr=ESP_WM_LITE,SSID=HueNet1,PW=12345678 1311 | [WML] SSID1=HueNet2,PW1=12345678 1312 | [WML] BName=ESP32_S2 1313 | [WML] i=0,id=svr,data=io.adafruit.com 1314 | [WML] i=1,id=prt,data=1883 1315 | [WML] i=2,id=usr,data=user_name 1316 | [WML] i=3,id=key,data=aio_key 1317 | [WML] i=4,id=pub,data=/feeds/Temperature 1318 | [WML] i=5,id=sub,data=/feeds/LED_Control 1319 | [WML] Check if isForcedCP 1320 | [WML] LoadCPFile 1321 | [WML] OK 1322 | [WML] bg: noConfigPortal = true 1323 | [WML] Connecting MultiWifi... 1324 | [WML] WiFi connected after time: 1 1325 | [WML] SSID=HueNet1,RSSI=-19 1326 | [WML] Channel=2,IP=192.168.2.116 1327 | [WML] bg: WiFi OK. 1328 | Stop multiResetDetecting 1329 | Saving config file... 1330 | Saving config file OK 1331 | 1332 | Creating new WiFi client object OK 1333 | Creating new MQTT object OK 1334 | AIO_SERVER = io.adafruit.com, AIO_SERVERPORT = 1883 1335 | AIO_USERNAME = user_name, AIO_KEY = aio_key 1336 | Creating new MQTT_Pub_Topic, Temperature = user_name/feeds/Temperature 1337 | Creating new Temperature object OK 1338 | Temperature MQTT_Pub_Topic = user_name/feeds/Temperature 1339 | Creating new AIO_SUB_TOPIC, LED_Control = user_name/feeds/LED_Control 1340 | Creating new LED_Control object OK 1341 | LED_Control AIO_SUB_TOPIC = user_name/feeds/LED_Control 1342 | 1343 | Connecting to WiFi MQTT (3 attempts)... 1344 | WiFi MQTT connection successful! 1345 | TW 1346 | Your stored Credentials : 1347 | AIO_SERVER = io.adafruit.com 1348 | AIO_SERVERPORT = 1883 1349 | AIO_USERNAME = user_name 1350 | AIO_KEY = aio_key 1351 | AIO_PUB_TOPIC = /feeds/Temperature 1352 | AIO_SUB_TOPIC = /feeds/LED_Control 1353 | TWTWTWTW TW 1354 | ``` 1355 | 1356 | #### 3.3. Lost a WiFi and autoconnect to another WiFi AP 1357 | 1358 | ```cpp 1359 | [WML] run: WiFi lost. Reconnect WiFi 1360 | [WML] Connecting MultiWifi... 1361 | [WML] WiFi connected after time: 1 1362 | [WML] SSID=HueNet2,RSSI=-54 1363 | [WML] Channel=4,IP=192.168.2.116 1364 | [WML] run: WiFi reconnected 1365 | H 1366 | ``` 1367 | 1368 | --- 1369 | --- 1370 | 1371 | ### 4. [ESP_WiFi_MQTT](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi_MQTT) on ESP32S2_DEV to demo MultiResetDetector 1372 | 1373 | This is the terminal output when running [**ESP_WiFi_MQTT**](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi_MQTT) example on **ESP32S2_DEV** 1374 | 1375 | #### 4.1. MultiResetDetected => Open Config Portal 1376 | 1377 | ```cpp 1378 | Starting ESP_WiFi_MQTT using LittleFS on ESP32S2_DEV 1379 | ESP_WiFiManager_Lite v1.10.5 1380 | ESP_MultiResetDetector v1.3.2 1381 | LittleFS Flag read = 0xFFFC0003 1382 | multiResetDetectorFlag = 0xFFFC0003 1383 | lowerBytes = 0x0003, upperBytes = 0x0003 1384 | multiResetDetected, number of times = 3 1385 | Saving config file... 1386 | Saving config file OK 1387 | [WML] 1388 | stConf:SSID=ESP_8A1DF7C,PW=MyESP_8A1DF7C 1389 | [WML] IP=192.168.4.1,ch=3 1390 | C 1391 | Your stored Credentials : 1392 | AIO_SERVER = io.adafruit.com 1393 | AIO_SERVERPORT = 1883 1394 | AIO_USERNAME = private 1395 | AIO_KEY = private 1396 | AIO_PUB_TOPIC = /feeds/Temperature 1397 | AIO_SUB_TOPIC = /feeds/LED_Control 1398 | NNNN NNNNN NNNNN NNNNN NN[WML] h:UpdLittleFS 1399 | [WML] h:Rst 1400 | ``` 1401 | 1402 | #### 4.2. Got valid Credentials from Config Portal then connected to WiFi 1403 | 1404 | 1405 | ```cpp 1406 | Starting ESP_WiFi_MQTT using LittleFS on ESP32S2_DEV 1407 | ESP_WiFiManager_Lite v1.10.5 1408 | ESP_MultiResetDetector v1.3.2 1409 | LittleFS Flag read = 0xFFFE0001 1410 | multiResetDetectorFlag = 0xFFFE0001 1411 | lowerBytes = 0x0001, upperBytes = 0x0001 1412 | No multiResetDetected, number of times = 1 1413 | LittleFS Flag read = 0xFFFE0001 1414 | Saving config file... 1415 | Saving config file OK 1416 | [WML] Hdr=ESP_WM_LITE,SSID=HueNet1,PW=12345678 1417 | [WML] SSID1=HueNet2,PW1=12345678 1418 | [WML] BName=ESP32-S2 1419 | [WML] Hdr=ESP_WM_LITE,SSID=HueNet1,PW=12345678 1420 | [WML] SSID1=HueNet2,PW1=12345678 1421 | [WML] BName=ESP32-S2 1422 | [WML] WiFi connected after time: 1 1423 | [WML] SSID=HueNet1,RSSI=-41 1424 | [WML] Channel=2,IP=192.168.2.157 1425 | Stop multiResetDetecting 1426 | Saving config file... 1427 | Saving config file OK 1428 | 1429 | Creating new WiFi client object OK 1430 | Creating new MQTT object OK 1431 | AIO_SERVER = io.adafruit.com, AIO_SERVERPORT = 1883 1432 | AIO_USERNAME = user_name, AIO_KEY = aio_key 1433 | Creating new MQTT_Pub_Topic, Temperature = user_name/feeds/Temperature 1434 | Creating new Temperature object OK 1435 | Temperature MQTT_Pub_Topic = user_name/feeds/Temperature 1436 | Creating new AIO_SUB_TOPIC, LED_Control = user_name/feeds/LED_Control 1437 | Creating new LED_Control object OK 1438 | LED_Control AIO_SUB_TOPIC = user_name/feeds/LED_Control 1439 | 1440 | Connecting to WiFi MQTT (3 attempts)... 1441 | WiFi MQTT connection successful! 1442 | TW 1443 | Your stored Credentials : 1444 | AIO_SERVER = io.adafruit.com 1445 | AIO_SERVERPORT = 1883 1446 | AIO_USERNAME = user_name 1447 | AIO_KEY = aio_key 1448 | AIO_PUB_TOPIC = /feeds/Temperature 1449 | AIO_SUB_TOPIC = /feeds/LED_Control 1450 | TWTWTWTW TWTWTWTWTW TWTW 1451 | ``` 1452 | 1453 | --- 1454 | 1455 | ### 5. [ESP_WiFi_MQTT](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi_MQTT) on ESP32_DEV to demo WiFi Scan 1456 | 1457 | This is the terminal output when running [**ESP_WiFi**](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi) example on **ESP32_DEV** with WiFi Scan for selection in Configuration Portal 1458 | 1459 | #### 5.1 MRD/DRD => Open Config Portal 1460 | 1461 | ```cpp 1462 | Starting ESP_WiFi_MQTT using LittleFS on ESP32_DEV 1463 | ESP_WiFiManager_Lite v1.10.5 1464 | ESP_MultiResetDetector v1.3.2 1465 | LittleFS Flag read = 0xFFFC0003 1466 | multiResetDetectorFlag = 0xFFFC0003 1467 | lowerBytes = 0x0003, upperBytes = 0x0003 1468 | multiResetDetected, number of times = 3 1469 | Saving config file... 1470 | Saving config file OK 1471 | [WML] Hdr=ESP_WM_LITE,SSID=HueNet1,PW=12345678 1472 | [WML] SSID1=HueNet2,PW1=12345678 1473 | [WML] BName=ESP32_DEV 1474 | [WML] Hdr=ESP_WM_LITE,SSID=HueNet1,PW=12345678 1475 | [WML] SSID1=HueNet2,PW1=12345678 1476 | [WML] BName=ESP32_DEV 1477 | [WML] WiFi networks found: 1478 | [WML] 1: HueNet, -24dB 1479 | [WML] 2: HueNet1, -31dB 1480 | [WML] 3: HueNetTek, -33dB 1481 | [WML] 4: dragino-1ed63c, -33dB 1482 | [WML] 5: HueNet2, -57dB 1483 | [WML] 6: bacau, -72dB 1484 | [WML] 7: guest_24, -72dB 1485 | [WML] 8: Waterhome, -91dB 1486 | [WML] 9: BAHFAMILY, -93dB 1487 | [WML] 10: TP-LINK_2.4GHz_9A67ED, -94dB 1488 | [WML] 11: Access 2.0, -96dB 1489 | [WML] 1490 | stConf:SSID=ESP_9ABF498,PW=MyESP_9ABF498 1491 | [WML] IP=192.168.4.1,ch=11 1492 | C 1493 | Your stored Credentials : 1494 | AIO_SERVER = io.adafruit.com 1495 | AIO_SERVERPORT = 1883 1496 | AIO_USERNAME = private 1497 | AIO_KEY = private 1498 | AIO_PUB_TOPIC = /feeds/Temperature 1499 | AIO_SUB_TOPIC = /feeds/LED_Control 1500 | CCC 1501 | ``` 1502 | 1503 | ### 5.2 Config Data Saved => Connection to Adafruit MQTT 1504 | 1505 | ```cpp 1506 | Starting ESP_WiFi_MQTT using LittleFS on ESP32_DEV 1507 | ESP_WiFiManager_Lite v1.10.5 1508 | ESP_MultiResetDetector v1.3.2 1509 | LittleFS Flag read = 0xFFFE0001 1510 | multiResetDetectorFlag = 0xFFFE0001 1511 | lowerBytes = 0x0001, upperBytes = 0x0001 1512 | No multiResetDetected, number of times = 1 1513 | LittleFS Flag read = 0xFFFE0001 1514 | Saving config file... 1515 | Saving config file OK 1516 | [WML] Hdr=ESP_WM_LITE,SSID=HueNet1,PW=12345678 1517 | [WML] SSID1=HueNet2,PW1=12345678 1518 | [WML] BName=ESP32_DEV 1519 | [WML] Hdr=ESP_WM_LITE,SSID=HueNet1,PW=12345678 1520 | [WML] SSID1=HueNet2,PW1=12345678 1521 | [WML] BName=ESP32_DEV 1522 | [WML] WiFi connected after time: 1 1523 | [WML] SSID=HueNet1,RSSI=-30 1524 | [WML] Channel=2,IP=192.168.2.45 1525 | Stop multiResetDetecting 1526 | Saving config file... 1527 | Saving config file OK 1528 | 1529 | Creating new WiFi client object OK 1530 | Creating new MQTT object OK 1531 | AIO_SERVER = io.adafruit.com, AIO_SERVERPORT = 1883 1532 | AIO_USERNAME = user_name, AIO_KEY = aio_key 1533 | Creating new MQTT_Pub_Topic, Temperature = user_name/feeds/Temperature 1534 | Creating new Temperature object OK 1535 | Temperature MQTT_Pub_Topic = user_name/feeds/Temperature 1536 | Creating new AIO_SUB_TOPIC, LED_Control = user_name/feeds/LED_Control 1537 | Creating new LED_Control object OK 1538 | LED_Control AIO_SUB_TOPIC = user_name/feeds/LED_Control 1539 | 1540 | Connecting to WiFi MQTT (3 attempts)... 1541 | WiFi MQTT connection successful! 1542 | TWTWTWTW TWTW 1543 | ``` 1544 | 1545 | --- 1546 | 1547 | ### 6. [ESP_WiFi](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi) on ESP32S3_DEV 1548 | 1549 | 1550 | This is the terminal output when running [**ESP_WiFi**](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi) example on **ESP32S3_DEV** 1551 | 1552 | 1553 | ```cpp 1554 | Starting ESP_WiFi using LittleFS on ESP32S3_DEV 1555 | ESP_WiFiManager_Lite v1.10.5 1556 | ESP_MultiResetDetector v1.3.2 1557 | LittleFS Flag read = 0xFFFE0001 1558 | multiResetDetectorFlag = 0xFFFE0001 1559 | lowerBytes = 0x0001, upperBytes = 0x0001 1560 | No multiResetDetected, number of times = 1 1561 | LittleFS Flag read = 0xFFFE0001 1562 | Saving config file... 1563 | Saving config file OK 1564 | [WML] Hdr=ESP_WM_LITE,SSID=HueNet1,PW=password 1565 | [WML] SSID1=HueNet2,PW1=password 1566 | [WML] BName=ESP32_S3 1567 | [WML] Hdr=ESP_WM_LITE,SSID=HueNet1,PW=password 1568 | [WML] SSID1=HueNet2,PW1=password 1569 | [WML] BName=ESP32_S3 1570 | [WML] WiFi connected after time: 0 1571 | [WML] SSID=HueNet1,RSSI=-23 1572 | [WML] Channel=2,IP=192.168.2.83 1573 | H 1574 | Your stored Credentials : 1575 | Blynk Server1 = account.duckdns.org 1576 | Token1 = token1 1577 | Blynk Server2 = account.ddns.net 1578 | Token2 = token2 1579 | Port = 8080 1580 | MQTT Server = mqtt.duckdns.org 1581 | Stop multiResetDetecting 1582 | Saving config file... 1583 | Saving config file OK 1584 | HHH 1585 | ``` 1586 | 1587 | --- 1588 | 1589 | ### 7. [ESP_WiFi](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi) on ESP32C3_DEV using LittleFS 1590 | 1591 | 1592 | This is the terminal output when running [**ESP_WiFi**](https://github.com/khoih-prog/ESP_WiFiManager_Lite/tree/main/examples/ESP_WiFi) example on **ESP32C3_DEV** using LittleFS 1593 | 1594 | 1595 | ```cpp 1596 | Starting ESP_WiFi using LittleFS on ESP32C3_DEV 1597 | ESP_WiFiManager_Lite v1.10.5 1598 | ESP_MultiResetDetector v1.3.2 1599 | LittleFS Flag read = 0xFFFE0001 1600 | multiResetDetectorFlag = 0xFFFE0001 1601 | lowerBytes = 0x0001, upperBytes = 0x0001 1602 | No multiResetDetected, number of times = 1 1603 | LittleFS Flag read = 0xFFFE0001 1604 | Saving config file... 1605 | Saving config file OK 1606 | [WML] Hdr=ESP_WM_LITE,SSID=HueNet1,PW=password 1607 | [WML] SSID1=HueNet2,PW1=password 1608 | [WML] BName=ESP32_C3 1609 | [WML] Hdr=ESP_WM_LITE,SSID=HueNet1,PW=password 1610 | [WML] SSID1=HueNet2,PW1=password 1611 | [WML] BName=ESP32_C3 1612 | [WML] WiFi connected after time: 0 1613 | [WML] SSID=HueNet1,RSSI=-21 1614 | [WML] Channel=2,IP=192.168.2.85 1615 | H 1616 | Your stored Credentials : 1617 | Blynk Server1 = account.duckdns.org 1618 | Token1 = token1 1619 | Blynk Server2 = account.ddns.net 1620 | Token2 = token2 1621 | Port = 8080 1622 | MQTT Server = mqtt.duckdns.org 1623 | Stop multiResetDetecting 1624 | Saving config file... 1625 | Saving config file OK 1626 | HHH 1627 | ``` 1628 | 1629 | --- 1630 | --- 1631 | 1632 | ### Debug 1633 | 1634 | Debug is enabled by default on Serial. To disable, add at the beginning of sketch 1635 | 1636 | ```cpp 1637 | /* Comment this out to disable prints and save space */ 1638 | #define ESP_WM_LITE_DEBUG_OUTPUT Serial 1639 | 1640 | #define _ESP_WM_LITE_LOGLEVEL_ 3 1641 | 1642 | #define USING_MRD true 1643 | 1644 | #if USING_MRD 1645 | #define MULTIRESETDETECTOR_DEBUG true 1646 | #else 1647 | #define DOUBLERESETDETECTOR_DEBUG true 1648 | #endif 1649 | ``` 1650 | 1651 | --- 1652 | 1653 | ### Troubleshooting 1654 | 1655 | If you get compilation errors, more often than not, you may need to install a newer version of the board's core or this library version. 1656 | 1657 | --- 1658 | --- 1659 | 1660 | 1661 | ### Issues 1662 | 1663 | Submit issues to: [ESP_WiFiManager_Lite issues](https://github.com/khoih-prog/ESP_WiFiManager_Lite/issues) 1664 | 1665 | --- 1666 | --- 1667 | 1668 | ### TO DO 1669 | 1670 | 1. Support more boards, shields and libraries 1671 | 2. Bug Searching and Killing 1672 | 1673 | --- 1674 | 1675 | ### DONE 1676 | 1677 | 1. Permit EEPROM size and location configurable to avoid conflict with others. 1678 | 2. More flexible to configure reconnection timeout. 1679 | 3. For fresh config data, don't need to wait for connecting timeout before entering config portal. 1680 | 4. If the config data not entered completely (SSIDs, Passwords, etc.), entering config portal 1681 | 5. Add configurable Config Portal IP, SSID and Password 1682 | 6. Change Synch XMLHttpRequest to Async 1683 | 7. Add configurable Static IP, GW, Subnet Mask and 2 DNS Servers' IP Addresses. 1684 | 8. Add checksums 1685 | 9. Add support to **ESP32 including ESP32-S2 (ESP32-S2 Saola, AI-Thinker ESP-12K, etc.) and ESP8266** 1686 | 10. Add MultiWiFi features with auto(re)connect 1687 | 11. Easy-to-use **Dynamic Parameters** without the necessity to write complicated ArduinoJSon functions 1688 | 12. Permit to input special chars such as **%** and **#** into data fields. 1689 | 13. Default Credentials and dynamic parameters 1690 | 14. **Multi/DoubleDetectDetector** to force Config Portal when multi/double reset is detected within predetermined time, default 10s. 1691 | 15. Configurable Config Portal Title 1692 | 16. Re-structure all examples to separate Credentials / Defines / Dynamic Params / Code so that you can change Credentials / Dynamic Params quickly for each device. 1693 | 17. Add Table of Contents and Version String 1694 | 18. Configurable **Customs HTML Headers**, including Customs Style, Customs Head Elements, CORS Header 1695 | 19. Permit optionally inputting one set of WiFi SSID/PWD by using `REQUIRE_ONE_SET_SSID_PW == true` 1696 | 20. Enforce WiFi PWD minimum length of 8 chars 1697 | 21. Add support to **ESP32-S2 (ESP32-S2 Saola, AI-Thinker ESP-12K, etc.) using EEPROM, LittleFS and SPIFFS** 1698 | 22. Configurable **Customs HTML Headers**, including Customs Style, Customs Head Elements, CORS Header 1699 | 23. Add support to **ESP32-C3 using EEPROM and SPIFFS** 1700 | 24. Enable **scan of WiFi networks** for selection in Configuration Portal 1701 | 25. Ready for ESP32 core v2.0.0+ 1702 | 26. Fix ESP8266 bug not easy to connect to Config Portal for ESP8266 core v3.0.0+ 1703 | 27. Fix the blocking issue in loop() with configurable `WIFI_RECON_INTERVAL` 1704 | 28. Add support to **ESP32-S3 (ESP32S3_DEV, ESP32_S3_BOX, UM TINYS3, UM PROS3, UM FEATHERS3, etc.) using EEPROM, SPIFFS or LittleFS** 1705 | 29. Add `LittleFS` support to **ESP32-C3** 1706 | 30. Use `ESP32-core's LittleFS` library instead of `Lorol's LITTLEFS` library for ESP32 core v2.0.0+ 1707 | 31. Optimize code by passing by `reference` instead of `value` 1708 | 32. Optional `Board_Name` in Config Portal 1709 | 33. Add function `isConfigMode()` to signal system is in Config Portal mode 1710 | 34. Fix ESP32 chipID 1711 | 35. Add ESP32 getChipID() and getChipOUI() functions 1712 | 36. Add `Captive-Portal` feature. Check [Captive portal #24](https://github.com/khoih-prog/ESP_WiFiManager_Lite/pull/24) 1713 | 37. Add option to not `USE_LED_BUILTIN` for Config-Portal. Check [added switch to turn use of builtin LED off #20](https://github.com/khoih-prog/ESP_WiFiManager_Lite/pull/20) 1714 | 38. Add public methods to load and save dynamic data 1715 | 39. Add Config Portal `scaling` support to mobile devices 1716 | 40. Using PROGMEM for HTML strings. Check [move HTML char* into PROGMEM #35](https://github.com/khoih-prog/ESP_WiFiManager_Lite/pull/35) 1717 | 41. Using PROGMEM for strings in examples. Check [Example fixes #37](https://github.com/khoih-prog/ESP_WiFiManager_Lite/pull/37) 1718 | 42. Improve `README.md` so that links can be used in other sites, such as `PIO` 1719 | 1720 | 1721 | --- 1722 | --- 1723 | 1724 | ### Contributions and Thanks 1725 | 1726 | Please help contribute to this project and add your name here. 1727 | 1728 | 1. Thanks to [Michael H. "bizprof"](https://github.com/bizprof). With the impressive new feature : 1729 | - `Enable scan of WiFi networks for selection in Configuration Portal`. Check [PR for v1.3.0 - Enable scan of WiFi networks #10](https://github.com/khoih-prog/WiFiManager_NINA_Lite/pull/10) leading to `v1.5.0 ` 1730 | 2. Thanks to [Holger Müller](https://github.com/hmueller01) for creating the following merged PRs leading to many new versions 1731 | - [Captive portal #24](https://github.com/khoih-prog/ESP_WiFiManager_Lite/pull/24) 1732 | - [reset cleanup #21](https://github.com/khoih-prog/ESP_WiFiManager_Lite/pull/21) 1733 | - [added switch to turn use of builtin LED off #20](https://github.com/khoih-prog/ESP_WiFiManager_Lite/pull/20) 1734 | - [added public methods to load and save dynamic data #28](https://github.com/khoih-prog/ESP_WiFiManager_Lite/pull/28) 1735 | - [Mobile scale #30](https://github.com/khoih-prog/ESP_WiFiManager_Lite/pull/30) 1736 | - [fix compiler error if EEPROM is used #33](https://github.com/khoih-prog/ESP_WiFiManager_Lite/pull/33) 1737 | - [move HTML char* into PROGMEM #35](https://github.com/khoih-prog/ESP_WiFiManager_Lite/pull/35) 1738 | - [Example fixes #37](https://github.com/khoih-prog/ESP_WiFiManager_Lite/pull/37) 1739 | 1740 | 1741 | 1742 | 1743 | 1744 | 1745 |
bizprof
⭐️⭐️ Michael H. "bizprof"

hmueller01
⭐️⭐️ Holger Müller

1746 | 1747 | 1748 | --- 1749 | 1750 | ### Contributing 1751 | 1752 | If you want to contribute to this project: 1753 | 1754 | - Report bugs and errors 1755 | - Ask for enhancements 1756 | - Create issues and pull requests 1757 | - Tell other people about this library 1758 | 1759 | --- 1760 | 1761 | ### License 1762 | 1763 | - The library is licensed under [MIT](https://github.com/khoih-prog/ESP_WiFiManager_Lite/blob/main/LICENSE) 1764 | 1765 | --- 1766 | 1767 | ### Copyright 1768 | 1769 | Copyright 2021- Khoi Hoang 1770 | 1771 | 1772 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | ## ESP_WiFiManager_Lite (Light Weight Credentials / WiFiManager for ESP32/ESP8266) 2 | 3 | [![arduino-library-badge](https://www.ardu-badge.com/badge/ESP_WiFiManager_Lite.svg?)](https://www.ardu-badge.com/ESP_WiFiManager_Lite) 4 | [![GitHub release](https://img.shields.io/github/release/khoih-prog/ESP_WiFiManager_Lite.svg)](https://github.com/khoih-prog/ESP_WiFiManager_Lite/releases) 5 | [![GitHub](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/khoih-prog/ESP_WiFiManager_Lite/blob/main/LICENSE) 6 | [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](#Contributing) 7 | [![GitHub issues](https://img.shields.io/github/issues/khoih-prog/ESP_WiFiManager_Lite.svg)](http://github.com/khoih-prog/ESP_WiFiManager_Lite/issues) 8 | 9 | Donate to my libraries using BuyMeACoffee 10 | 11 | 12 | --- 13 | --- 14 | 15 | ## Table of Contents 16 | 17 | * [Changelog](#changelog) 18 | * [Release v1.10.5](#release-v1105) 19 | * [Release v1.10.4](#release-v1104) 20 | * [Release v1.10.3](#release-v1103) 21 | * [Release v1.10.2](#release-v1102) 22 | * [Release v1.10.1](#release-v1101) 23 | * [Release v1.10.0](#release-v1100) 24 | * [Release v1.9.0](#release-v190) 25 | * [Release v1.8.2](#release-v182) 26 | * [Release v1.8.1](#release-v181) 27 | * [Release v1.8.0](#release-v180) 28 | * [Release v1.7.0](#release-v170) 29 | * [Release v1.6.0](#release-v160) 30 | * [Release v1.5.1](#release-v151) 31 | * [Major Release v1.5.0](#major-release-v150) 32 | * [Release v1.4.0](#release-v140) 33 | * [Release v1.3.0](#release-v130) 34 | * [Release v1.2.0](#release-v120) 35 | * [Release v1.1.0](#release-v110) 36 | * [Release v1.0.0](#release-v100) 37 | 38 | --- 39 | --- 40 | 41 | ## Changelog 42 | 43 | ### Release v1.10.5 44 | 45 | 1. Using PROGMEM for strings in examples. Check [Example fixes #37](https://github.com/khoih-prog/ESP_WiFiManager_Lite/pull/37) 46 | 2. Improve `README.md` so that links can be used in other sites, such as `PIO` 47 | 48 | ### Release v1.10.4 49 | 50 | 1. Using PROGMEM for HTML strings. Check [move HTML char* into PROGMEM #35](https://github.com/khoih-prog/ESP_WiFiManager_Lite/pull/35) 51 | 52 | ### Release v1.10.3 53 | 54 | 1. Fix compiler error if EEPROM is used. Check [fix compiler error if EEPROM is used #33](https://github.com/khoih-prog/ESP_WiFiManager_Lite/pull/33) 55 | 56 | ### Release v1.10.2 57 | 58 | 1. Add Config Portal scaling support to mobile devices. Check [Mobile scale #30](https://github.com/khoih-prog/ESP_WiFiManager_Lite/pull/30) 59 | 60 | ### Release v1.10.1 61 | 62 | 1. Add public methods to load and save dynamic data. Check [added public methods to load and save dynamic data #28](https://github.com/khoih-prog/ESP_WiFiManager_Lite/pull/28) 63 | 64 | ### Release v1.10.0 65 | 66 | 1. Add Captive-Portal feature. Check [Captive portal #24](https://github.com/khoih-prog/ESP_WiFiManager_Lite/pull/24) 67 | 2. Add option to not `USE_LED_BUILTIN` for Config-Portal. Check [added switch to turn use of builtin LED off #20](https://github.com/khoih-prog/ESP_WiFiManager_Lite/pull/20) 68 | 3. Code clean-up 69 | 70 | ### Release v1.9.0 71 | 72 | 1. Fix ESP32 chipID. Check [Help for storing variables in memory (non-volatile) #87](https://github.com/khoih-prog/ESP_WiFiManager/discussions/87#discussioncomment-3593028) 73 | 2. Add ESP32 getChipID() and getChipOUI() functions 74 | 3. Remove dependency on `LittleFS_esp32` library to prevent PIO error when using new ESP32 core v1.0.6+ 75 | 76 | ### Release v1.8.2 77 | 78 | 1. Optimize code by using passing by `reference` instead of by `value` 79 | 2. Optional `Board_Name` in Menu. Check [option to remove board name from web page #25](https://github.com/khoih-prog/WiFiManager_NINA_Lite/issues/25) 80 | 3. Add function `isConfigMode()` to signal system is in Config Portal mode. 81 | 82 | ### Release v1.8.1 83 | 84 | 1. Add LittleFS support to `ESP32-C3`. 85 | 2. Use `ESP32-core's LittleFS` library instead of `Lorol's LITTLEFS` library for ESP32 core v2.0.0+ 86 | 87 | ### Release v1.8.0 88 | 89 | 1. Add support to `ESP32-S3` (`ESP32S3_DEV, ESP32_S3_BOX, UM TINYS3, UM PROS3, UM FEATHERS3`, etc.) using [ESP32 core, esp32-s3-support branch, v2.0.2+](https://github.com/espressif/arduino-esp32/tree/esp32-s3-support) 90 | 91 | ### Release v1.7.0 92 | 93 | 1. Fix ESP8266 bug not easy to connect to Config Portal for ESP8266 core v3.0.0+ 94 | 2. Fix the blocking issue in loop(). Check [retries block the main loop #18](https://github.com/khoih-prog/WiFiManager_NINA_Lite/issues/18) 95 | 3. Configurable `WIFI_RECON_INTERVAL`. Check [retries block the main loop #18](https://github.com/khoih-prog/WiFiManager_NINA_Lite/issues/18#issuecomment-1006197561) 96 | 4. Clean up 97 | 98 | ### Release v1.6.0 99 | 100 | 1. Auto detect ESP32 core and use either built-in LittleFS or [LITTLEFS](https://github.com/lorol/LITTLEFS) library. 101 | 2. Fix bug returning IP `255.255.255.255` in core v2.0.0+ when using `hostname` 102 | 103 | 104 | ### Release v1.5.1 105 | 106 | 1. Update `platform.ini` and `library.json` to use original `khoih-prog` instead of `khoih.prog` after PIO fix 107 | 108 | ### Major Release v1.5.0 109 | 110 | 1. Enable scan of WiFi networks for selection in Configuration Portal. Check [PR for v1.3.0 - Enable scan of WiFi networks #10](https://github.com/khoih-prog/WiFiManager_NINA_Lite/pull/10). Now you can select optional **SCAN_WIFI_NETWORKS**, **MANUAL_SSID_INPUT_ALLOWED** to be able to manually input SSID, not only from a scanned SSID lists and **MAX_SSID_IN_LIST** (from 2-15) 111 | 2. Minor enhancement to not display garbage when data is invalid 112 | 113 | 114 | ### Release v1.4.0 115 | 116 | 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). 117 | 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). 118 | 119 | ### Release v1.3.0 120 | 121 | 1. Fix invalid "blank" Config Data treated as Valid. 122 | 2. Permit optionally inputting one set of WiFi SSID/PWD by using `REQUIRE_ONE_SET_SSID_PW == true` 123 | 3. Enforce WiFi PWD minimum length of 8 chars 124 | 4. Fix bug where EEPROM_SIZE truncated by DRD/MRD to 512, resulting lost and corrupted data. 125 | 5. Fix crashing bug in serverSendHeaders() 126 | 127 | ### Release v1.2.0 128 | 129 | 1. Configurable **Customs HTML Headers**, including Customs Style, Customs Head Elements, CORS Header. 130 | 2. Fix Config Portal Bug. 131 | 3. Update examples 132 | 133 | ### Release v1.1.0 134 | 135 | 1. Add support to **ESP32-S2 (ESP32-S2 Saola and AI-Thinker ESP-12K)** 136 | 2. Add [**Instructions to install ESP32-S2 core**](#howto-install-esp32-s2-core-for-esp32-s2-saola-ai-thinker-esp-12k-boards-into-arduino-ide) 137 | 138 | ### Release v1.0.0 139 | 140 | 1. Initial release to support ESP32 and ESP8266. 141 | 142 | 143 | -------------------------------------------------------------------------------- /esp32s2_WebServer_Patch/WebServer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | WebServer.cpp - Dead simple web-server. 3 | Supports only one simultaneous client, knows how to handle GET and POST. 4 | 5 | Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | Modified 8 May 2015 by Hristo Gochkov (proper post and file upload handling) 21 | */ 22 | 23 | // KH, Using "WebServer.handleClient delay" (https://github.com/espressif/arduino-esp32/pull/4350) 24 | 25 | #include 26 | #include 27 | #include 28 | #include "WiFiServer.h" 29 | #include "WiFiClient.h" 30 | #include "WebServer.h" 31 | #include "FS.h" 32 | #include "detail/RequestHandlersImpl.h" 33 | #include "mbedtls/md5.h" 34 | 35 | 36 | static const char AUTHORIZATION_HEADER[] = "Authorization"; 37 | static const char qop_auth[] = "qop=\"auth\""; 38 | static const char WWW_Authenticate[] = "WWW-Authenticate"; 39 | static const char Content_Length[] = "Content-Length"; 40 | 41 | 42 | WebServer::WebServer(IPAddress addr, int port) 43 | : _corsEnabled(false) 44 | , _server(addr, port) 45 | , _currentMethod(HTTP_ANY) 46 | , _currentVersion(0) 47 | , _currentStatus(HC_NONE) 48 | , _statusChange(0) 49 | , _nullDelay(true) 50 | , _currentHandler(nullptr) 51 | , _firstHandler(nullptr) 52 | , _lastHandler(nullptr) 53 | , _currentArgCount(0) 54 | , _currentArgs(nullptr) 55 | , _postArgsLen(0) 56 | , _postArgs(nullptr) 57 | , _headerKeysCount(0) 58 | , _currentHeaders(nullptr) 59 | , _contentLength(0) 60 | , _chunked(false) 61 | { 62 | } 63 | 64 | WebServer::WebServer(int port) 65 | : _corsEnabled(false) 66 | , _server(port) 67 | , _currentMethod(HTTP_ANY) 68 | , _currentVersion(0) 69 | , _currentStatus(HC_NONE) 70 | , _statusChange(0) 71 | , _nullDelay(true) 72 | , _currentHandler(nullptr) 73 | , _firstHandler(nullptr) 74 | , _lastHandler(nullptr) 75 | , _currentArgCount(0) 76 | , _currentArgs(nullptr) 77 | , _postArgsLen(0) 78 | , _postArgs(nullptr) 79 | , _headerKeysCount(0) 80 | , _currentHeaders(nullptr) 81 | , _contentLength(0) 82 | , _chunked(false) 83 | { 84 | } 85 | 86 | WebServer::~WebServer() 87 | { 88 | _server.close(); 89 | 90 | if (_currentHeaders) 91 | delete[]_currentHeaders; 92 | 93 | RequestHandler* handler = _firstHandler; 94 | 95 | while (handler) 96 | { 97 | RequestHandler* next = handler->next(); 98 | delete handler; 99 | handler = next; 100 | } 101 | } 102 | 103 | void WebServer::begin() 104 | { 105 | close(); 106 | _server.begin(); 107 | _server.setNoDelay(true); 108 | } 109 | 110 | void WebServer::begin(uint16_t port) 111 | { 112 | close(); 113 | _server.begin(port); 114 | _server.setNoDelay(true); 115 | } 116 | 117 | String WebServer::_extractParam(String& authReq, const String& param, const char delimit) 118 | { 119 | int _begin = authReq.indexOf(param); 120 | 121 | if (_begin == -1) 122 | return ""; 123 | 124 | return authReq.substring(_begin + param.length(), authReq.indexOf(delimit, _begin + param.length())); 125 | } 126 | 127 | static String md5str(String &in) 128 | { 129 | char out[33] = {0}; 130 | mbedtls_md5_context _ctx; 131 | uint8_t i; 132 | uint8_t * _buf = (uint8_t*)malloc(16); 133 | 134 | if (_buf == NULL) 135 | return String(out); 136 | 137 | memset(_buf, 0x00, 16); 138 | mbedtls_md5_init(&_ctx); 139 | mbedtls_md5_starts(&_ctx); 140 | mbedtls_md5_update(&_ctx, (const uint8_t *)in.c_str(), in.length()); 141 | mbedtls_md5_finish(&_ctx, _buf); 142 | 143 | for (i = 0; i < 16; i++) 144 | { 145 | sprintf(out + (i * 2), "%02x", _buf[i]); 146 | } 147 | 148 | out[32] = 0; 149 | free(_buf); 150 | return String(out); 151 | } 152 | 153 | bool WebServer::authenticate(const char * username, const char * password) 154 | { 155 | if (hasHeader(FPSTR(AUTHORIZATION_HEADER))) 156 | { 157 | String authReq = header(FPSTR(AUTHORIZATION_HEADER)); 158 | 159 | if (authReq.startsWith(F("Basic"))) 160 | { 161 | authReq = authReq.substring(6); 162 | authReq.trim(); 163 | char toencodeLen = strlen(username) + strlen(password) + 1; 164 | char *toencode = new char[toencodeLen + 1]; 165 | 166 | if (toencode == NULL) 167 | { 168 | authReq = ""; 169 | return false; 170 | } 171 | 172 | char *encoded = new char[base64_encode_expected_len(toencodeLen) + 1]; 173 | 174 | if (encoded == NULL) 175 | { 176 | authReq = ""; 177 | delete[] toencode; 178 | return false; 179 | } 180 | 181 | sprintf(toencode, "%s:%s", username, password); 182 | 183 | if (base64_encode_chars(toencode, toencodeLen, encoded) > 0 && authReq.equalsConstantTime(encoded)) 184 | { 185 | authReq = ""; 186 | delete[] toencode; 187 | delete[] encoded; 188 | return true; 189 | } 190 | 191 | delete[] toencode; 192 | delete[] encoded; 193 | } 194 | else if (authReq.startsWith(F("Digest"))) 195 | { 196 | authReq = authReq.substring(7); 197 | log_v("%s", authReq.c_str()); 198 | String _username = _extractParam(authReq, F("username=\""), '\"'); 199 | 200 | if (!_username.length() || _username != String(username)) 201 | { 202 | authReq = ""; 203 | return false; 204 | } 205 | 206 | // extracting required parameters for RFC 2069 simpler Digest 207 | String _realm = _extractParam(authReq, F("realm=\""), '\"'); 208 | String _nonce = _extractParam(authReq, F("nonce=\""), '\"'); 209 | String _uri = _extractParam(authReq, F("uri=\""), '\"'); 210 | String _response = _extractParam(authReq, F("response=\""), '\"'); 211 | String _opaque = _extractParam(authReq, F("opaque=\""), '\"'); 212 | 213 | if ((!_realm.length()) || (!_nonce.length()) || (!_uri.length()) || (!_response.length()) || (!_opaque.length())) 214 | { 215 | authReq = ""; 216 | return false; 217 | } 218 | 219 | if ((_opaque != _sopaque) || (_nonce != _snonce) || (_realm != _srealm)) 220 | { 221 | authReq = ""; 222 | return false; 223 | } 224 | 225 | // parameters for the RFC 2617 newer Digest 226 | String _nc, _cnonce; 227 | 228 | if (authReq.indexOf(FPSTR(qop_auth)) != -1) 229 | { 230 | _nc = _extractParam(authReq, F("nc="), ','); 231 | _cnonce = _extractParam(authReq, F("cnonce=\""), '\"'); 232 | } 233 | 234 | String _H1 = md5str(String(username) + ':' + _realm + ':' + String(password)); 235 | log_v("Hash of user:realm:pass=%s", _H1.c_str()); 236 | String _H2 = ""; 237 | 238 | if (_currentMethod == HTTP_GET) 239 | { 240 | _H2 = md5str(String(F("GET:")) + _uri); 241 | } 242 | else if (_currentMethod == HTTP_POST) 243 | { 244 | _H2 = md5str(String(F("POST:")) + _uri); 245 | } 246 | else if (_currentMethod == HTTP_PUT) 247 | { 248 | _H2 = md5str(String(F("PUT:")) + _uri); 249 | } 250 | else if (_currentMethod == HTTP_DELETE) 251 | { 252 | _H2 = md5str(String(F("DELETE:")) + _uri); 253 | } 254 | else 255 | { 256 | _H2 = md5str(String(F("GET:")) + _uri); 257 | } 258 | 259 | log_v("Hash of GET:uri=%s", _H2.c_str()); 260 | String _responsecheck = ""; 261 | 262 | if (authReq.indexOf(FPSTR(qop_auth)) != -1) 263 | { 264 | _responsecheck = md5str(_H1 + ':' + _nonce + ':' + _nc + ':' + _cnonce + F(":auth:") + _H2); 265 | } 266 | else 267 | { 268 | _responsecheck = md5str(_H1 + ':' + _nonce + ':' + _H2); 269 | } 270 | 271 | log_v("The Proper response=%s", _responsecheck.c_str()); 272 | 273 | if (_response == _responsecheck) 274 | { 275 | authReq = ""; 276 | return true; 277 | } 278 | } 279 | 280 | authReq = ""; 281 | } 282 | 283 | return false; 284 | } 285 | 286 | String WebServer::_getRandomHexString() 287 | { 288 | char buffer[33]; // buffer to hold 32 Hex Digit + /0 289 | int i; 290 | 291 | for (i = 0; i < 4; i++) 292 | { 293 | sprintf (buffer + (i * 8), "%08x", esp_random()); 294 | } 295 | 296 | return String(buffer); 297 | } 298 | 299 | void WebServer::requestAuthentication(HTTPAuthMethod mode, const char* realm, const String& authFailMsg) 300 | { 301 | if (realm == NULL) 302 | { 303 | _srealm = String(F("Login Required")); 304 | } 305 | else 306 | { 307 | _srealm = String(realm); 308 | } 309 | 310 | if (mode == BASIC_AUTH) 311 | { 312 | sendHeader(String(FPSTR(WWW_Authenticate)), String(F("Basic realm=\"")) + _srealm + String(F("\""))); 313 | } 314 | else 315 | { 316 | _snonce = _getRandomHexString(); 317 | _sopaque = _getRandomHexString(); 318 | sendHeader(String(FPSTR(WWW_Authenticate)), 319 | String(F("Digest realm=\"")) + _srealm + String(F("\", qop=\"auth\", nonce=\"")) + _snonce + String( 320 | F("\", opaque=\"")) + _sopaque + String(F("\""))); 321 | } 322 | 323 | using namespace mime; 324 | send(401, String(FPSTR(mimeTable[html].mimeType)), authFailMsg); 325 | } 326 | 327 | void WebServer::on(const Uri &uri, WebServer::THandlerFunction handler) 328 | { 329 | on(uri, HTTP_ANY, handler); 330 | } 331 | 332 | void WebServer::on(const Uri &uri, HTTPMethod method, WebServer::THandlerFunction fn) 333 | { 334 | on(uri, method, fn, _fileUploadHandler); 335 | } 336 | 337 | void WebServer::on(const Uri &uri, HTTPMethod method, WebServer::THandlerFunction fn, WebServer::THandlerFunction ufn) 338 | { 339 | _addRequestHandler(new FunctionRequestHandler(fn, ufn, uri, method)); 340 | } 341 | 342 | void WebServer::addHandler(RequestHandler* handler) 343 | { 344 | _addRequestHandler(handler); 345 | } 346 | 347 | void WebServer::_addRequestHandler(RequestHandler* handler) 348 | { 349 | if (!_lastHandler) 350 | { 351 | _firstHandler = handler; 352 | _lastHandler = handler; 353 | } 354 | else 355 | { 356 | _lastHandler->next(handler); 357 | _lastHandler = handler; 358 | } 359 | } 360 | 361 | void WebServer::serveStatic(const char* uri, FS& fs, const char* path, const char* cache_header) 362 | { 363 | _addRequestHandler(new StaticRequestHandler(fs, path, uri, cache_header)); 364 | } 365 | 366 | void WebServer::handleClient() 367 | { 368 | if (_currentStatus == HC_NONE) 369 | { 370 | WiFiClient client = _server.available(); 371 | 372 | if (!client) 373 | { 374 | if (_nullDelay) 375 | { 376 | delay(1); 377 | } 378 | 379 | return; 380 | } 381 | 382 | log_v("New client"); 383 | 384 | _currentClient = client; 385 | _currentStatus = HC_WAIT_READ; 386 | _statusChange = millis(); 387 | } 388 | 389 | bool keepCurrentClient = false; 390 | bool callYield = false; 391 | 392 | if (_currentClient.connected()) 393 | { 394 | switch (_currentStatus) 395 | { 396 | case HC_NONE: 397 | // No-op to avoid C++ compiler warning 398 | break; 399 | 400 | case HC_WAIT_READ: 401 | 402 | // Wait for data from client to become available 403 | if (_currentClient.available()) 404 | { 405 | if (_parseRequest(_currentClient)) 406 | { 407 | // because HTTP_MAX_SEND_WAIT is expressed in milliseconds, 408 | // it must be divided by 1000 409 | _currentClient.setTimeout(HTTP_MAX_SEND_WAIT / 1000); 410 | _contentLength = CONTENT_LENGTH_NOT_SET; 411 | _handleRequest(); 412 | 413 | // Fix for issue with Chrome based browsers: https://github.com/espressif/arduino-esp32/issues/3652 414 | // if (_currentClient.connected()) { 415 | // _currentStatus = HC_WAIT_CLOSE; 416 | // _statusChange = millis(); 417 | // keepCurrentClient = true; 418 | // } 419 | } 420 | } 421 | else // !_currentClient.available() 422 | { 423 | if (millis() - _statusChange <= HTTP_MAX_DATA_WAIT) 424 | { 425 | keepCurrentClient = true; 426 | } 427 | 428 | callYield = true; 429 | } 430 | 431 | break; 432 | 433 | case HC_WAIT_CLOSE: 434 | 435 | // Wait for client to close the connection 436 | if (millis() - _statusChange <= HTTP_MAX_CLOSE_WAIT) 437 | { 438 | keepCurrentClient = true; 439 | callYield = true; 440 | } 441 | } 442 | } 443 | 444 | if (!keepCurrentClient) 445 | { 446 | _currentClient = WiFiClient(); 447 | _currentStatus = HC_NONE; 448 | _currentUpload.reset(); 449 | } 450 | 451 | if (callYield) 452 | { 453 | yield(); 454 | } 455 | } 456 | 457 | void WebServer::close() 458 | { 459 | _server.close(); 460 | _currentStatus = HC_NONE; 461 | 462 | if (!_headerKeysCount) 463 | collectHeaders(0, 0); 464 | } 465 | 466 | void WebServer::stop() 467 | { 468 | close(); 469 | } 470 | 471 | void WebServer::sendHeader(const String& name, const String& value, bool first) 472 | { 473 | String headerLine = name; 474 | headerLine += F(": "); 475 | headerLine += value; 476 | headerLine += "\r\n"; 477 | 478 | if (first) 479 | { 480 | _responseHeaders = headerLine + _responseHeaders; 481 | } 482 | else 483 | { 484 | _responseHeaders += headerLine; 485 | } 486 | } 487 | 488 | void WebServer::setContentLength(const size_t contentLength) 489 | { 490 | _contentLength = contentLength; 491 | } 492 | 493 | void WebServer::enableDelay(boolean value) 494 | { 495 | _nullDelay = value; 496 | } 497 | 498 | void WebServer::enableCORS(boolean value) 499 | { 500 | _corsEnabled = value; 501 | } 502 | 503 | void WebServer::enableCrossOrigin(boolean value) 504 | { 505 | enableCORS(value); 506 | } 507 | 508 | void WebServer::_prepareHeader(String& response, int code, const char* content_type, size_t contentLength) 509 | { 510 | response = String(F("HTTP/1.")) + String(_currentVersion) + ' '; 511 | response += String(code); 512 | response += ' '; 513 | response += _responseCodeToString(code); 514 | response += "\r\n"; 515 | 516 | using namespace mime; 517 | 518 | if (!content_type) 519 | content_type = mimeTable[html].mimeType; 520 | 521 | sendHeader(String(F("Content-Type")), String(FPSTR(content_type)), true); 522 | 523 | if (_contentLength == CONTENT_LENGTH_NOT_SET) 524 | { 525 | sendHeader(String(FPSTR(Content_Length)), String(contentLength)); 526 | } 527 | else if (_contentLength != CONTENT_LENGTH_UNKNOWN) 528 | { 529 | sendHeader(String(FPSTR(Content_Length)), String(_contentLength)); 530 | } 531 | else if (_contentLength == CONTENT_LENGTH_UNKNOWN && _currentVersion) //HTTP/1.1 or above client 532 | { 533 | //let's do chunked 534 | _chunked = true; 535 | sendHeader(String(F("Accept-Ranges")), String(F("none"))); 536 | sendHeader(String(F("Transfer-Encoding")), String(F("chunked"))); 537 | } 538 | 539 | if (_corsEnabled) 540 | { 541 | sendHeader(String(FPSTR("Access-Control-Allow-Origin")), String("*")); 542 | } 543 | 544 | sendHeader(String(F("Connection")), String(F("close"))); 545 | 546 | response += _responseHeaders; 547 | response += "\r\n"; 548 | _responseHeaders = ""; 549 | } 550 | 551 | void WebServer::send(int code, const char* content_type, const String& content) 552 | { 553 | String header; 554 | // Can we assume the following? 555 | //if(code == 200 && content.length() == 0 && _contentLength == CONTENT_LENGTH_NOT_SET) 556 | // _contentLength = CONTENT_LENGTH_UNKNOWN; 557 | _prepareHeader(header, code, content_type, content.length()); 558 | _currentClientWrite(header.c_str(), header.length()); 559 | 560 | if (content.length()) 561 | sendContent(content); 562 | } 563 | 564 | void WebServer::send_P(int code, PGM_P content_type, PGM_P content) 565 | { 566 | size_t contentLength = 0; 567 | 568 | if (content != NULL) 569 | { 570 | contentLength = strlen_P(content); 571 | } 572 | 573 | String header; 574 | char type[64]; 575 | memccpy_P((void*)type, (PGM_VOID_P)content_type, 0, sizeof(type)); 576 | _prepareHeader(header, code, (const char* )type, contentLength); 577 | _currentClientWrite(header.c_str(), header.length()); 578 | sendContent_P(content); 579 | } 580 | 581 | void WebServer::send_P(int code, PGM_P content_type, PGM_P content, size_t contentLength) 582 | { 583 | String header; 584 | char type[64]; 585 | memccpy_P((void*)type, (PGM_VOID_P)content_type, 0, sizeof(type)); 586 | _prepareHeader(header, code, (const char* )type, contentLength); 587 | sendContent(header); 588 | sendContent_P(content, contentLength); 589 | } 590 | 591 | void WebServer::send(int code, char* content_type, const String& content) 592 | { 593 | send(code, (const char*)content_type, content); 594 | } 595 | 596 | void WebServer::send(int code, const String& content_type, const String& content) 597 | { 598 | send(code, (const char*)content_type.c_str(), content); 599 | } 600 | 601 | void WebServer::sendContent(const String& content) 602 | { 603 | sendContent(content.c_str(), content.length()); 604 | } 605 | 606 | void WebServer::sendContent(const char* content, size_t contentLength) 607 | { 608 | const char * footer = "\r\n"; 609 | 610 | if (_chunked) 611 | { 612 | char * chunkSize = (char *)malloc(11); 613 | 614 | if (chunkSize) 615 | { 616 | sprintf(chunkSize, "%x%s", contentLength, footer); 617 | _currentClientWrite(chunkSize, strlen(chunkSize)); 618 | free(chunkSize); 619 | } 620 | } 621 | 622 | _currentClientWrite(content, contentLength); 623 | 624 | if (_chunked) 625 | { 626 | _currentClient.write(footer, 2); 627 | 628 | if (contentLength == 0) 629 | { 630 | _chunked = false; 631 | } 632 | } 633 | } 634 | 635 | void WebServer::sendContent_P(PGM_P content) 636 | { 637 | sendContent_P(content, strlen_P(content)); 638 | } 639 | 640 | void WebServer::sendContent_P(PGM_P content, size_t size) 641 | { 642 | const char * footer = "\r\n"; 643 | 644 | if (_chunked) 645 | { 646 | char * chunkSize = (char *)malloc(11); 647 | 648 | if (chunkSize) 649 | { 650 | sprintf(chunkSize, "%x%s", size, footer); 651 | _currentClientWrite(chunkSize, strlen(chunkSize)); 652 | free(chunkSize); 653 | } 654 | } 655 | 656 | _currentClientWrite_P(content, size); 657 | 658 | if (_chunked) 659 | { 660 | _currentClient.write(footer, 2); 661 | 662 | if (size == 0) 663 | { 664 | _chunked = false; 665 | } 666 | } 667 | } 668 | 669 | 670 | void WebServer::_streamFileCore(const size_t fileSize, const String & fileName, const String & contentType) 671 | { 672 | using namespace mime; 673 | setContentLength(fileSize); 674 | 675 | if (fileName.endsWith(String(FPSTR(mimeTable[gz].endsWith))) && 676 | contentType != String(FPSTR(mimeTable[gz].mimeType)) && 677 | contentType != String(FPSTR(mimeTable[none].mimeType))) 678 | { 679 | sendHeader(F("Content-Encoding"), F("gzip")); 680 | } 681 | 682 | send(200, contentType, ""); 683 | } 684 | 685 | String WebServer::pathArg(unsigned int i) 686 | { 687 | if (_currentHandler != nullptr) 688 | return _currentHandler->pathArg(i); 689 | 690 | return ""; 691 | } 692 | 693 | String WebServer::arg(String name) 694 | { 695 | for (int j = 0; j < _postArgsLen; ++j) 696 | { 697 | if ( _postArgs[j].key == name ) 698 | return _postArgs[j].value; 699 | } 700 | 701 | for (int i = 0; i < _currentArgCount; ++i) 702 | { 703 | if ( _currentArgs[i].key == name ) 704 | return _currentArgs[i].value; 705 | } 706 | 707 | return ""; 708 | } 709 | 710 | String WebServer::arg(int i) 711 | { 712 | if (i < _currentArgCount) 713 | return _currentArgs[i].value; 714 | 715 | return ""; 716 | } 717 | 718 | String WebServer::argName(int i) 719 | { 720 | if (i < _currentArgCount) 721 | return _currentArgs[i].key; 722 | 723 | return ""; 724 | } 725 | 726 | int WebServer::args() 727 | { 728 | return _currentArgCount; 729 | } 730 | 731 | bool WebServer::hasArg(String name) 732 | { 733 | for (int j = 0; j < _postArgsLen; ++j) 734 | { 735 | if (_postArgs[j].key == name) 736 | return true; 737 | } 738 | 739 | for (int i = 0; i < _currentArgCount; ++i) 740 | { 741 | if (_currentArgs[i].key == name) 742 | return true; 743 | } 744 | 745 | return false; 746 | } 747 | 748 | 749 | String WebServer::header(String name) 750 | { 751 | for (int i = 0; i < _headerKeysCount; ++i) 752 | { 753 | if (_currentHeaders[i].key.equalsIgnoreCase(name)) 754 | return _currentHeaders[i].value; 755 | } 756 | 757 | return ""; 758 | } 759 | 760 | void WebServer::collectHeaders(const char* headerKeys[], const size_t headerKeysCount) 761 | { 762 | _headerKeysCount = headerKeysCount + 1; 763 | 764 | if (_currentHeaders) 765 | delete[]_currentHeaders; 766 | 767 | _currentHeaders = new RequestArgument[_headerKeysCount]; 768 | _currentHeaders[0].key = FPSTR(AUTHORIZATION_HEADER); 769 | 770 | for (int i = 1; i < _headerKeysCount; i++) 771 | { 772 | _currentHeaders[i].key = headerKeys[i - 1]; 773 | } 774 | } 775 | 776 | String WebServer::header(int i) 777 | { 778 | if (i < _headerKeysCount) 779 | return _currentHeaders[i].value; 780 | 781 | return ""; 782 | } 783 | 784 | String WebServer::headerName(int i) 785 | { 786 | if (i < _headerKeysCount) 787 | return _currentHeaders[i].key; 788 | 789 | return ""; 790 | } 791 | 792 | int WebServer::headers() 793 | { 794 | return _headerKeysCount; 795 | } 796 | 797 | bool WebServer::hasHeader(String name) 798 | { 799 | for (int i = 0; i < _headerKeysCount; ++i) 800 | { 801 | if ((_currentHeaders[i].key.equalsIgnoreCase(name)) && (_currentHeaders[i].value.length() > 0)) 802 | return true; 803 | } 804 | 805 | return false; 806 | } 807 | 808 | String WebServer::hostHeader() 809 | { 810 | return _hostHeader; 811 | } 812 | 813 | void WebServer::onFileUpload(THandlerFunction fn) 814 | { 815 | _fileUploadHandler = fn; 816 | } 817 | 818 | void WebServer::onNotFound(THandlerFunction fn) 819 | { 820 | _notFoundHandler = fn; 821 | } 822 | 823 | void WebServer::_handleRequest() 824 | { 825 | bool handled = false; 826 | 827 | if (!_currentHandler) 828 | { 829 | log_e("request handler not found"); 830 | } 831 | else 832 | { 833 | handled = _currentHandler->handle(*this, _currentMethod, _currentUri); 834 | 835 | if (!handled) 836 | { 837 | log_e("request handler failed to handle request"); 838 | } 839 | } 840 | 841 | if (!handled && _notFoundHandler) 842 | { 843 | _notFoundHandler(); 844 | handled = true; 845 | } 846 | 847 | if (!handled) 848 | { 849 | using namespace mime; 850 | send(404, String(FPSTR(mimeTable[html].mimeType)), String(F("Not found: ")) + _currentUri); 851 | handled = true; 852 | } 853 | 854 | if (handled) 855 | { 856 | _finalizeResponse(); 857 | } 858 | 859 | _currentUri = ""; 860 | } 861 | 862 | 863 | void WebServer::_finalizeResponse() 864 | { 865 | if (_chunked) 866 | { 867 | sendContent(""); 868 | } 869 | } 870 | 871 | String WebServer::_responseCodeToString(int code) 872 | { 873 | switch (code) 874 | { 875 | case 100: 876 | return F("Continue"); 877 | 878 | case 101: 879 | return F("Switching Protocols"); 880 | 881 | case 200: 882 | return F("OK"); 883 | 884 | case 201: 885 | return F("Created"); 886 | 887 | case 202: 888 | return F("Accepted"); 889 | 890 | case 203: 891 | return F("Non-Authoritative Information"); 892 | 893 | case 204: 894 | return F("No Content"); 895 | 896 | case 205: 897 | return F("Reset Content"); 898 | 899 | case 206: 900 | return F("Partial Content"); 901 | 902 | case 300: 903 | return F("Multiple Choices"); 904 | 905 | case 301: 906 | return F("Moved Permanently"); 907 | 908 | case 302: 909 | return F("Found"); 910 | 911 | case 303: 912 | return F("See Other"); 913 | 914 | case 304: 915 | return F("Not Modified"); 916 | 917 | case 305: 918 | return F("Use Proxy"); 919 | 920 | case 307: 921 | return F("Temporary Redirect"); 922 | 923 | case 400: 924 | return F("Bad Request"); 925 | 926 | case 401: 927 | return F("Unauthorized"); 928 | 929 | case 402: 930 | return F("Payment Required"); 931 | 932 | case 403: 933 | return F("Forbidden"); 934 | 935 | case 404: 936 | return F("Not Found"); 937 | 938 | case 405: 939 | return F("Method Not Allowed"); 940 | 941 | case 406: 942 | return F("Not Acceptable"); 943 | 944 | case 407: 945 | return F("Proxy Authentication Required"); 946 | 947 | case 408: 948 | return F("Request Time-out"); 949 | 950 | case 409: 951 | return F("Conflict"); 952 | 953 | case 410: 954 | return F("Gone"); 955 | 956 | case 411: 957 | return F("Length Required"); 958 | 959 | case 412: 960 | return F("Precondition Failed"); 961 | 962 | case 413: 963 | return F("Request Entity Too Large"); 964 | 965 | case 414: 966 | return F("Request-URI Too Large"); 967 | 968 | case 415: 969 | return F("Unsupported Media Type"); 970 | 971 | case 416: 972 | return F("Requested range not satisfiable"); 973 | 974 | case 417: 975 | return F("Expectation Failed"); 976 | 977 | case 500: 978 | return F("Internal Server Error"); 979 | 980 | case 501: 981 | return F("Not Implemented"); 982 | 983 | case 502: 984 | return F("Bad Gateway"); 985 | 986 | case 503: 987 | return F("Service Unavailable"); 988 | 989 | case 504: 990 | return F("Gateway Time-out"); 991 | 992 | case 505: 993 | return F("HTTP Version not supported"); 994 | 995 | default: 996 | return F(""); 997 | } 998 | } 999 | -------------------------------------------------------------------------------- /esp32s2_WebServer_Patch/WebServer.h: -------------------------------------------------------------------------------- 1 | /* 2 | WebServer.h - Dead simple web-server. 3 | Supports only one simultaneous client, knows how to handle GET and POST. 4 | 5 | Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | Modified 8 May 2015 by Hristo Gochkov (proper post and file upload handling) 21 | */ 22 | 23 | 24 | #ifndef WEBSERVER_H 25 | #define WEBSERVER_H 26 | 27 | #include 28 | #include 29 | #include 30 | #include "HTTP_Method.h" 31 | #include "Uri.h" 32 | 33 | enum HTTPUploadStatus { UPLOAD_FILE_START, UPLOAD_FILE_WRITE, UPLOAD_FILE_END, 34 | UPLOAD_FILE_ABORTED 35 | }; 36 | enum HTTPClientStatus { HC_NONE, HC_WAIT_READ, HC_WAIT_CLOSE }; 37 | enum HTTPAuthMethod { BASIC_AUTH, DIGEST_AUTH }; 38 | 39 | #define HTTP_DOWNLOAD_UNIT_SIZE 1436 40 | 41 | #ifndef HTTP_UPLOAD_BUFLEN 42 | #define HTTP_UPLOAD_BUFLEN 1436 43 | #endif 44 | 45 | #define HTTP_MAX_DATA_WAIT 5000 //ms to wait for the client to send the request 46 | #define HTTP_MAX_POST_WAIT 5000 //ms to wait for POST data to arrive 47 | #define HTTP_MAX_SEND_WAIT 5000 //ms to wait for data chunk to be ACKed 48 | #define HTTP_MAX_CLOSE_WAIT 2000 //ms to wait for the client to close the connection 49 | 50 | #define CONTENT_LENGTH_UNKNOWN ((size_t) -1) 51 | #define CONTENT_LENGTH_NOT_SET ((size_t) -2) 52 | 53 | class WebServer; 54 | 55 | typedef struct 56 | { 57 | HTTPUploadStatus status; 58 | String filename; 59 | String name; 60 | String type; 61 | size_t totalSize; // file size 62 | size_t currentSize; // size of data currently in buf 63 | uint8_t buf[HTTP_UPLOAD_BUFLEN]; 64 | } HTTPUpload; 65 | 66 | #include "detail/RequestHandler.h" 67 | 68 | namespace fs 69 | { 70 | class FS; 71 | } 72 | 73 | class WebServer 74 | { 75 | public: 76 | WebServer(IPAddress addr, int port = 80); 77 | WebServer(int port = 80); 78 | virtual ~WebServer(); 79 | 80 | virtual void begin(); 81 | virtual void begin(uint16_t port); 82 | virtual void handleClient(); 83 | 84 | virtual void close(); 85 | void stop(); 86 | 87 | bool authenticate(const char * username, const char * password); 88 | void requestAuthentication(HTTPAuthMethod mode = BASIC_AUTH, const char* realm = NULL, 89 | const String& authFailMsg = String("") ); 90 | 91 | typedef std::function THandlerFunction; 92 | void on(const Uri &uri, THandlerFunction handler); 93 | void on(const Uri &uri, HTTPMethod method, THandlerFunction fn); 94 | void on(const Uri &uri, HTTPMethod method, THandlerFunction fn, THandlerFunction ufn); 95 | void addHandler(RequestHandler* handler); 96 | void serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_header = NULL ); 97 | void onNotFound(THandlerFunction fn); //called when handler is not assigned 98 | void onFileUpload(THandlerFunction fn); //handle file uploads 99 | 100 | String uri() 101 | { 102 | return _currentUri; 103 | } 104 | HTTPMethod method() 105 | { 106 | return _currentMethod; 107 | } 108 | virtual WiFiClient client() 109 | { 110 | return _currentClient; 111 | } 112 | HTTPUpload& upload() 113 | { 114 | return *_currentUpload; 115 | } 116 | 117 | String pathArg(unsigned int i); // get request path argument by number 118 | String arg(String name); // get request argument value by name 119 | String arg(int i); // get request argument value by number 120 | String argName(int i); // get request argument name by number 121 | int args(); // get arguments count 122 | bool hasArg(String name); // check if argument exists 123 | void collectHeaders(const char* headerKeys[], const size_t headerKeysCount); // set the request headers to collect 124 | String header(String name); // get request header value by name 125 | String header(int i); // get request header value by number 126 | String headerName(int i); // get request header name by number 127 | int headers(); // get header count 128 | bool hasHeader(String name); // check if header exists 129 | 130 | String hostHeader(); // get request host header if available or empty String if not 131 | 132 | // send response to the client 133 | // code - HTTP response code, can be 200 or 404 134 | // content_type - HTTP content type, like "text/plain" or "image/png" 135 | // content - actual content body 136 | void send(int code, const char* content_type = NULL, const String& content = String("")); 137 | void send(int code, char* content_type, const String& content); 138 | void send(int code, const String& content_type, const String& content); 139 | void send_P(int code, PGM_P content_type, PGM_P content); 140 | void send_P(int code, PGM_P content_type, PGM_P content, size_t contentLength); 141 | 142 | void enableDelay(boolean value); 143 | void enableCORS(boolean value = true); 144 | void enableCrossOrigin(boolean value = true); 145 | 146 | void setContentLength(const size_t contentLength); 147 | void sendHeader(const String& name, const String& value, bool first = false); 148 | void sendContent(const String& content); 149 | void sendContent(const char* content, size_t contentLength); 150 | void sendContent_P(PGM_P content); 151 | void sendContent_P(PGM_P content, size_t size); 152 | 153 | static String urlDecode(const String& text); 154 | 155 | template 156 | size_t streamFile(T &file, const String& contentType) 157 | { 158 | _streamFileCore(file.size(), file.name(), contentType); 159 | return _currentClient.write(file); 160 | } 161 | 162 | protected: 163 | virtual size_t _currentClientWrite(const char* b, size_t l) 164 | { 165 | return _currentClient.write( b, l ); 166 | } 167 | virtual size_t _currentClientWrite_P(PGM_P b, size_t l) 168 | { 169 | return _currentClient.write_P( b, l ); 170 | } 171 | void _addRequestHandler(RequestHandler* handler); 172 | void _handleRequest(); 173 | void _finalizeResponse(); 174 | bool _parseRequest(WiFiClient& client); 175 | void _parseArguments(String data); 176 | static String _responseCodeToString(int code); 177 | bool _parseForm(WiFiClient& client, String boundary, uint32_t len); 178 | bool _parseFormUploadAborted(); 179 | void _uploadWriteByte(uint8_t b); 180 | int _uploadReadByte(WiFiClient& client); 181 | void _prepareHeader(String& response, int code, const char* content_type, size_t contentLength); 182 | bool _collectHeader(const char* headerName, const char* headerValue); 183 | 184 | void _streamFileCore(const size_t fileSize, const String & fileName, const String & contentType); 185 | 186 | String _getRandomHexString(); 187 | // for extracting Auth parameters 188 | String _extractParam(String& authReq, const String& param, const char delimit = '"'); 189 | 190 | struct RequestArgument 191 | { 192 | String key; 193 | String value; 194 | }; 195 | 196 | boolean _corsEnabled; 197 | WiFiServer _server; 198 | 199 | WiFiClient _currentClient; 200 | HTTPMethod _currentMethod; 201 | String _currentUri; 202 | uint8_t _currentVersion; 203 | HTTPClientStatus _currentStatus; 204 | unsigned long _statusChange; 205 | bool _nullDelay; 206 | 207 | RequestHandler* _currentHandler; 208 | RequestHandler* _firstHandler; 209 | RequestHandler* _lastHandler; 210 | THandlerFunction _notFoundHandler; 211 | THandlerFunction _fileUploadHandler; 212 | 213 | int _currentArgCount; 214 | RequestArgument* _currentArgs; 215 | int _postArgsLen; 216 | RequestArgument* _postArgs; 217 | 218 | std::unique_ptr _currentUpload; 219 | 220 | int _headerKeysCount; 221 | RequestArgument* _currentHeaders; 222 | size_t _contentLength; 223 | String _responseHeaders; 224 | 225 | String _hostHeader; 226 | bool _chunked; 227 | 228 | String _snonce; // Store noance and opaque for future comparison 229 | String _sopaque; 230 | String _srealm; // Store the Auth realm between Calls 231 | 232 | }; 233 | 234 | 235 | #endif //ESP8266WEBSERVER_H 236 | -------------------------------------------------------------------------------- /examples/ESP_WiFi/Credentials.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | Credentials.h 3 | For ESP8266 / ESP32 boards 4 | 5 | ESP_WiFiManager_Lite (https://github.com/khoih-prog/ESP_WiFiManager_Lite) is a library 6 | for the ESP32/ESP8266 boards to enable store Credentials in EEPROM/SPIFFS/LittleFS for easy 7 | configuration/reconfiguration and autoconnect/autoreconnect of WiFi and other services without Hardcoding. 8 | 9 | Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager_Lite 10 | Licensed under MIT license 11 | *****************************************************************************************************************************/ 12 | 13 | #ifndef Credentials_h 14 | #define Credentials_h 15 | 16 | #include "defines.h" 17 | 18 | /// Start Default Config Data ////////////////// 19 | 20 | /* 21 | #define SSID_MAX_LEN 32 22 | //From v1.0.3, WPA2 passwords can be up to 63 characters long. 23 | #define PASS_MAX_LEN 64 24 | 25 | typedef struct 26 | { 27 | char wifi_ssid[SSID_MAX_LEN]; 28 | char wifi_pw [PASS_MAX_LEN]; 29 | } WiFi_Credentials; 30 | 31 | #define NUM_WIFI_CREDENTIALS 2 32 | 33 | // Configurable items besides fixed Header, just add board_name 34 | #define NUM_CONFIGURABLE_ITEMS ( ( 2 * NUM_WIFI_CREDENTIALS ) + 1 ) 35 | //////////////// 36 | 37 | typedef struct Configuration 38 | { 39 | char header [16]; 40 | WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS]; 41 | char board_name [24]; 42 | int checkSum; 43 | } ESP_WM_LITE_Configuration; 44 | */ 45 | 46 | #define TO_LOAD_DEFAULT_CONFIG_DATA false 47 | 48 | #if TO_LOAD_DEFAULT_CONFIG_DATA 49 | 50 | // This feature is primarily used in development to force a known set of values as Config Data 51 | // It will NOT force the Config Portal to activate. Use DRD or erase Config Data with ESP_WiFiManager.clearConfigData() 52 | 53 | // Used mostly for development and debugging. FORCES default values to be loaded each run. 54 | // Config Portal data input will be ignored and overridden by DEFAULT_CONFIG_DATA 55 | //bool LOAD_DEFAULT_CONFIG_DATA = true; 56 | 57 | // Used mostly once debugged. Assumes good data already saved in device. 58 | // Config Portal data input will be override DEFAULT_CONFIG_DATA 59 | bool LOAD_DEFAULT_CONFIG_DATA = false; 60 | 61 | 62 | ESP_WM_LITE_Configuration defaultConfig = 63 | { 64 | //char header[16], dummy, not used 65 | #if ESP8266 66 | "ESP8266", 67 | #else 68 | "ESP32", 69 | #endif 70 | 71 | // WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS]; 72 | // WiFi_Credentials.wifi_ssid and WiFi_Credentials.wifi_pw 73 | "SSID1", "password1", 74 | "SSID2", "password2", 75 | //char board_name [24]; 76 | 77 | #if ESP8266 78 | "ESP8266-Control", 79 | #else 80 | "ESP32-Control", 81 | #endif 82 | 83 | // terminate the list 84 | //int checkSum, dummy, not used 85 | 0 86 | /////////// End Default Config Data ///////////// 87 | }; 88 | 89 | #else 90 | 91 | bool LOAD_DEFAULT_CONFIG_DATA = false; 92 | 93 | ESP_WM_LITE_Configuration defaultConfig; 94 | 95 | #endif // TO_LOAD_DEFAULT_CONFIG_DATA 96 | 97 | /////////// End Default Config Data ///////////// 98 | 99 | 100 | #endif //Credentials_h 101 | -------------------------------------------------------------------------------- /examples/ESP_WiFi/ESP_WiFi.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | ESP_WiFi.ino 3 | For ESP8266 / ESP32 boards 4 | 5 | ESP_WiFiManager_Lite (https://github.com/khoih-prog/ESP_WiFiManager_Lite) is a library 6 | for the ESP32/ESP8266 boards to enable store Credentials in EEPROM/SPIFFS/LittleFS for easy 7 | configuration/reconfiguration and autoconnect/autoreconnect of WiFi and other services without Hardcoding. 8 | 9 | Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager_Lite 10 | Licensed under MIT license 11 | *****************************************************************************************************************************/ 12 | 13 | #include "defines.h" 14 | #include "Credentials.h" 15 | #include "dynamicParams.h" 16 | 17 | ESP_WiFiManager_Lite* ESP_WiFiManager; 18 | 19 | void heartBeatPrint() 20 | { 21 | static int num = 1; 22 | 23 | if (WiFi.status() == WL_CONNECTED) 24 | Serial.print("H"); // H means connected to WiFi 25 | else 26 | { 27 | if (ESP_WiFiManager->isConfigMode()) 28 | Serial.print("C"); // C means in Config Mode 29 | else 30 | Serial.print("F"); // F means not connected to WiFi 31 | } 32 | 33 | if (num == 80) 34 | { 35 | Serial.println(); 36 | num = 1; 37 | } 38 | else if (num++ % 10 == 0) 39 | { 40 | Serial.print(F(" ")); 41 | } 42 | } 43 | 44 | void check_status() 45 | { 46 | static unsigned long checkstatus_timeout = 0; 47 | 48 | //KH 49 | #define HEARTBEAT_INTERVAL 20000L 50 | // Print hearbeat every HEARTBEAT_INTERVAL (20) seconds. 51 | if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) 52 | { 53 | heartBeatPrint(); 54 | checkstatus_timeout = millis() + HEARTBEAT_INTERVAL; 55 | } 56 | } 57 | 58 | #if USING_CUSTOMS_STYLE 59 | const char NewCustomsStyle[] PROGMEM = ""; 61 | #endif 62 | 63 | void setup() 64 | { 65 | // Debug console 66 | Serial.begin(115200); 67 | while (!Serial); 68 | 69 | delay(200); 70 | 71 | Serial.print(F("\nStarting ESP_WiFi using ")); Serial.print(FS_Name); 72 | Serial.print(F(" on ")); Serial.println(ARDUINO_BOARD); 73 | Serial.println(ESP_WIFI_MANAGER_LITE_VERSION); 74 | 75 | #if USING_MRD 76 | Serial.println(ESP_MULTI_RESET_DETECTOR_VERSION); 77 | #else 78 | Serial.println(ESP_DOUBLE_RESET_DETECTOR_VERSION); 79 | #endif 80 | 81 | ESP_WiFiManager = new ESP_WiFiManager_Lite(); 82 | 83 | String AP_SSID = "your_customized_ssid"; 84 | String AP_PWD = "your_customized_pwd"; 85 | 86 | // Set customized AP SSID and PWD 87 | ESP_WiFiManager->setConfigPortal(AP_SSID, AP_PWD); 88 | 89 | // Optional to change default AP IP(192.168.4.1) and channel(10) 90 | //ESP_WiFiManager->setConfigPortalIP(IPAddress(192, 168, 120, 1)); 91 | ESP_WiFiManager->setConfigPortalChannel(0); 92 | 93 | #if USING_CUSTOMS_STYLE 94 | ESP_WiFiManager->setCustomsStyle(NewCustomsStyle); 95 | #endif 96 | 97 | #if USING_CUSTOMS_HEAD_ELEMENT 98 | ESP_WiFiManager->setCustomsHeadElement(PSTR("")); 99 | #endif 100 | 101 | #if USING_CORS_FEATURE 102 | ESP_WiFiManager->setCORSHeader(PSTR("Your Access-Control-Allow-Origin")); 103 | #endif 104 | 105 | // Set customized DHCP HostName 106 | ESP_WiFiManager->begin(HOST_NAME); 107 | //Or use default Hostname "ESP32-WIFI-XXXXXX" 108 | //ESP_WiFiManager->begin(); 109 | } 110 | 111 | #if USE_DYNAMIC_PARAMETERS 112 | void displayCredentials() 113 | { 114 | Serial.println(F("\nYour stored Credentials :")); 115 | 116 | for (uint16_t i = 0; i < NUM_MENU_ITEMS; i++) 117 | { 118 | Serial.print(myMenuItems[i].displayName); 119 | Serial.print(F(" = ")); 120 | Serial.println(myMenuItems[i].pdata); 121 | } 122 | } 123 | 124 | void displayCredentialsInLoop() 125 | { 126 | static bool displayedCredentials = false; 127 | 128 | if (!displayedCredentials) 129 | { 130 | for (int i = 0; i < NUM_MENU_ITEMS; i++) 131 | { 132 | if (!strlen(myMenuItems[i].pdata)) 133 | { 134 | break; 135 | } 136 | 137 | if ( i == (NUM_MENU_ITEMS - 1) ) 138 | { 139 | displayedCredentials = true; 140 | displayCredentials(); 141 | } 142 | } 143 | } 144 | } 145 | 146 | #endif 147 | 148 | void loop() 149 | { 150 | ESP_WiFiManager->run(); 151 | check_status(); 152 | 153 | #if USE_DYNAMIC_PARAMETERS 154 | displayCredentialsInLoop(); 155 | #endif 156 | } 157 | -------------------------------------------------------------------------------- /examples/ESP_WiFi/defines.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | defines.h 3 | For ESP8266 / ESP32 boards 4 | 5 | ESP_WiFiManager_Lite (https://github.com/khoih-prog/ESP_WiFiManager_Lite) is a library 6 | for the ESP32/ESP8266 boards to enable store Credentials in EEPROM/SPIFFS/LittleFS for easy 7 | configuration/reconfiguration and autoconnect/autoreconnect of WiFi and other services without Hardcoding. 8 | 9 | Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager_Lite 10 | Licensed under MIT license 11 | *****************************************************************************************************************************/ 12 | 13 | #ifndef defines_h 14 | #define defines_h 15 | 16 | #if !( ESP8266 || ESP32) 17 | #error This code is intended to run only on the ESP8266/ESP32 boards ! Please check your Tools->Board setting. 18 | #endif 19 | 20 | /* Comment this out to disable prints and save space */ 21 | #define ESP_WM_LITE_DEBUG_OUTPUT Serial 22 | 23 | #define _ESP_WM_LITE_LOGLEVEL_ 2 24 | 25 | // use builtin LED to show configuration mode 26 | #define USE_LED_BUILTIN true 27 | 28 | #define USING_MRD true 29 | 30 | #if USING_MRD 31 | #define MULTIRESETDETECTOR_DEBUG true 32 | 33 | // Number of seconds after reset during which a 34 | // subseqent reset will be considered a double reset. 35 | #define MRD_TIMEOUT 10 36 | 37 | // RTC Memory Address for the DoubleResetDetector to use 38 | #define MRD_ADDRESS 0 39 | 40 | #if (_ESP_WM_LITE_LOGLEVEL_ > 3) 41 | #warning Using MULTI_RESETDETECTOR 42 | #endif 43 | #else 44 | #define DOUBLERESETDETECTOR_DEBUG true 45 | 46 | // Number of seconds after reset during which a 47 | // subseqent reset will be considered a double reset. 48 | #define DRD_TIMEOUT 10 49 | 50 | // RTC Memory Address for the DoubleResetDetector to use 51 | #define DRD_ADDRESS 0 52 | 53 | #if (_ESP_WM_LITE_LOGLEVEL_ > 3) 54 | #warning Using DOUBLE_RESETDETECTOR 55 | #endif 56 | #endif 57 | 58 | ///////////////////////////////////////////// 59 | 60 | // LittleFS has higher priority than SPIFFS 61 | #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) ) 62 | #define USE_LITTLEFS true 63 | #define USE_SPIFFS false 64 | #elif defined(ARDUINO_ESP32C3_DEV) 65 | // For core v1.0.6-, ESP32-C3 only supporting SPIFFS and EEPROM. To use v2.0.0+ for LittleFS 66 | #define USE_LITTLEFS false 67 | #define USE_SPIFFS true 68 | #else 69 | // For ESP8266, and other boards 70 | #define USE_LITTLEFS true 71 | #define USE_SPIFFS false 72 | #endif 73 | 74 | ///////////////////////////////////////////// 75 | 76 | // Add customs headers from v1.2.0 77 | #define USING_CUSTOMS_STYLE true 78 | #define USING_CUSTOMS_HEAD_ELEMENT true 79 | #define USING_CORS_FEATURE true 80 | 81 | ///////////////////////////////////////////// 82 | 83 | // Force some params 84 | #define TIMEOUT_RECONNECT_WIFI 10000L 85 | 86 | // Permit running CONFIG_TIMEOUT_RETRYTIMES_BEFORE_RESET times before reset hardware 87 | // to permit user another chance to config. Only if Config Data is valid. 88 | // If Config Data is invalid, this has no effect as Config Portal will persist 89 | #define RESET_IF_CONFIG_TIMEOUT true 90 | 91 | // Permitted range of user-defined CONFIG_TIMEOUT_RETRYTIMES_BEFORE_RESET between 2-100 92 | #define CONFIG_TIMEOUT_RETRYTIMES_BEFORE_RESET 5 93 | 94 | // Config Timeout 120s (default 60s). Applicable only if Config Data is Valid 95 | #define CONFIG_TIMEOUT 120000L 96 | 97 | ///////////////////////////////////////////// 98 | 99 | // Permit input only one set of WiFi SSID/PWD. The other can be "NULL or "blank" 100 | // Default is false (if not defined) => must input 2 sets of SSID/PWD 101 | #define REQUIRE_ONE_SET_SSID_PW true //false 102 | 103 | // Max times to try WiFi per loop() iteration. To avoid blocking issue in loop() 104 | // Default 1 if not defined, and minimum 1. 105 | #define MAX_NUM_WIFI_RECON_TRIES_PER_LOOP 2 106 | 107 | // Default no interval between recon WiFi if lost 108 | // Max permitted interval will be 10mins 109 | // Uncomment to use. Be careful, WiFi reconnect will be delayed if using this method 110 | // Only use whenever urgent tasks in loop() can't be delayed. But if so, it's better you have to rewrite your code, e.g. using higher priority tasks. 111 | //#define WIFI_RECON_INTERVAL 30000 112 | 113 | ///////////////////////////////////////////// 114 | 115 | // Permit reset hardware if no WiFi to permit user another chance to access Config Portal. 116 | #define RESET_IF_NO_WIFI false 117 | 118 | ///////////////////////////////////////////// 119 | 120 | #define USE_DYNAMIC_PARAMETERS true 121 | 122 | ///////////////////////////////////////////// 123 | 124 | #define SCAN_WIFI_NETWORKS true 125 | 126 | // To be able to manually input SSID, not from a scanned SSID lists 127 | #define MANUAL_SSID_INPUT_ALLOWED true 128 | 129 | // From 2-15 130 | #define MAX_SSID_IN_LIST 8 131 | 132 | ///////////////////////////////////////////// 133 | 134 | // Optional, to use Board Name in Menu 135 | #define USING_BOARD_NAME true 136 | 137 | ///////////////////////////////////////////// 138 | 139 | #include 140 | 141 | #if ESP8266 142 | #define HOST_NAME "ESP8266-Controller" 143 | #else 144 | #define HOST_NAME "ESP32-Controller" 145 | #endif 146 | 147 | #ifdef LED_BUILTIN 148 | #define LED_PIN LED_BUILTIN 149 | #else 150 | #define LED_PIN 13 151 | #endif 152 | 153 | #endif //defines_h 154 | -------------------------------------------------------------------------------- /examples/ESP_WiFi/dynamicParams.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | dynamicParams.h 3 | For ESP8266 / ESP32 boards 4 | 5 | ESP_WiFiManager_Lite (https://github.com/khoih-prog/ESP_WiFiManager_Lite) is a library 6 | for the ESP32/ESP8266 boards to enable store Credentials in EEPROM/SPIFFS/LittleFS for easy 7 | configuration/reconfiguration and autoconnect/autoreconnect of WiFi and other services without Hardcoding. 8 | 9 | Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager_Lite 10 | Licensed under MIT license 11 | *****************************************************************************************************************************/ 12 | 13 | #ifndef dynamicParams_h 14 | #define dynamicParams_h 15 | 16 | #include "defines.h" 17 | 18 | // USE_DYNAMIC_PARAMETERS defined in defined.h 19 | 20 | /////////////// Start dynamic Credentials /////////////// 21 | 22 | //Defined in 23 | /************************************** 24 | #define MAX_ID_LEN 5 25 | #define MAX_DISPLAY_NAME_LEN 16 26 | 27 | typedef struct 28 | { 29 | char id [MAX_ID_LEN + 1]; 30 | char displayName [MAX_DISPLAY_NAME_LEN + 1]; 31 | char *pdata; 32 | uint8_t maxlen; 33 | } MenuItem; 34 | **************************************/ 35 | 36 | #if USE_DYNAMIC_PARAMETERS 37 | 38 | #define MAX_BLYNK_SERVER_LEN 34 39 | #define MAX_BLYNK_TOKEN_LEN 34 40 | 41 | char Blynk_Server1 [MAX_BLYNK_SERVER_LEN + 1] = "account.duckdns.org"; 42 | char Blynk_Token1 [MAX_BLYNK_TOKEN_LEN + 1] = "token1"; 43 | 44 | char Blynk_Server2 [MAX_BLYNK_SERVER_LEN + 1] = "account.ddns.net"; 45 | char Blynk_Token2 [MAX_BLYNK_TOKEN_LEN + 1] = "token2"; 46 | 47 | #define MAX_BLYNK_PORT_LEN 6 48 | char Blynk_Port [MAX_BLYNK_PORT_LEN + 1] = "8080"; 49 | 50 | #define MAX_MQTT_SERVER_LEN 34 51 | char MQTT_Server [MAX_MQTT_SERVER_LEN + 1] = "mqtt.duckdns.org"; 52 | 53 | MenuItem myMenuItems [] = 54 | { 55 | { "sv1", "Blynk Server1", Blynk_Server1, MAX_BLYNK_SERVER_LEN }, 56 | { "tk1", "Token1", Blynk_Token1, MAX_BLYNK_TOKEN_LEN }, 57 | { "sv2", "Blynk Server2", Blynk_Server2, MAX_BLYNK_SERVER_LEN }, 58 | { "tk2", "Token2", Blynk_Token2, MAX_BLYNK_TOKEN_LEN }, 59 | { "prt", "Port", Blynk_Port, MAX_BLYNK_PORT_LEN }, 60 | { "mqt", "MQTT Server", MQTT_Server, MAX_MQTT_SERVER_LEN }, 61 | }; 62 | 63 | uint16_t NUM_MENU_ITEMS = sizeof(myMenuItems) / sizeof(MenuItem); //MenuItemSize; 64 | 65 | #else 66 | 67 | MenuItem myMenuItems [] = {}; 68 | 69 | uint16_t NUM_MENU_ITEMS = 0; 70 | 71 | #endif //USE_DYNAMIC_PARAMETERS 72 | 73 | 74 | #endif //dynamicParams_h 75 | -------------------------------------------------------------------------------- /examples/ESP_WiFi_MQTT/Credentials.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | Credentials.h 3 | For ESP8266 / ESP32 boards 4 | 5 | ESP_WiFiManager_Lite (https://github.com/khoih-prog/ESP_WiFiManager_Lite) is a library 6 | for the ESP32/ESP8266 boards to enable store Credentials in EEPROM/SPIFFS/LittleFS for easy 7 | configuration/reconfiguration and autoconnect/autoreconnect of WiFi and other services without Hardcoding. 8 | 9 | Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager_Lite 10 | Licensed under MIT license 11 | *****************************************************************************************************************************/ 12 | 13 | #ifndef Credentials_h 14 | #define Credentials_h 15 | 16 | #include "defines.h" 17 | 18 | /// Start Default Config Data ////////////////// 19 | 20 | /* 21 | #define SSID_MAX_LEN 32 22 | //From v1.0.3, WPA2 passwords can be up to 63 characters long. 23 | #define PASS_MAX_LEN 64 24 | 25 | typedef struct 26 | { 27 | char wifi_ssid[SSID_MAX_LEN]; 28 | char wifi_pw [PASS_MAX_LEN]; 29 | } WiFi_Credentials; 30 | 31 | #define NUM_WIFI_CREDENTIALS 2 32 | 33 | // Configurable items besides fixed Header, just add board_name 34 | #define NUM_CONFIGURABLE_ITEMS ( ( 2 * NUM_WIFI_CREDENTIALS ) + 1 ) 35 | //////////////// 36 | 37 | typedef struct Configuration 38 | { 39 | char header [16]; 40 | WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS]; 41 | char board_name [24]; 42 | int checkSum; 43 | } ESP_WM_LITE_Configuration; 44 | */ 45 | 46 | #define TO_LOAD_DEFAULT_CONFIG_DATA false 47 | 48 | #if TO_LOAD_DEFAULT_CONFIG_DATA 49 | 50 | // This feature is primarily used in development to force a known set of values as Config Data 51 | // It will NOT force the Config Portal to activate. Use DRD or erase Config Data with ESP_WiFiManager.clearConfigData() 52 | 53 | // Used mostly for development and debugging. FORCES default values to be loaded each run. 54 | // Config Portal data input will be ignored and overridden by DEFAULT_CONFIG_DATA 55 | //bool LOAD_DEFAULT_CONFIG_DATA = true; 56 | 57 | // Used mostly once debugged. Assumes good data already saved in device. 58 | // Config Portal data input will be override DEFAULT_CONFIG_DATA 59 | bool LOAD_DEFAULT_CONFIG_DATA = false; 60 | 61 | 62 | ESP_WM_LITE_Configuration defaultConfig = 63 | { 64 | //char header[16], dummy, not used 65 | #if ESP8266 66 | "ESP8266", 67 | #else 68 | "ESP32", 69 | #endif 70 | 71 | // WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS]; 72 | // WiFi_Credentials.wifi_ssid and WiFi_Credentials.wifi_pw 73 | "SSID1", "password1", 74 | "SSID2", "password2", 75 | //char board_name [24]; 76 | 77 | #if ESP8266 78 | "ESP8266-Control", 79 | #else 80 | "ESP32-Control", 81 | #endif 82 | 83 | // terminate the list 84 | //int checkSum, dummy, not used 85 | 0 86 | /////////// End Default Config Data ///////////// 87 | }; 88 | 89 | #else 90 | 91 | bool LOAD_DEFAULT_CONFIG_DATA = false; 92 | 93 | ESP_WM_LITE_Configuration defaultConfig; 94 | 95 | #endif // TO_LOAD_DEFAULT_CONFIG_DATA 96 | 97 | /////////// End Default Config Data ///////////// 98 | 99 | 100 | #endif //Credentials_h 101 | -------------------------------------------------------------------------------- /examples/ESP_WiFi_MQTT/ESP_WiFi_MQTT.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | ESP_WiFi_MQTT.ino 3 | For ESP8266 / ESP32 boards 4 | 5 | ESP_WiFiManager_Lite (https://github.com/khoih-prog/ESP_WiFiManager_Lite) is a library 6 | for the ESP32/ESP8266 boards to enable store Credentials in EEPROM/SPIFFS/LittleFS for easy 7 | configuration/reconfiguration and autoconnect/autoreconnect of WiFi and other services without Hardcoding. 8 | 9 | Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager_Lite 10 | Licensed under MIT license 11 | *****************************************************************************************************************************/ 12 | 13 | /**************************************************************************************************************************** 14 | You have to modify file ./libraries/Adafruit_MQTT_Library/Adafruit_MQTT.cpp as follows to avoid dtostrf error 15 | 16 | //#if defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_MKR1000) || \ 17 | // defined(ARDUINO_ARCH_SAMD) 18 | #if !( ESP32 || ESP8266 || defined(CORE_TEENSY) || defined(STM32F1) || defined(STM32F2) || defined(STM32F3) || defined(STM32F4) || defined(STM32F7) ) 19 | static char *dtostrf(double val, signed char width, unsigned char prec, char *sout) 20 | { 21 | char fmt[20]; 22 | sprintf(fmt, "%%%d.%df", width, prec); 23 | sprintf(sout, fmt, val); 24 | return sout; 25 | } 26 | #endif 27 | *****************************************************************************************************************************/ 28 | 29 | #include "defines.h" 30 | #include "Credentials.h" 31 | #include "dynamicParams.h" 32 | 33 | #define LOCAL_DEBUG true //false 34 | 35 | #include "Adafruit_MQTT.h" //https://github.com/adafruit/Adafruit_MQTT_Library 36 | #include "Adafruit_MQTT_Client.h" //https://github.com/adafruit/Adafruit_MQTT_Library 37 | 38 | // Create a WiFiClient class to connect to the MQTT server 39 | WiFiClient *client = NULL; 40 | 41 | Adafruit_MQTT_Client *mqtt = NULL; 42 | Adafruit_MQTT_Publish *Temperature = NULL; 43 | Adafruit_MQTT_Subscribe *LED_Control = NULL; 44 | 45 | // You have to get from a sensor. Here is just an example 46 | uint32_t measuredTemp = 5; 47 | 48 | ESP_WiFiManager_Lite* ESP_WiFiManager; 49 | 50 | void heartBeatPrint() 51 | { 52 | static int num = 1; 53 | 54 | if (WiFi.status() == WL_CONNECTED) 55 | Serial.print("H"); // H means connected to WiFi 56 | else 57 | { 58 | if (ESP_WiFiManager->isConfigMode()) 59 | Serial.print("C"); // C means in Config Mode 60 | else 61 | Serial.print("F"); // F means not connected to WiFi 62 | } 63 | 64 | if (num == 40) 65 | { 66 | Serial.println(); 67 | num = 1; 68 | } 69 | else if (num++ % 5 == 0) 70 | { 71 | Serial.print(" "); 72 | } 73 | } 74 | 75 | void publishMQTT() 76 | { 77 | MQTT_connect(); 78 | 79 | if (Temperature->publish(measuredTemp)) 80 | { 81 | //Serial.println(F("Failed to send value to Temperature feed!")); 82 | Serial.print(F("T")); // T means publishing OK 83 | } 84 | else 85 | { 86 | //Serial.println(F("Value to Temperature feed sucessfully sent!")); 87 | Serial.print(F("F")); // F means publishing failure 88 | } 89 | } 90 | 91 | void subscribeMQTT() 92 | { 93 | Adafruit_MQTT_Subscribe *subscription; 94 | 95 | MQTT_connect(); 96 | 97 | while ((subscription = mqtt->readSubscription(5000))) 98 | { 99 | if (subscription == LED_Control) 100 | { 101 | Serial.print(F("\nGot: ")); 102 | Serial.println((char *)LED_Control->lastread); 103 | 104 | if (!strcmp((char*) LED_Control->lastread, "ON")) 105 | { 106 | digitalWrite(LED_PIN, HIGH); 107 | } 108 | else 109 | { 110 | digitalWrite(LED_PIN, LOW); 111 | } 112 | } 113 | } 114 | } 115 | 116 | void check_status() 117 | { 118 | static unsigned long checkstatus_timeout = 0; 119 | 120 | //KH 121 | #define HEARTBEAT_INTERVAL 5000L 122 | // Print WiFi hearbeat, Publish MQTT Topic every HEARTBEAT_INTERVAL (5) seconds. 123 | if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) 124 | { 125 | if (WiFi.status() == WL_CONNECTED) 126 | { 127 | // MQTT related jobs 128 | publishMQTT(); 129 | subscribeMQTT(); 130 | } 131 | 132 | heartBeatPrint(); 133 | checkstatus_timeout = millis() + HEARTBEAT_INTERVAL; 134 | } 135 | } 136 | 137 | void deleteOldInstances() 138 | { 139 | // Delete previous instances 140 | if (mqtt) 141 | { 142 | delete mqtt; 143 | mqtt = NULL; 144 | Serial.println(F("Deleting old MQTT object")); 145 | } 146 | 147 | if (Temperature) 148 | { 149 | delete Temperature; 150 | Temperature = NULL; 151 | Serial.println(F("Deleting old Temperature object")); 152 | } 153 | } 154 | 155 | #define USE_GLOBAL_TOPIC true 156 | 157 | #if USE_GLOBAL_TOPIC 158 | String completePubTopic; 159 | String completeSubTopic; 160 | #endif 161 | 162 | void createNewInstances() 163 | { 164 | if (!client) 165 | { 166 | client = new WiFiClient; 167 | 168 | if (client) 169 | { 170 | Serial.println(F("\nCreating new WiFi client object OK")); 171 | } 172 | else 173 | Serial.println(F("\nCreating new WiFi client object failed")); 174 | } 175 | 176 | // Create new instances from new data 177 | if (!mqtt) 178 | { 179 | // Setup the MQTT client class by passing in the WiFi client and MQTT server and login details. 180 | mqtt = new Adafruit_MQTT_Client(client, AIO_SERVER, atoi(AIO_SERVERPORT), AIO_USERNAME, AIO_KEY); 181 | 182 | if (mqtt) 183 | { 184 | Serial.println(F("Creating new MQTT object OK")); 185 | Serial.print(F("AIO_SERVER = ")); Serial.print(AIO_SERVER); Serial.print(F(", AIO_SERVERPORT = ")); Serial.println(AIO_SERVERPORT); 186 | Serial.print(F("AIO_USERNAME = ")); Serial.print(AIO_USERNAME); Serial.print(F(", AIO_KEY = ")); Serial.println(AIO_KEY); 187 | } 188 | else 189 | Serial.println(F("Creating new MQTT object failed")); 190 | } 191 | 192 | if (!Temperature) 193 | { 194 | #if USE_GLOBAL_TOPIC 195 | completePubTopic = String(AIO_USERNAME) + String(AIO_PUB_TOPIC); 196 | #else 197 | // Must be static or global 198 | static String completePubTopic = String(AIO_USERNAME) + String(AIO_PUB_TOPIC); 199 | #endif 200 | 201 | Temperature = new Adafruit_MQTT_Publish(mqtt, completePubTopic.c_str()); 202 | Serial.print(F("Creating new MQTT_Pub_Topic, Temperature = ")); Serial.println(completePubTopic); 203 | 204 | if (Temperature) 205 | { 206 | Serial.println(F("Creating new Temperature object OK")); 207 | Serial.print(F("Temperature MQTT_Pub_Topic = ")); Serial.println(completePubTopic); 208 | } 209 | else 210 | Serial.println(F("Creating new Temperature object failed")); 211 | } 212 | 213 | if (!LED_Control) 214 | { 215 | #if USE_GLOBAL_TOPIC 216 | completeSubTopic = String(AIO_USERNAME) + String(AIO_SUB_TOPIC); 217 | #else 218 | // Must be static or global 219 | static String completeSubTopic = String(AIO_USERNAME) + String(AIO_SUB_TOPIC); 220 | #endif 221 | 222 | LED_Control = new Adafruit_MQTT_Subscribe(mqtt, completeSubTopic.c_str()); 223 | 224 | Serial.print(F("Creating new AIO_SUB_TOPIC, LED_Control = ")); Serial.println(completeSubTopic); 225 | 226 | if (LED_Control) 227 | { 228 | Serial.println(F("Creating new LED_Control object OK")); 229 | Serial.print(F("LED_Control AIO_SUB_TOPIC = ")); Serial.println(completeSubTopic); 230 | 231 | mqtt->subscribe(LED_Control); 232 | } 233 | else 234 | Serial.println(F("Creating new LED_Control object failed")); 235 | } 236 | } 237 | 238 | void MQTT_connect() 239 | { 240 | int8_t ret; 241 | 242 | createNewInstances(); 243 | 244 | // Return if already connected 245 | if (mqtt->connected()) 246 | { 247 | return; 248 | } 249 | 250 | #if LOCAL_DEBUG 251 | Serial.println(F("\nConnecting to WiFi MQTT (3 attempts)...")); 252 | #endif 253 | 254 | uint8_t attempt = 3; 255 | 256 | while ( (ret = mqtt->connect()) ) 257 | { 258 | // connect will return 0 for connected 259 | Serial.println(mqtt->connectErrorString(ret)); 260 | 261 | #if LOCAL_DEBUG 262 | Serial.println(F("Another attemtpt to connect to MQTT in 5 seconds...")); 263 | #endif 264 | 265 | mqtt->disconnect(); 266 | delay(5000); // wait 5 seconds 267 | attempt--; 268 | 269 | if (attempt == 0) 270 | { 271 | Serial.println(F("WiFi MQTT connection failed. Continuing with program...")); 272 | return; 273 | } 274 | } 275 | 276 | #if LOCAL_DEBUG 277 | Serial.println(F("WiFi MQTT connection successful!")); 278 | #endif 279 | } 280 | 281 | #if USING_CUSTOMS_STYLE 282 | const char NewCustomsStyle[] PROGMEM = ""; 284 | #endif 285 | 286 | void setup() 287 | { 288 | // Debug console 289 | Serial.begin(115200); 290 | while (!Serial); 291 | 292 | pinMode(LED_PIN, OUTPUT); 293 | 294 | delay(200); 295 | 296 | Serial.print(F("\nStarting ESP_WiFi_MQTT using ")); Serial.print(FS_Name); 297 | Serial.print(F(" on ")); Serial.println(ARDUINO_BOARD); 298 | Serial.println(ESP_WIFI_MANAGER_LITE_VERSION); 299 | 300 | #if USING_MRD 301 | Serial.println(ESP_MULTI_RESET_DETECTOR_VERSION); 302 | #else 303 | Serial.println(ESP_DOUBLE_RESET_DETECTOR_VERSION); 304 | #endif 305 | 306 | ESP_WiFiManager = new ESP_WiFiManager_Lite(); 307 | 308 | String AP_SSID = "your_customized_ssid"; 309 | String AP_PWD = "your_customized_pwd"; 310 | 311 | // Set customized AP SSID and PWD 312 | ESP_WiFiManager->setConfigPortal(AP_SSID, AP_PWD); 313 | 314 | // Optional to change default AP IP(192.168.4.1) and channel(10) 315 | //ESP_WiFiManager->setConfigPortalIP(IPAddress(192, 168, 120, 1)); 316 | ESP_WiFiManager->setConfigPortalChannel(0); 317 | 318 | #if USING_CUSTOMS_STYLE 319 | ESP_WiFiManager->setCustomsStyle(NewCustomsStyle); 320 | #endif 321 | 322 | #if USING_CUSTOMS_HEAD_ELEMENT 323 | ESP_WiFiManager->setCustomsHeadElement(PSTR("")); 324 | #endif 325 | 326 | #if USING_CORS_FEATURE 327 | ESP_WiFiManager->setCORSHeader(PSTR("Your Access-Control-Allow-Origin")); 328 | #endif 329 | 330 | // Set customized DHCP HostName 331 | ESP_WiFiManager->begin(HOST_NAME); 332 | //Or use default Hostname "ESP-WiFi-XXXXXX" 333 | //ESP_WiFiManager->begin(); 334 | } 335 | 336 | #if USE_DYNAMIC_PARAMETERS 337 | void displayCredentials() 338 | { 339 | Serial.println(F("\nYour stored Credentials :")); 340 | 341 | for (uint16_t i = 0; i < NUM_MENU_ITEMS; i++) 342 | { 343 | Serial.print(myMenuItems[i].displayName); 344 | Serial.print(F(" = ")); 345 | Serial.println(myMenuItems[i].pdata); 346 | } 347 | } 348 | 349 | void displayCredentialsInLoop() 350 | { 351 | static bool displayedCredentials = false; 352 | 353 | if (!displayedCredentials) 354 | { 355 | for (int i = 0; i < NUM_MENU_ITEMS; i++) 356 | { 357 | if (!strlen(myMenuItems[i].pdata)) 358 | { 359 | break; 360 | } 361 | 362 | if ( i == (NUM_MENU_ITEMS - 1) ) 363 | { 364 | displayedCredentials = true; 365 | displayCredentials(); 366 | } 367 | } 368 | } 369 | } 370 | 371 | #endif 372 | 373 | void loop() 374 | { 375 | ESP_WiFiManager->run(); 376 | check_status(); 377 | 378 | #if USE_DYNAMIC_PARAMETERS 379 | displayCredentialsInLoop(); 380 | #endif 381 | } 382 | -------------------------------------------------------------------------------- /examples/ESP_WiFi_MQTT/defines.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | defines.h 3 | For ESP8266 / ESP32 boards 4 | 5 | ESP_WiFiManager_Lite (https://github.com/khoih-prog/ESP_WiFiManager_Lite) is a library 6 | for the ESP32/ESP8266 boards to enable store Credentials in EEPROM/SPIFFS/LittleFS for easy 7 | configuration/reconfiguration and autoconnect/autoreconnect of WiFi and other services without Hardcoding. 8 | 9 | Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager_Lite 10 | Licensed under MIT license 11 | *****************************************************************************************************************************/ 12 | 13 | #ifndef defines_h 14 | #define defines_h 15 | 16 | #if !( ESP8266 || ESP32) 17 | #error This code is intended to run only on the ESP8266/ESP32 boards ! Please check your Tools->Board setting. 18 | #endif 19 | 20 | /* Comment this out to disable prints and save space */ 21 | #define ESP_WM_LITE_DEBUG_OUTPUT Serial 22 | 23 | #define _ESP_WM_LITE_LOGLEVEL_ 2 24 | 25 | // use builtin LED to show configuration mode 26 | #define USE_LED_BUILTIN true 27 | 28 | #define USING_MRD true 29 | 30 | #if USING_MRD 31 | #define MULTIRESETDETECTOR_DEBUG true 32 | 33 | // Number of seconds after reset during which a 34 | // subseqent reset will be considered a double reset. 35 | #define MRD_TIMEOUT 10 36 | 37 | // RTC Memory Address for the DoubleResetDetector to use 38 | #define MRD_ADDRESS 0 39 | #warning Using MULTI_RESETDETECTOR 40 | #else 41 | #define DOUBLERESETDETECTOR_DEBUG true 42 | 43 | // Number of seconds after reset during which a 44 | // subseqent reset will be considered a double reset. 45 | #define DRD_TIMEOUT 10 46 | 47 | // RTC Memory Address for the DoubleResetDetector to use 48 | #define DRD_ADDRESS 0 49 | #warning Using DOUBLE_RESETDETECTOR 50 | #endif 51 | 52 | ///////////////////////////////////////////// 53 | 54 | // LittleFS has higher priority than SPIFFS 55 | #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) ) 56 | #define USE_LITTLEFS true 57 | #define USE_SPIFFS false 58 | #elif defined(ARDUINO_ESP32C3_DEV) 59 | // For core v1.0.6-, ESP32-C3 only supporting SPIFFS and EEPROM. To use v2.0.0+ for LittleFS 60 | #define USE_LITTLEFS false 61 | #define USE_SPIFFS true 62 | #else 63 | // For ESP8266, and other boards 64 | #define USE_LITTLEFS true 65 | #define USE_SPIFFS false 66 | #endif 67 | 68 | ///////////////////////////////////////////// 69 | 70 | // Add customs headers from v1.2.0 71 | #define USING_CUSTOMS_STYLE true 72 | #define USING_CUSTOMS_HEAD_ELEMENT true 73 | #define USING_CORS_FEATURE true 74 | 75 | ///////////////////////////////////////////// 76 | 77 | // Force some params 78 | #define TIMEOUT_RECONNECT_WIFI 10000L 79 | 80 | // Permit running CONFIG_TIMEOUT_RETRYTIMES_BEFORE_RESET times before reset hardware 81 | // to permit user another chance to config. Only if Config Data is valid. 82 | // If Config Data is invalid, this has no effect as Config Portal will persist 83 | #define RESET_IF_CONFIG_TIMEOUT true 84 | 85 | // Permitted range of user-defined CONFIG_TIMEOUT_RETRYTIMES_BEFORE_RESET between 2-100 86 | #define CONFIG_TIMEOUT_RETRYTIMES_BEFORE_RESET 5 87 | 88 | // Config Timeout 120s (default 60s). Applicable only if Config Data is Valid 89 | #define CONFIG_TIMEOUT 120000L 90 | 91 | ///////////////////////////////////////////// 92 | 93 | // Permit input only one set of WiFi SSID/PWD. The other can be "NULL or "blank" 94 | // Default is false (if not defined) => must input 2 sets of SSID/PWD 95 | #define REQUIRE_ONE_SET_SSID_PW true //false 96 | 97 | // Max times to try WiFi per loop() iteration. To avoid blocking issue in loop() 98 | // Default 1 if not defined, and minimum 1. 99 | #define MAX_NUM_WIFI_RECON_TRIES_PER_LOOP 2 100 | 101 | // Default no interval between recon WiFi if lost 102 | // Max permitted interval will be 10mins 103 | // Uncomment to use. Be careful, WiFi reconnect will be delayed if using this method 104 | // Only use whenever urgent tasks in loop() can't be delayed. But if so, it's better you have to rewrite your code, e.g. using higher priority tasks. 105 | //#define WIFI_RECON_INTERVAL 30000 106 | 107 | ///////////////////////////////////////////// 108 | 109 | // Permit reset hardware if no WiFi to permit user another chance to access Config Portal. 110 | #define RESET_IF_NO_WIFI false 111 | 112 | ///////////////////////////////////////////// 113 | 114 | #define USE_DYNAMIC_PARAMETERS true 115 | 116 | ///////////////////////////////////////////// 117 | 118 | #define SCAN_WIFI_NETWORKS true 119 | 120 | // To be able to manually input SSID, not from a scanned SSID lists 121 | #define MANUAL_SSID_INPUT_ALLOWED true 122 | 123 | // From 2-15 124 | #define MAX_SSID_IN_LIST 8 125 | 126 | ///////////////////////////////////////////// 127 | 128 | // Optional, to use Board Name in Menu 129 | #define USING_BOARD_NAME true 130 | 131 | ///////////////////////////////////////////// 132 | 133 | #include 134 | 135 | #if ESP8266 136 | #define HOST_NAME "ESP8266-Controller" 137 | #else 138 | #define HOST_NAME "ESP32-Controller" 139 | #endif 140 | 141 | #ifdef LED_BUILTIN 142 | #define LED_PIN LED_BUILTIN 143 | #else 144 | #define LED_PIN 13 145 | #endif 146 | 147 | #endif //defines_h 148 | -------------------------------------------------------------------------------- /examples/ESP_WiFi_MQTT/dynamicParams.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | dynamicParams.h 3 | For ESP8266 / ESP32 boards 4 | 5 | ESP_WiFiManager_Lite (https://github.com/khoih-prog/ESP_WiFiManager_Lite) is a library 6 | for the ESP32/ESP8266 boards to enable store Credentials in EEPROM/SPIFFS/LittleFS for easy 7 | configuration/reconfiguration and autoconnect/autoreconnect of WiFi and other services without Hardcoding. 8 | 9 | Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager_Lite 10 | Licensed under MIT license 11 | *****************************************************************************************************************************/ 12 | 13 | #ifndef dynamicParams_h 14 | #define dynamicParams_h 15 | 16 | #include "defines.h" 17 | 18 | // USE_DYNAMIC_PARAMETERS defined in defined.h 19 | 20 | /////////////// Start dynamic Credentials /////////////// 21 | 22 | //Defined in 23 | /************************************** 24 | #define MAX_ID_LEN 5 25 | #define MAX_DISPLAY_NAME_LEN 16 26 | 27 | typedef struct 28 | { 29 | char id [MAX_ID_LEN + 1]; 30 | char displayName [MAX_DISPLAY_NAME_LEN + 1]; 31 | char *pdata; 32 | uint8_t maxlen; 33 | } MenuItem; 34 | **************************************/ 35 | 36 | #if USE_DYNAMIC_PARAMETERS 37 | 38 | #define AIO_SERVER_LEN 20 39 | #define AIO_SERVERPORT_LEN 6 40 | #define AIO_USERNAME_LEN 20 41 | #define AIO_KEY_LEN 40 42 | 43 | // 44 | #define AIO_PUB_TOPIC_LEN 40 45 | #define AIO_SUB_TOPIC_LEN 40 46 | 47 | char AIO_SERVER [AIO_SERVER_LEN + 1] = "io.adafruit.com"; 48 | char AIO_SERVERPORT [AIO_SERVERPORT_LEN + 1] = "1883"; //1883, or 8883 for SSL 49 | char AIO_USERNAME [AIO_USERNAME_LEN + 1] = "private"; 50 | char AIO_KEY [AIO_KEY_LEN + 1] = "private"; 51 | 52 | char AIO_PUB_TOPIC [AIO_PUB_TOPIC_LEN + 1] = "/feeds/Temperature"; 53 | char AIO_SUB_TOPIC [AIO_SUB_TOPIC_LEN + 1] = "/feeds/LED_Control"; 54 | 55 | MenuItem myMenuItems [] = 56 | { 57 | { "svr", "AIO_SERVER", AIO_SERVER, AIO_SERVER_LEN }, 58 | { "prt", "AIO_SERVERPORT", AIO_SERVERPORT, AIO_SERVERPORT_LEN }, 59 | { "usr", "AIO_USERNAME", AIO_USERNAME, AIO_USERNAME_LEN }, 60 | { "key", "AIO_KEY", AIO_KEY, AIO_KEY_LEN }, 61 | { "pub", "AIO_PUB_TOPIC", AIO_PUB_TOPIC, AIO_PUB_TOPIC_LEN }, 62 | { "sub", "AIO_SUB_TOPIC", AIO_SUB_TOPIC, AIO_SUB_TOPIC_LEN }, 63 | }; 64 | 65 | uint16_t NUM_MENU_ITEMS = sizeof(myMenuItems) / sizeof(MenuItem); //MenuItemSize; 66 | 67 | #else 68 | 69 | MenuItem myMenuItems [] = {}; 70 | 71 | uint16_t NUM_MENU_ITEMS = 0; 72 | 73 | #endif //USE_DYNAMIC_PARAMETERS 74 | 75 | 76 | #endif //dynamicParams_h 77 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ########################################## 2 | # Syntax Coloring Map For ESP_WifiManager 3 | ########################################## 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | ESP_WiFiManager_Lite KEYWORD1 10 | ESP_WM_LITE_Configuration KEYWORD1 11 | MenuItem KEYWORD1 12 | WiFi_Credentials KEYWORD1 13 | 14 | 15 | ####################################### 16 | # Methods and Functions (KEYWORD2) 17 | ####################################### 18 | 19 | connectWiFi KEYWORD2 20 | begin KEYWORD2 21 | run KEYWORD2 22 | setHostname 23 | setConfigPortalIP KEYWORD2 24 | setConfigPortalChannel KEYWORD2 25 | setConfigPortal KEYWORD2 26 | setSTAStaticIPConfig KEYWORD2 27 | getWiFiSSID KEYWORD2 28 | getWiFiPW KEYWORD2 29 | getWiFiStatus KEYWORD2 30 | getFullConfigData KEYWORD2 31 | localIP KEYWORD2 32 | clearConfigData KEYWORD2 33 | isConfigDataValid KEYWORD2 34 | isConfigMode KEYWORD2 35 | resetFunc KEYWORD2 36 | resetAndEnterConfigPortal KEYWORD2 37 | resetAndEnterConfigPortalPersistent KEYWORD2 38 | IPAddressToString KEYWORD2 39 | setCustomsStyle KEYWORD2 40 | getCustomsStyle KEYWORD2 41 | setCustomsHeadElement KEYWORD2 42 | getCustomsHeadElement KEYWORD2 43 | setCORSHeader KEYWORD2 44 | getCORSHeader KEYWORD2 45 | extLoadDynamicData KEYWORD2 46 | extSaveDynamicData KEYWORD2 47 | 48 | ####################################### 49 | 50 | getChipID KEYWORD2 51 | getChipOUI KEYWORD2 52 | 53 | ESP_getChipId KEYWORD2 54 | ESP_getChipOUI KEYWORD2 55 | 56 | ####################################### 57 | # Constants (LITERAL1) 58 | ####################################### 59 | 60 | # LITERAL1 61 | 62 | ESP_WIFI_MANAGER_LITE_VERSION LITERAL1 63 | 64 | ESP_WIFI_MANAGER_LITE_VERSION_MAJOR LITERAL1 65 | ESP_WIFI_MANAGER_LITE_VERSION_MINOR LITERAL1 66 | ESP_WIFI_MANAGER_LITE_VERSION_PATCH LITERAL1 67 | ESP_WIFI_MANAGER_LITE_VERSION_INT LITERAL1 68 | 69 | CONFIG_DATA_SIZE LITERAL1 70 | NUM_MENU_ITEMS LITERAL1 71 | ESP_WM_LITE_HTML_HEAD LITERAL1 72 | ESP_WM_LITE_HTML_HEAD_START LITERAL1 73 | ESP_WM_LITE_HTML_HEAD_STYLE LITERAL1 74 | ESP_WM_LITE_HTML_HEAD_END LITERAL1 75 | ESP_WM_LITE_FLDSET_START LITERAL1 76 | ESP_WM_LITE_FLDSET_END LITERAL1 77 | ESP_WM_LITE_HTML_PARAM LITERAL1 78 | ESP_WM_LITE_HTML_BUTTON LITERAL1 79 | ESP_WM_LITE_HTML_SCRIPT LITERAL1 80 | ESP_WM_LITE_HTML_SCRIPT_ITEM LITERAL1 81 | ESP_WM_LITE_HTML_SCRIPT_END LITERAL1 82 | ESP_WM_LITE_HTML_END LITERAL1 83 | 84 | WM_HTTP_HEAD_CL LITERAL1 85 | WM_HTTP_HEAD_TEXT_HTML LITERAL1 86 | WM_HTTP_HEAD_TEXT_PLAIN LITERAL1 87 | WM_HTTP_CACHE_CONTROL LITERAL1 88 | WM_HTTP_NO_STORE LITERAL1 89 | WM_HTTP_PRAGMA LITERAL1 90 | WM_HTTP_NO_CACHE LITERAL1 91 | WM_HTTP_EXPIRES LITERAL1 92 | WM_HTTP_CORS LITERAL1 93 | WM_HTTP_CORS_ALLOW_ALL LITERAL1 94 | 95 | USE_LED_BUILTIN LITERAL1 96 | 97 | LED_ON LITERAL1 98 | LED_OFF LITERAL1 99 | 100 | USING_BOARD_NAME LITERAL1 101 | 102 | FORCED_CONFIG_PORTAL_FLAG_DATA LITERAL1 103 | FORCED_PERS_CONFIG_PORTAL_FLAG_DATA LITERAL1 104 | FORCED_CONFIG_PORTAL_FLAG_DATA_SIZE LITERAL1 105 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ESP_WiFiManager_Lite", 3 | "version": "1.10.5", 4 | "keywords": "wifi, wi-fi, MultiWiFi, multi-wifi, WiFiManager, esp8266, esp32, esp32-s2, esp32-s3, esp32-c3, Communication, iot, credentials, persistent, config-portal, DoubleReset, MultiReset, DoubleResetDetector, littlefs, spiffs, eeprom, light-weight", 5 | "description": "Library to configure MultiWiFi/Credentials at runtime for ESP32 (including ESP32-S2, ESP32-S3 and ESP32-C3) and ESP8266 boards. You can also specify DHCP HostName, static AP and STA IP. Use much less memory compared to full-fledge WiFiManager. Config Portal will be auto-adjusted to match the number of dynamic custom parameters. Optional default Credentials to be autoloaded into Config Portal to use or change instead of manually input. Credentials are saved in LittleFS, SPIFFS or EEPROM. New powerful-yet-simple-to-use feature to enable adding dynamic custom parameters from sketch and input using the same Config Portal. Double or MultiDetectDetector as well as Virtual Switches feature permits entering Config Portal as requested. Configurable Customs HTML Headers, including Customs Style, Customs Head Elements, CORS Header. Now using correct ESP32 chipIP", 6 | "authors": 7 | { 8 | "name": "Khoi Hoang", 9 | "url": "https://github.com/khoih-prog", 10 | "maintainer": true 11 | }, 12 | "repository": 13 | { 14 | "type": "git", 15 | "url": "https://github.com/khoih-prog/ESP_WiFiManager_Lite" 16 | }, 17 | "homepage": "https://github.com/khoih-prog/ESP_WiFiManager_Lite", 18 | "export": { 19 | "exclude": [ 20 | "linux", 21 | "extras", 22 | "tests" 23 | ] 24 | }, 25 | "dependencies": 26 | [ 27 | { 28 | "owner": "khoih-prog", 29 | "name": "ESP_DoubleResetDetector", 30 | "version": "^1.3.2", 31 | "platforms": ["espressif8266", "espressif32"] 32 | }, 33 | { 34 | "owner": "khoih-prog", 35 | "name": "ESP_MultiResetDetector", 36 | "version": "^1.3.2", 37 | "platforms": ["espressif8266", "espressif32"] 38 | } 39 | ], 40 | "license": "MIT", 41 | "frameworks": "*", 42 | "platforms": ["espressif8266", "espressif32"], 43 | "examples": "examples/*/*/*.ino", 44 | "headers": "ESP_WiFiManager_Lite.h" 45 | } 46 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=ESP_WiFiManager_Lite 2 | version=1.10.5 3 | author=Khoi Hoang 4 | maintainer=Khoi Hoang 5 | license=MIT 6 | sentence=Light-Weight MultiWiFi/Credentials Manager for ESP32 (including ESP32-S2, ESP32-S3 and ESP32-C3) and ESP8266 boards. Powerful-yet-simple-to-use feature to enable adding dynamic custom parameters. 7 | paragraph=Library to configure MultiWiFi/Credentials at runtime for ESP32 (including ESP32-S2, ESP32-S3 and ESP32-C3) and ESP8266 boards. You can also specify DHCP HostName, static AP and STA IP. Use much less memory compared to full-fledge WiFiManager. Config Portal will be auto-adjusted to match the number of dynamic custom parameters. Optional default Credentials to be autoloaded into Config Portal to use or change instead of manually input. Credentials are saved in LittleFS, SPIFFS or EEPROM. New powerful-yet-simple-to-use feature to enable adding dynamic custom parameters from sketch and input using the same Config Portal. Double or MultiDetectDetector as well as Virtual Switches feature permits entering Config Portal as requested. Configurable Customs HTML Headers, including Customs Style, Customs Head Elements, CORS Header. Now using correct ESP32 chipIP 8 | category=Communication 9 | url=https://github.com/khoih-prog/ESP_WiFiManager_Lite 10 | architectures=esp8266,esp32 11 | depends=ESP_DoubleResetDetector,ESP_MultiResetDetector 12 | includes=ESP_WiFiManager_Lite.h 13 | -------------------------------------------------------------------------------- /pics/Input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager_Lite/085afdbd7ccfb7e46b1ed9f1cf5c50be29cc3223/pics/Input.png -------------------------------------------------------------------------------- /pics/Input_With_Scan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager_Lite/085afdbd7ccfb7e46b1ed9f1cf5c50be29cc3223/pics/Input_With_Scan.png -------------------------------------------------------------------------------- /pics/MQTT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager_Lite/085afdbd7ccfb7e46b1ed9f1cf5c50be29cc3223/pics/MQTT.png -------------------------------------------------------------------------------- /pics/Main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager_Lite/085afdbd7ccfb7e46b1ed9f1cf5c50be29cc3223/pics/Main.png -------------------------------------------------------------------------------- /pics/Save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager_Lite/085afdbd7ccfb7e46b1ed9f1cf5c50be29cc3223/pics/Save.png -------------------------------------------------------------------------------- /platformio/platformio.ini: -------------------------------------------------------------------------------- 1 | ;PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | ; ============================================================ 13 | ; chose environment: 14 | ; ESP8266 15 | ; ESP32 16 | ; esp32s2 17 | ; esp32s3 18 | ; esp32c3 19 | 20 | ; ============================================================ 21 | default_envs = ESP8266 22 | ;default_envs = ESP32 23 | 24 | [env] 25 | ; ============================================================ 26 | ; Serial configuration 27 | ; choose upload speed, serial-monitor speed 28 | ; ============================================================ 29 | upload_speed = 921600 30 | ;upload_port = COM11 31 | ;monitor_speed = 9600 32 | ;monitor_port = COM11 33 | 34 | ; ============================================================ 35 | ; Checks for the compatibility with frameworks and dev/platforms 36 | lib_compat_mode = strict 37 | ;lib_ldf_mode = chain+ 38 | ;lib_ldf_mode = deep+ 39 | 40 | ; ============================================================ 41 | lib_deps = 42 | ; PlatformIO 4.x 43 | ; ESP_DoubleResetDetector@>=1.3.2 44 | ; ESP_MultiResetDetector@>=1.3.2 45 | ; LittleFS_esp32@>=1.0.6 46 | ; PlatformIO 5.x 47 | ; khoih-prog/ESP_WiFiManager_Lite@>=1.10.4 48 | khoih-prog/ESP_DoubleResetDetector@>=1.3.2 49 | khoih-prog/ESP_MultiResetDetector@>=1.3.2 50 | ; lorol/LittleFS_esp32@>=1.0.6 51 | 52 | ; ============================================================ 53 | build_flags = 54 | ; set your debug output (default=Serial) 55 | -D DEBUG_ESP_PORT=Serial 56 | ; comment the following line to enable WiFi debugging 57 | -D NDEBUG 58 | 59 | ; comment the following line to use EEPROM 60 | -D USE_LITTLEFS=true 61 | 62 | ; ============================================================ 63 | ; ============================================================ 64 | [env:ESP8266] 65 | platform = espressif8266 66 | framework = arduino 67 | ; ============================================================ 68 | ; Board configuration 69 | ; choose your board by uncommenting one of the following lines 70 | ; ============================================================ 71 | ;board = gen4iod 72 | ;board = huzzah 73 | ;board = oak 74 | ;board = esp_wroom_02 75 | ;board = espduino 76 | ;board = espectro 77 | ;board = espino 78 | ;board = espresso_lite_v1 79 | ;board = espresso_lite_v2 80 | ;board = esp12e 81 | ;board = esp01_1m 82 | ;board = esp01 83 | ;board = esp07 84 | ;board = esp8285 85 | ;board = heltec_wifi_kit_8 86 | ;board = inventone 87 | ;board = nodemcu 88 | board = nodemcuv2 89 | ;board = modwifi 90 | ;board = phoenix_v1 91 | ;board = phoenix_v2 92 | ;board = sparkfunBlynk 93 | ;board = thing 94 | ;board = thingdev 95 | ;board = esp210 96 | ;board = espinotee 97 | ;board = d1 98 | ;board = d1_mini 99 | ;board = d1_mini_lite 100 | ;board = d1_mini_pro 101 | ;board = wifi_slot 102 | ;board = wifiduino 103 | ;board = wifinfo 104 | ;board = wio_link 105 | ;board = wio_node 106 | ;board = xinabox_cw01 107 | ;board = esp32doit-devkit-v1 108 | 109 | ; ============================================================ 110 | ; ============================================================ 111 | [env:ESP32] 112 | platform = espressif32 113 | framework = arduino 114 | 115 | ; ============================================================ 116 | ; Board configuration 117 | ; choose your board by uncommenting one of the following lines 118 | ; ============================================================ 119 | ;board = esp32cam 120 | ;board = alksesp32 121 | ;board = featheresp32 122 | ;board = espea32 123 | ;board = bpi-bit 124 | ;board = d-duino-32 125 | board = esp32doit-devkit-v1 126 | ;board = pocket_32 127 | ;board = fm-devkit 128 | ;board = pico32 129 | ;board = esp32-evb 130 | ;board = esp32-gateway 131 | ;board = esp32-pro 132 | ;board = esp32-poe 133 | ;board = oroca_edubot 134 | ;board = onehorse32dev 135 | ;board = lopy 136 | ;board = lopy4 137 | ;board = wesp32 138 | ;board = esp32thing 139 | ;board = sparkfun_lora_gateway_1-channel 140 | ;board = ttgo-lora32-v1 141 | ;board = ttgo-t-beam 142 | ;board = turta_iot_node 143 | ;board = lolin_d32 144 | ;board = lolin_d32_pro 145 | ;board = lolin32 146 | ;board = wemosbat 147 | ;board = widora-air 148 | ;board = xinabox_cw02 149 | ;board = iotbusio 150 | ;board = iotbusproteus 151 | ;board = nina_w10 152 | 153 | ; ============================================================ 154 | ; ============================================================ 155 | [env:esp32s2] 156 | platform = espressif32 157 | framework = arduino 158 | 159 | ; toolchain download links see 160 | ; refer "name": "xtensa-esp32s2-elf-gcc","version": "gcc8_4_0-esp-2021r1" section of 161 | ; https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json 162 | ; e.g. Windows: https://github.com/espressif/crosstool-NG/releases/download/esp-2021r1/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r1-win32.zip 163 | platform_packages = 164 | toolchain-xtensa32s2@file://C:\Users\Max\Downloads\xtensa-esp32s2-elf 165 | framework-arduinoespressif32@https://github.com/espressif/arduino-esp32.git#a4118ea88987c28aac3a49bcb9cc5d6c0acc6f3f 166 | platformio/tool-esptoolpy @ ~1.30100 167 | board = esp32dev 168 | board_build.mcu = esp32s2 169 | board_build.partitions = huge_app.csv 170 | board_build.variant = esp32s2 171 | board_build.f_cpu = 240000000L 172 | board_build.f_flash = 80000000L 173 | board_build.flash_mode = qio 174 | board_build.arduino.ldscript = esp32s2_out.ld 175 | build_unflags = 176 | -DARDUINO_ESP32_DEV 177 | -DARDUINO_VARIANT="esp32" 178 | build_flags = 179 | -DARDUINO_ESP32S2_DEV 180 | -DARDUINO_VARIANT="esp32s2" 181 | 182 | ; ============================================================ 183 | ; ============================================================ 184 | [env:esp32s3] 185 | platform = espressif32 186 | framework = arduino 187 | 188 | board = esp32-s3-devkitc-1 189 | board_build.mcu = esp32s3 190 | board_build.partitions = huge_app.csv 191 | board_build.variant = esp32s3 192 | board_build.f_cpu = 240000000L 193 | board_build.f_flash = 80000000L 194 | board_build.flash_mode = qio 195 | board_build.arduino.ldscript = esp32s3_out.ld 196 | build_unflags = 197 | -DARDUINO_ESP32_DEV 198 | -DARDUINO_VARIANT="esp32" 199 | build_flags = 200 | -DARDUINO_ESP32S3_DEV 201 | -DARDUINO_VARIANT="esp32s3" 202 | 203 | ; ============================================================ 204 | ; ============================================================ 205 | [env:esp32sc3] 206 | platform = espressif32 207 | framework = arduino 208 | 209 | board = esp32-c3-devkitm-1 210 | board_build.mcu = esp32c3 211 | board_build.partitions = huge_app.csv 212 | board_build.variant = esp32c3 213 | board_build.f_cpu = 160000000L 214 | board_build.f_flash = 80000000L 215 | board_build.flash_mode = qio 216 | board_build.arduino.ldscript = esp32c3_out.ld 217 | build_unflags = 218 | -DARDUINO_ESP32_DEV 219 | -DARDUINO_VARIANT="esp32" 220 | build_flags = 221 | -DARDUINO_ESP32S3_DEV 222 | -DARDUINO_VARIANT="esp32c3" 223 | 224 | ; ============================================================ 225 | ; ============================================================ 226 | -------------------------------------------------------------------------------- /src/ESP_WiFiManager_Lite_Debug.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | ESP_WiFiManager_Lite_Debug.h 3 | For ESP8266 / ESP32 boards 4 | 5 | ESP_WiFiManager_Lite (https://github.com/khoih-prog/ESP_WiFiManager_Lite) is a library 6 | for the ESP32/ESP8266 boards to enable store Credentials in EEPROM/SPIFFS/LittleFS for easy 7 | configuration/reconfiguration and autoconnect/autoreconnect of WiFi and other services without Hardcoding. 8 | 9 | Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager_Lite 10 | Licensed under MIT license 11 | 12 | Version: 1.10.5 13 | 14 | Version Modified By Date Comments 15 | ------- ----------- ---------- ----------- 16 | 1.0.0 K Hoang 04/02/2021 Initial coding for ESP32/ESP8266 17 | ... 18 | 1.8.1 K Hoang 11/02/2022 Add LittleFS support to ESP32-C3. Use core LittleFS instead of Lorol's LITTLEFS for v2.0.0+ 19 | 1.8.2 K Hoang 21/02/2022 Optional Board_Name in Menu. Optimize code by using passing by reference 20 | 1.9.0 K Hoang 09/09/2022 Fix ESP32 chipID and add ESP_getChipOUI() 21 | 1.10.0 K Hoang 10/01/2023 Add Captive-Portal feature 22 | 1.10.1 K Hoang 12/01/2023 Added public methods to load and save dynamic data 23 | 1.10.2 K Hoang 15/01/2023 Add Config Portal scaling support to mobile devices 24 | 1.10.3 K Hoang 19/01/2023 Fix compiler error if EEPROM is used 25 | 1.10.4 K Hoang 27/01/2023 Using PROGMEM for HTML strings 26 | 1.10.5 K Hoang 28/01/2023 Using PROGMEM for strings in examples 27 | *****************************************************************************************************************************/ 28 | 29 | #ifndef ESP_WiFiManager_Lite_Debug_h 30 | #define ESP_WiFiManager_Lite_Debug_h 31 | 32 | #ifdef ESP_WM_LITE_DEBUG_OUTPUT 33 | #define DBG_PORT_ESP_WML ESP_WM_LITE_DEBUG_OUTPUT 34 | #else 35 | #define DBG_PORT_ESP_WML Serial 36 | #endif 37 | 38 | // Change _ESP_WM_LITE_LOGLEVEL_ to set tracing and logging verbosity 39 | // 0: DISABLED: no logging 40 | // 1: ERROR: errors 41 | // 2: WARN: errors and warnings 42 | // 3: INFO: errors, warnings and informational (default) 43 | // 4: DEBUG: errors, warnings, informational and debug 44 | 45 | #ifndef _ESP_WM_LITE_LOGLEVEL_ 46 | #define _ESP_WM_LITE_LOGLEVEL_ 0 47 | #endif 48 | 49 | const char ESP_WML_MARK[] = "[WML] "; 50 | 51 | #define ESP_WML_PRINT_MARK DBG_PORT_ESP_WML.print(ESP_WML_MARK) 52 | 53 | #define ESP_WML_PRINT DBG_PORT_ESP_WML.print 54 | #define ESP_WML_PRINTLN DBG_PORT_ESP_WML.println 55 | 56 | 57 | /////////////////////////////////////////// 58 | 59 | #define ESP_WML_LOGERROR0(x) if(_ESP_WM_LITE_LOGLEVEL_>0) { ESP_WML_PRINT(x); } 60 | #define ESP_WML_LOGERROR(x) if(_ESP_WM_LITE_LOGLEVEL_>0) { ESP_WML_PRINT_MARK; ESP_WML_PRINTLN(x); } 61 | #define ESP_WML_LOGERROR1(x,y) if(_ESP_WM_LITE_LOGLEVEL_>0) { ESP_WML_PRINT_MARK; ESP_WML_PRINT(x); ESP_WML_PRINTLN(y); } 62 | #define ESP_WML_LOGERROR2(x,y,z) if(_ESP_WM_LITE_LOGLEVEL_>0) { ESP_WML_PRINT_MARK; ESP_WML_PRINT(x); ESP_WML_PRINT(y); ESP_WML_PRINTLN(z); } 63 | #define ESP_WML_LOGERROR3(x,y,z,w) if(_ESP_WM_LITE_LOGLEVEL_>0) { ESP_WML_PRINT_MARK; ESP_WML_PRINT(x); ESP_WML_PRINT(y); ESP_WML_PRINT(z); ESP_WML_PRINTLN(w); } 64 | #define ESP_WML_LOGERROR5(x,y,z,w,xx,yy) if(_ESP_WM_LITE_LOGLEVEL_>0) { ESP_WML_PRINT_MARK; ESP_WML_PRINT(x); ESP_WML_PRINT(y); ESP_WML_PRINT(z); ESP_WML_PRINT(w); ESP_WML_PRINT(xx); ESP_WML_PRINTLN(yy); } 65 | 66 | /////////////////////////////////////////// 67 | 68 | #define ESP_WML_LOGWARN0(x) if(_ESP_WM_LITE_LOGLEVEL_>1) { ESP_WML_PRINT(x); } 69 | #define ESP_WML_LOGWARN(x) if(_ESP_WM_LITE_LOGLEVEL_>1) { ESP_WML_PRINT_MARK; ESP_WML_PRINTLN(x); } 70 | #define ESP_WML_LOGWARN1(x,y) if(_ESP_WM_LITE_LOGLEVEL_>1) { ESP_WML_PRINT_MARK; ESP_WML_PRINT(x); ESP_WML_PRINTLN(y); } 71 | #define ESP_WML_LOGWARN2(x,y,z) if(_ESP_WM_LITE_LOGLEVEL_>1) { ESP_WML_PRINT_MARK; ESP_WML_PRINT(x); ESP_WML_PRINT(y); ESP_WML_PRINTLN(z); } 72 | #define ESP_WML_LOGWARN3(x,y,z,w) if(_ESP_WM_LITE_LOGLEVEL_>1) { ESP_WML_PRINT_MARK; ESP_WML_PRINT(x); ESP_WML_PRINT(y); ESP_WML_PRINT(z); ESP_WML_PRINTLN(w); } 73 | #define ESP_WML_LOGWARN5(x,y,z,w,xx,yy) if(_ESP_WM_LITE_LOGLEVEL_>1) { ESP_WML_PRINT_MARK; ESP_WML_PRINT(x); ESP_WML_PRINT(y); ESP_WML_PRINT(z); ESP_WML_PRINT(w); ESP_WML_PRINT(xx); ESP_WML_PRINTLN(yy); } 74 | 75 | /////////////////////////////////////////// 76 | 77 | #define ESP_WML_LOGINFO0(x) if(_ESP_WM_LITE_LOGLEVEL_>2) { ESP_WML_PRINT(x); } 78 | #define ESP_WML_LOGINFO(x) if(_ESP_WM_LITE_LOGLEVEL_>2) { ESP_WML_PRINT_MARK; ESP_WML_PRINTLN(x); } 79 | #define ESP_WML_LOGINFO1(x,y) if(_ESP_WM_LITE_LOGLEVEL_>2) { ESP_WML_PRINT_MARK; ESP_WML_PRINT(x); ESP_WML_PRINTLN(y); } 80 | #define ESP_WML_LOGINFO2(x,y,z) if(_ESP_WM_LITE_LOGLEVEL_>3) { ESP_WML_PRINT_MARK; ESP_WML_PRINT(x); ESP_WML_PRINT(y); ESP_WML_PRINTLN(z); } 81 | #define ESP_WML_LOGINFO3(x,y,z,w) if(_ESP_WM_LITE_LOGLEVEL_>3) { ESP_WML_PRINT_MARK; ESP_WML_PRINT(x); ESP_WML_PRINT(y); ESP_WML_PRINT(z); ESP_WML_PRINTLN(w); } 82 | #define ESP_WML_LOGINFO5(x,y,z,w,xx,yy) if(_ESP_WM_LITE_LOGLEVEL_>2) { ESP_WML_PRINT_MARK; ESP_WML_PRINT(x); ESP_WML_PRINT(y); ESP_WML_PRINT(z); ESP_WML_PRINT(w); ESP_WML_PRINT(xx); ESP_WML_PRINTLN(yy); } 83 | 84 | /////////////////////////////////////////// 85 | 86 | #define ESP_WML_LOGDEBUG0(x) if(_ESP_WM_LITE_LOGLEVEL_>3) { ESP_WML_PRINT(x); } 87 | #define ESP_WML_LOGDEBUG(x) if(_ESP_WM_LITE_LOGLEVEL_>3) { ESP_WML_PRINT_MARK; ESP_WML_PRINTLN(x); } 88 | #define ESP_WML_LOGDEBUG1(x,y) if(_ESP_WM_LITE_LOGLEVEL_>3) { ESP_WML_PRINT_MARK; ESP_WML_PRINT(x); ESP_WML_PRINTLN(y); } 89 | #define ESP_WML_LOGDEBUG2(x,y,z) if(_ESP_WM_LITE_LOGLEVEL_>3) { ESP_WML_PRINT_MARK; ESP_WML_PRINT(x); ESP_WML_PRINT(y); ESP_WML_PRINTLN(z); } 90 | #define ESP_WML_LOGDEBUG3(x,y,z,w) if(_ESP_WM_LITE_LOGLEVEL_>3) { ESP_WML_PRINT_MARK; ESP_WML_PRINT(x); ESP_WML_PRINT(y); ESP_WML_PRINT(z); ESP_WML_PRINTLN(w); } 91 | #define ESP_WML_LOGDEBUG5(x,y,z,w,xx,yy) if(_ESP_WM_LITE_LOGLEVEL_>3) { ESP_WML_PRINT_MARK; ESP_WML_PRINT(x); ESP_WML_PRINT(y); ESP_WML_PRINT(z); ESP_WML_PRINT(w); ESP_WML_PRINT(xx); ESP_WML_PRINTLN(yy); } 92 | 93 | /////////////////////////////////////////// 94 | 95 | #endif //ESP_WiFiManager_Lite_Debug_h 96 | -------------------------------------------------------------------------------- /utils/astyle_library.conf: -------------------------------------------------------------------------------- 1 | # Code formatting rules for Arduino libraries, modified from for KH libraries: 2 | # 3 | # https://github.com/arduino/Arduino/blob/master/build/shared/examples_formatter.conf 4 | # 5 | 6 | # astyle --style=allman -s2 -t2 -C -S -xW -Y -M120 -f -p -xg -H -xb -c --xC120 -xL *.h *.cpp *.ino 7 | 8 | --mode=c 9 | --lineend=linux 10 | --style=allman 11 | 12 | # -r or -R 13 | #--recursive 14 | 15 | # -c => Converts tabs into spaces 16 | convert-tabs 17 | 18 | # -s2 => 2 spaces indentation 19 | --indent=spaces=2 20 | 21 | # -t2 => tab =2 spaces 22 | #--indent=tab=2 23 | 24 | # -C 25 | --indent-classes 26 | 27 | # -S 28 | --indent-switches 29 | 30 | # -xW 31 | --indent-preproc-block 32 | 33 | # -Y => indent classes, switches (and cases), comments starting at column 1 34 | --indent-col1-comments 35 | 36 | # -M120 => maximum of 120 spaces to indent a continuation line 37 | --max-continuation-indent=120 38 | 39 | # -xC120 => max‑code‑length will break a line if the code exceeds # characters 40 | --max-code-length=120 41 | 42 | # -f => 43 | --break-blocks 44 | 45 | # -p => put a space around operators 46 | --pad-oper 47 | 48 | # -xg => Insert space padding after commas 49 | --pad-comma 50 | 51 | # -H => put a space after if/for/while 52 | pad-header 53 | 54 | # -xb => Break one line headers (e.g. if/for/while) 55 | --break-one-line-headers 56 | 57 | # -c => Converts tabs into spaces 58 | #--convert-tabs 59 | 60 | # if you like one-liners, keep them 61 | #keep-one-line-statements 62 | 63 | # -xV 64 | --attach-closing-while 65 | 66 | #unpad-paren 67 | 68 | # -xp 69 | remove-comment-prefix 70 | 71 | -------------------------------------------------------------------------------- /utils/restyle.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for dir in . ; do 4 | find $dir -type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" -o -name "*.ino" \) -exec astyle --suffix=none --options=./utils/astyle_library.conf \{\} \; 5 | done 6 | 7 | --------------------------------------------------------------------------------