├── .codespellrc ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── dependabot.yml ├── stale.yml └── workflows │ ├── auto-github-actions.yml │ ├── check-arduino.yml │ ├── report-size-deltas.yml │ └── spell-check.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── changelog.md ├── examples ├── ConfigOnMRD_ESP32_minimal │ └── ConfigOnMRD_ESP32_minimal.ino ├── ConfigOnMRD_ESP8266_minimal │ └── ConfigOnMRD_ESP8266_minimal.ino ├── ConfigOnMultiReset │ └── ConfigOnMultiReset.ino ├── checkWaitingMRD │ └── checkWaitingMRD.ino └── minimal │ └── minimal.ino ├── keywords.txt ├── library.json ├── library.properties ├── platformio └── platformio.ini ├── src └── ESP_MultiResetDetector.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 | ### Information 35 | 36 | Please ensure to specify the following: 37 | 38 | * Arduino IDE version (e.g. 1.8.19) or Platform.io version 39 | * `ESP8266` or `ESP32` Core Version (e.g. ESP8266 core v3.0.2 or ESP32 v2.0.5) 40 | * Contextual information (e.g. what you were trying to achieve) 41 | * Simplest possible steps to reproduce 42 | * Anything that might be relevant in your opinion, such as: 43 | * Operating system (Windows, Ubuntu, etc.) and the output of `uname -a` 44 | * Network configuration 45 | 46 | 47 | ### Example 48 | 49 | ``` 50 | Arduino IDE version: 1.8.19 51 | ESP8266 Core Version 3.0.2 52 | OS: Ubuntu 20.04 LTS 53 | Linux xy-Inspiron-3593 5.15.0-53-generic #59~20.04.1-Ubuntu SMP Thu Oct 20 15:10:22 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux 54 | 55 | Context: 56 | I encountered a crash while using this library 57 | 58 | Steps to reproduce: 59 | 1. ... 60 | 2. ... 61 | 3. ... 62 | 4. ... 63 | ``` 64 | 65 | --- 66 | 67 | ### Sending Feature Requests 68 | 69 | Feel free to post feature requests. It's helpful if you can explain exactly why the feature would be useful. 70 | 71 | There are usually some outstanding feature requests in the [existing issues list](https://github.com/khoih-prog/ESP_MultiResetDetector/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement), feel free to add comments to them. 72 | 73 | --- 74 | 75 | ### Sending Pull Requests 76 | 77 | Pull Requests with changes and fixes are also welcome! 78 | 79 | Please use the `astyle` to reformat the updated library code as follows (demo for Ubuntu Linux) 80 | 81 | 1. Change directory to the library GitHub 82 | 83 | ``` 84 | xy@xy-Inspiron-3593:~$ cd Arduino/xy/ESP_MultiResetDetector_GitHub/ 85 | xy@xy-Inspiron-3593:~/Arduino/xy/ESP_MultiResetDetector_GitHub$ 86 | ``` 87 | 88 | 2. Issue astyle command 89 | 90 | ``` 91 | xy@xy-Inspiron-3593:~/Arduino/xy/ESP_MultiResetDetector_GitHub$ bash utils/restyle.sh 92 | ``` 93 | 94 | -------------------------------------------------------------------------------- /.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 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.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/check-arduino.yml: -------------------------------------------------------------------------------- 1 | name: Check Arduino 2 | 3 | # See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows 4 | on: 5 | push: 6 | pull_request: 7 | schedule: 8 | # Run every Tuesday at 8 AM UTC to catch breakage caused by new rules added to Arduino Lint. 9 | - cron: "0 8 * * TUE" 10 | workflow_dispatch: 11 | repository_dispatch: 12 | 13 | jobs: 14 | lint: 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - name: Checkout repository 19 | uses: actions/checkout@v3 20 | 21 | - name: Arduino Lint 22 | uses: arduino/arduino-lint-action@v1 23 | with: 24 | compliance: specification 25 | library-manager: update 26 | # Always use this setting for official repositories. Remove for 3rd party projects. 27 | official: true 28 | project-type: library 29 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing to ESP_MultiResetDetector 2 | 3 | ### Reporting Bugs 4 | 5 | Please report bugs in ESP_MultiResetDetector 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_MultiResetDetector/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_MultiResetDetector/issues/new). 12 | 13 | ### How to submit a bug report 14 | 15 | Please ensure to specify the following: 16 | 17 | * Arduino IDE version (e.g. 1.8.19) or Platform.io version 18 | * `ESP8266` or `ESP32` Core Version (e.g. ESP8266 core v3.0.2 or ESP32 v2.0.5) 19 | * Contextual information (e.g. what you were trying to achieve) 20 | * Simplest possible steps to reproduce 21 | * Anything that might be relevant in your opinion, such as: 22 | * Operating system (Windows, Ubuntu, etc.) and the output of `uname -a` 23 | * Network configuration 24 | 25 | 26 | ### Example 27 | 28 | ``` 29 | Arduino IDE version: 1.8.19 30 | ESP8266 Core Version 3.0.2 31 | OS: Ubuntu 20.04 LTS 32 | Linux xy-Inspiron-3593 5.15.0-53-generic #59~20.04.1-Ubuntu SMP Thu Oct 20 15:10:22 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux 33 | 34 | Context: 35 | I encountered a crash while using this library 36 | 37 | Steps to reproduce: 38 | 1. ... 39 | 2. ... 40 | 3. ... 41 | 4. ... 42 | ``` 43 | 44 | --- 45 | 46 | ### Sending Feature Requests 47 | 48 | Feel free to post feature requests. It's helpful if you can explain exactly why the feature would be useful. 49 | 50 | There are usually some outstanding feature requests in the [existing issues list](https://github.com/khoih-prog/ESP_MultiResetDetector/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement), feel free to add comments to them. 51 | 52 | --- 53 | 54 | ### Sending Pull Requests 55 | 56 | Pull Requests with changes and fixes are also welcome! 57 | 58 | Please use the `astyle` to reformat the updated library code as follows (demo for Ubuntu Linux) 59 | 60 | 1. Change directory to the library GitHub 61 | 62 | ``` 63 | xy@xy-Inspiron-3593:~$ cd Arduino/xy/ESP_MultiResetDetector_GitHub/ 64 | xy@xy-Inspiron-3593:~/Arduino/xy/ESP_MultiResetDetector_GitHub$ 65 | ``` 66 | 67 | 2. Issue astyle command 68 | 69 | ``` 70 | xy@xy-Inspiron-3593:~/Arduino/xy/ESP_MultiResetDetector_GitHub$ bash utils/restyle.sh 71 | ``` 72 | 73 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## ESP_MultiResetDetector Library 2 | 3 | [![arduino-library-badge](https://www.ardu-badge.com/badge/ESP_MultiResetDetector.svg?)](https://www.ardu-badge.com/ESP_MultiResetDetector) 4 | [![GitHub release](https://img.shields.io/github/release/khoih-prog/ESP_MultiResetDetector.svg)](https://github.com/khoih-prog/ESP_MultiResetDetector/releases) 5 | [![GitHub](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/khoih-prog/ESP_MultiResetDetector/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_MultiResetDetector.svg)](http://github.com/khoih-prog/ESP_MultiResetDetector/issues) 8 | 9 | 10 | Donate to my libraries using BuyMeACoffee 11 | 12 | 13 | --- 14 | --- 15 | 16 | ## Table of Contents 17 | 18 | * [Why do we need this ESP_MultiResetDetector library](#why-do-we-need-this-esp_multiresetdetector-library) 19 | * [Features](#features) 20 | * [Currently supported Boards](#currently-supported-boards) 21 | * [Changelog](changelog.md) 22 | * [Prerequisites](#prerequisites) 23 | * [Installation](#installation) 24 | * [Use Arduino Library Manager](#use-arduino-library-manager) 25 | * [Manual Install](#manual-install) 26 | * [VS Code & PlatformIO](#vs-code--platformio) 27 | * [HOWTO Usage](#howto-usage) 28 | * [Examples](#examples) 29 | * [ 1. ConfigOnMultiReset](examples/ConfigOnMultiReset) 30 | * [ 2. ConfigOnMRD_ESP32_minimal](examples/ConfigOnMRD_ESP32_minimal) 31 | * [ 3. ConfigOnMRD_ESP8266_minimal](examples/ConfigOnMRD_ESP8266_minimal) 32 | * [ 4. minimal](examples/minimal) 33 | * [ 5. checkWaitingMRD](examples/checkWaitingMRD) **New** 34 | * [Examples from other libraries](#examples-from-other-libraries) 35 | * [ 1. ESP_WiFiManager Library](https://github.com/khoih-prog/ESP_WiFiManager) 36 | * [ 1. ConfigOnDoubleReset](https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ConfigOnDoubleReset) 37 | * [ 2. ConfigOnDRD_FS_MQTT_Ptr](https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ConfigOnDRD_FS_MQTT_Ptr) 38 | * [ 3. ESP32_FSWebServer_DRD](https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ESP32_FSWebServer_DRD) 39 | * [ 4. ESP_FSWebServer_DRD](https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ESP_FSWebServer_DRD) 40 | * [ 5. ConfigOnDRD_ESP32_minimal](https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ConfigOnDRD_ESP32_minimal) 41 | * [ 6. ConfigOnDRD_ESP8266_minimal](https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ConfigOnDRD_ESP8266_minimal) 42 | * [ 7. ConfigOnDRD_FS_MQTT_Ptr_Complex](https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ConfigOnDRD_FS_MQTT_Ptr_Complex) 43 | * [ 8. ConfigOnDRD_FS_MQTT_Ptr_Medium](https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ConfigOnDRD_FS_MQTT_Ptr_Medium) 44 | * [ 2. ESPAsync_WiFiManager Library](https://github.com/khoih-prog/ESPAsync_WiFiManager) 45 | * [ 1. Async_ConfigOnDoubleReset](https://github.com/khoih-prog/ESPAsync_WiFiManager/tree/master/examples/Async_ConfigOnDoubleReset) 46 | * [ 2. Async_ConfigOnDRD_FS_MQTT_Ptr](https://github.com/khoih-prog/ESPAsync_WiFiManager/tree/master/examples/Async_ConfigOnDRD_FS_MQTT_Ptr) 47 | * [ 3. Async_ESP32_FSWebServer_DRD](https://github.com/khoih-prog/ESPAsync_WiFiManager/tree/master/examples/Async_ESP32_FSWebServer_DRD) 48 | * [ 4. Async_ESP_FSWebServer_DRD](https://github.com/khoih-prog/ESPAsync_WiFiManager/tree/master/examples/Async_ESP_FSWebServer_DRD) 49 | * [ 5. Async_ConfigOnDRD_ESP32_minimal](https://github.com/khoih-prog/ESPAsync_WiFiManager/tree/master/examples/Async_ConfigOnDRD_ESP32_minimal) 50 | * [ 6. Async_ConfigOnDRD_ESP8266_minimal](https://github.com/khoih-prog/ESPAsync_WiFiManager/tree/master/examples/Async_ConfigOnDRD_ESP8266_minimal) 51 | * [ 7. Async_ConfigOnDRD_FS_MQTT_Ptr_Complex](https://github.com/khoih-prog/ESPAsync_WiFiManager/tree/master/examples/Async_ConfigOnDRD_FS_MQTT_Ptr_Complex) 52 | * [ 8. Async_ConfigOnDRD_FS_MQTT_Ptr_Medium](https://github.com/khoih-prog/ESPAsync_WiFiManager/tree/master/examples/Async_ConfigOnDRD_FS_MQTT_Ptr_Medium) 53 | * [Many other libraries are depending on this library's DRD and MRD feature](#many-other-libraries-are-depending-on-this-librarys-drd-and-mrd-feature) 54 | * [ 1. Blynk_WM](https://github.com/khoih-prog/Blynk_WM) 55 | * [ 2. Blynk_Async_WM](https://github.com/khoih-prog/Blynk_Async_WM) 56 | * [ 3. BlynkEthernet_WM](https://github.com/khoih-prog/BlynkEthernet_WM) 57 | * [ 4. BlynkESP32_BT_WF](https://github.com/khoih-prog/BlynkESP32_BT_WF) 58 | * [ 5. BlynkGSM_Manager](https://github.com/khoih-prog/BlynkEthernet_WM) 59 | * [ 6. Blynk_Async_ESP32_BT_WF](https://github.com/khoih-prog/Blynk_Async_ESP32_BT_WF) 60 | * [ 7. Blynk_Async_GSM_Manager](https://github.com/khoih-prog/Blynk_Async_GSM_Manager) 61 | * [ 8. Ethernet_Manager](https://github.com/khoih-prog/Ethernet_Manager) 62 | * [Example checkWaitingMRD](#Example-checkWaitingMRD) 63 | * [Debug Terminal Output Samples](#debug-terminal-output-samples) 64 | * [1. ESP32_FSWebServer_DRD on ESP32_DEV](#1-esp32_fswebserver_drd-on-esp32_dev) 65 | * [2. minimal on ESP32_DEV](#2-minimal-on-esp32_dev) 66 | * [ 2.1 Data Corrupted => reset to 0](#21-data-corrupted--reset-to-0) 67 | * [ 2.2 Reset Detected => Reporting 1](#22-reset-detected--reporting-1) 68 | * [ 2.3 Reset Detected => Reporting 2](#23-reset-detected--reporting-2) 69 | * [ 2.4 Reset Detected => Reporting 3](#24-reset-detected--reporting-3) 70 | * [ 2.5 Reset Detected => Reporting 4](#25-reset-detected--reporting-4) 71 | * [ 2.6 Reset Detected => Reporting 5. Multi Reset Detected](#26-reset-detected--reporting-5-multi-reset-detected) 72 | * [ 2.7 Timed out => reset to 1](#27-timed-out--reset-to-1) 73 | * [ 2.8 Reset Detected => Reporting 1](#28-reset-detected--reporting-1) 74 | * [3. minimal on ESP8266_NODEMCU](#3-minimal-on-esp8266_nodemcu) 75 | * [ 3.1 Data Corrupted => reset to 0](#31-data-corrupted--reset-to-0) 76 | * [ 3.2 Reset Detected => Reporting 1](#32-reset-detected--reporting-1) 77 | * [ 3.3 Reset Detected => Reporting 2](#33-reset-detected--reporting-2) 78 | * [ 3.4 Reset Detected => Reporting 3](#34-reset-detected--reporting-3) 79 | * [ 3.5 Reset Detected => Reporting 4](#35-reset-detected--reporting-4) 80 | * [ 3.6 Reset Detected => Reporting 5. Multi Reset Detected](#36-reset-detected--reporting-5-multi-reset-detected) 81 | * [ 3.7 Timed out => reset to 1](#37-timed-out--reset-to-1) 82 | * [ 3.8 Reset Detected => Reporting 1](#38-reset-detected--reporting-1) 83 | * [4. ESPAsync_WiFi using LittleFS on ESP32S3_DEV](#4-ESPAsync_WiFi-using-LittleFS-on-ESP32S3_DEV) 84 | * [Libraries using ESP_MultiResetDetector, ESP_DoubleResetDetector or DoubleResetDetector_Generic library](#libraries-using-esp_multiresetdetector-esp_doubleresetdetector-or-doubleresetdetector_generic-library) 85 | * [Debug](#debug) 86 | * [Troubleshooting](#troubleshooting) 87 | * [Issues](#issues) 88 | * [TO DO](#to-do) 89 | * [DONE](#done) 90 | * [Contributions and Thanks](#contributions-and-thanks) 91 | * [Contributing](#contributing) 92 | * [License](#license) 93 | * [Copyright](#copyright) 94 | 95 | --- 96 | --- 97 | 98 | ### Why do we need this [ESP_MultiResetDetector library](https://github.com/khoih-prog/ESP_MultiResetDetector) 99 | 100 | #### Features 101 | 102 | [**ESP_MultiResetDetector**](https://github.com/khoih-prog/ESP_MultiResetDetector) is a library for the **ESP8266 and ESP32** boards to detects a **configurable multi reset**, within configurable timeout (default 10s) seconds, so that an alternative start-up mode can be used. Example use cases are to allow re-configuration of a device's WiFi / MQTT / Blynk credentials or to count the number of resets within a pre-determined timed. 103 | 104 | This library is based on, modified, bug-fixed and improved from [`Stephen Denne's DoubleResetDetector`](https://github.com/datacute/DoubleResetDetector) to add support to ESP8266 and ESP32 using EEPROM, SPIFFS and LittleFS besides original RTC. 105 | 106 | Currently, [`DoubleResetDetector`](https://github.com/datacute/DoubleResetDetector) only supports ESP8266 using RTC memory. 107 | 108 | This library can be used to detect a **multi reset within a predetermined time to force the program to enter a special operation** such as Config Portal, Clear Default Data, etc., using : 109 | 110 | 1. EEPROM, SPIFFS or LittleFS for ESP8266 and ESP32 boards. 111 | 2. RTC memory for ESP8266 boards (unadvised). 112 | 113 | #### Currently supported Boards 114 | 115 | This [**ESP_MultiResetDetector** library](https://github.com/khoih-prog/ESP_MultiResetDetector) currently supports these following boards: 116 | 117 | 1. **ESP32, ESP32_C3, ESP32_S2 and ESP32_S3 boards, using EEPROM, SPIFFS or LittleFS**. 118 | 2. **ESP8266 boards RTC memory, EEPROM, SPIFFS or LittleFS** 119 | 120 | --- 121 | --- 122 | 123 | 124 | ## Prerequisites 125 | 126 | 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) 127 | 2. [`ESP32 Core 2.0.5+`](https://github.com/espressif/arduino-esp32) for ESP32-based boards. [![Latest release](https://img.shields.io/github/release/espressif/arduino-esp32.svg)](https://github.com/espressif/arduino-esp32/releases/latest/) 128 | 3. [`ESP8266 Core 3.0.2+`](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. 129 | 4. [`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+** 130 | 131 | --- 132 | --- 133 | 134 | ## Installation 135 | 136 | ### Use Arduino Library Manager 137 | 138 | The best and easiest way is to use `Arduino Library Manager`. Search for `ESP_MultiResetDetector`, then select / install the latest version. You can also use this link [![arduino-library-badge](https://www.ardu-badge.com/badge/ESP_MultiResetDetector.svg?)](https://www.ardu-badge.com/ESP_MultiResetDetector) for more detailed instructions. 139 | 140 | ### Manual Install 141 | 142 | 1. Navigate to [ESP_MultiResetDetector](https://github.com/khoih-prog/ESP_MultiResetDetector) page. 143 | 2. Download the latest release `ESP_MultiResetDetector-main.zip`. 144 | 3. Extract the zip file to `ESP_MultiResetDetector-main` directory 145 | 4. Copy the whole `ESP_MultiResetDetector-main` folder to Arduino libraries' directory such as `~/Arduino/libraries/`. 146 | 147 | ### VS Code & PlatformIO: 148 | 149 | 1. Install [VS Code](https://code.visualstudio.com/) 150 | 2. Install [PlatformIO](https://platformio.org/platformio-ide) 151 | 3. Install [**ESP_MultiResetDetector** library](https://registry.platformio.org/libraries/khoih-prog/ESP_MultiResetDetector) by using [Library Manager](https://registry.platformio.org/libraries/khoih-prog/ESP_MultiResetDetector/installation). Search for **ESP_MultiResetDetector** in [Platform.io Author's Libraries](https://platformio.org/lib/search?query=author:%22Khoi%20Hoang%22) 152 | 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) 153 | 154 | --- 155 | --- 156 | 157 | #### HOWTO Usage 158 | 159 | How to use 160 | 161 | ```cpp 162 | // These defines must be put before #include 163 | // to select where to store MultiResetDetector's variable. 164 | // For ESP32, You must select one to be true (EEPROM or SPIFFS) 165 | // For ESP8266, You must select one to be true (RTC, EEPROM, LITTLEFS or SPIFFS) 166 | // Otherwise, library will use default EEPROM storage 167 | 168 | #ifdef ESP8266 169 | #define ESP8266_MRD_USE_RTC false //true 170 | #endif 171 | 172 | #define ESP_MRD_USE_LITTLEFS true 173 | #define ESP_MRD_USE_SPIFFS false 174 | #define ESP_MRD_USE_EEPROM false 175 | 176 | #define MULTIRESETDETECTOR_DEBUG true //false 177 | 178 | // These definitions must be placed before #include to be used 179 | // Otherwise, default values (MRD_TIMES = 3, MRD_TIMEOUT = 10 seconds and MRD_ADDRESS = 0) will be used 180 | // Number of subsequent resets during MRD_TIMEOUT to activate 181 | #define MRD_TIMES 5 182 | 183 | // Number of seconds after reset during which a 184 | // subsequent reset will be considered a multi reset. 185 | #define MRD_TIMEOUT 10 186 | 187 | // RTC/EEPROM Memory Address for the MultiResetDetector to use 188 | #define MRD_ADDRESS 0 189 | 190 | #include //https://github.com/khoih-prog/ESP_MultiResetDetector 191 | 192 | MultiResetDetector* mrd; 193 | 194 | #ifdef ESP32 195 | 196 | // For ESP32 197 | #ifndef LED_BUILTIN 198 | #define LED_BUILTIN 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED 199 | #endif 200 | 201 | #define LED_OFF LOW 202 | #define LED_ON HIGH 203 | 204 | #else 205 | 206 | // For ESP8266 207 | #define LED_ON LOW 208 | #define LED_OFF HIGH 209 | 210 | #endif 211 | 212 | void setup() 213 | { 214 | pinMode(LED_BUILTIN, OUTPUT); 215 | 216 | Serial.begin(115200); 217 | while (!Serial); 218 | delay(200); 219 | 220 | Serial.print(F("\nStarting ESP_MultiResetDetector minimal on ")); Serial.print(ARDUINO_BOARD); 221 | 222 | #if ESP_MRD_USE_LITTLEFS 223 | Serial.println(F(" using LittleFS")); 224 | #elif ESP_MRD_USE_SPIFFS 225 | Serial.println(F(" using SPIFFS")); 226 | #else 227 | Serial.println(F(" using EEPROM")); 228 | #endif 229 | 230 | Serial.println(ESP_MULTI_RESET_DETECTOR_VERSION); 231 | 232 | mrd = new MultiResetDetector(MRD_TIMEOUT, MRD_ADDRESS); 233 | 234 | if (mrd->detectMultiReset()) 235 | { 236 | Serial.println("Multi Reset Detected"); 237 | digitalWrite(LED_BUILTIN, LED_ON); 238 | } 239 | else 240 | { 241 | Serial.println("No Multi Reset Detected"); 242 | digitalWrite(LED_BUILTIN, LED_OFF); 243 | } 244 | 245 | } 246 | 247 | void loop() 248 | { 249 | // Call the multi reset detector loop method every so often, 250 | // so that it can recognise when the timeout expires. 251 | // You can also call mrd.stop() when you wish to no longer 252 | // consider the next reset as a multi reset. 253 | mrd->loop(); 254 | } 255 | ``` 256 | 257 | --- 258 | --- 259 | 260 | ### Examples 261 | 262 | 1. [ConfigOnMultiReset](examples/ConfigOnMultiReset) 263 | 2. [ConfigOnMRD_ESP32_minimal](examples/ConfigOnMRD_ESP32_minimal) 264 | 3. [ConfigOnMRD_ESP8266_minimal](examples/ConfigOnMRD_ESP8266_minimal) 265 | 4. [minimal](examples/minimal) 266 | 267 | ### Examples from other libraries 268 | 269 | #### 1.[ESP_WiFiManager Library](https://github.com/khoih-prog/ESP_WiFiManager) 270 | 271 | * [ 1. ConfigOnDoubleReset](https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ConfigOnDoubleReset) 272 | * [ 2. ConfigOnDRD_FS_MQTT_Ptr](https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ConfigOnDRD_FS_MQTT_Ptr) 273 | * [ 3. ESP32_FSWebServer_DRD](https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ESP32_FSWebServer_DRD) 274 | * [ 4. ESP_FSWebServer_DRD](https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ESP_FSWebServer_DRD) 275 | * [ 5. ConfigOnDRD_ESP32_minimal](https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ConfigOnDRD_ESP32_minimal) 276 | * [ 6. ConfigOnDRD_ESP8266_minimal](https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ConfigOnDRD_ESP8266_minimal) 277 | * [ 7. ConfigOnDRD_FS_MQTT_Ptr_Complex](https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ConfigOnDRD_FS_MQTT_Ptr_Complex) 278 | * [ 8. ConfigOnDRD_FS_MQTT_Ptr_Medium](https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ConfigOnDRD_FS_MQTT_Ptr_Medium) 279 | 280 | 281 | #### 2. [ESPAsync_WiFiManager Library](https://github.com/khoih-prog/ESPAsync_WiFiManager) 282 | 283 | * [ 1. Async_ConfigOnDoubleReset](https://github.com/khoih-prog/ESPAsync_WiFiManager/tree/master/examples/Async_ConfigOnDoubleReset) 284 | * [ 2. Async_ConfigOnDRD_FS_MQTT_Ptr](https://github.com/khoih-prog/ESPAsync_WiFiManager/tree/master/examples/Async_ConfigOnDRD_FS_MQTT_Ptr) 285 | * [ 3. Async_ESP32_FSWebServer_DRD](https://github.com/khoih-prog/ESPAsync_WiFiManager/tree/master/examples/Async_ESP32_FSWebServer_DRD) 286 | * [ 4. Async_ESP_FSWebServer_DRD](https://github.com/khoih-prog/ESPAsync_WiFiManager/tree/master/examples/Async_ESP_FSWebServer_DRD) 287 | * [ 5. Async_ConfigOnDRD_ESP32_minimal](https://github.com/khoih-prog/ESPAsync_WiFiManager/tree/master/examples/Async_ConfigOnDRD_ESP32_minimal) 288 | * [ 6. Async_ConfigOnDRD_ESP8266_minimal](https://github.com/khoih-prog/ESPAsync_WiFiManager/tree/master/examples/Async_ConfigOnDRD_ESP8266_minimal) 289 | * [ 7. Async_ConfigOnDRD_FS_MQTT_Ptr_Complex](https://github.com/khoih-prog/ESPAsync_WiFiManager/tree/master/examples/Async_ConfigOnDRD_FS_MQTT_Ptr_Complex) 290 | * [ 8. Async_ConfigOnDRD_FS_MQTT_Ptr_Medium](https://github.com/khoih-prog/ESPAsync_WiFiManager/tree/master/examples/Async_ConfigOnDRD_FS_MQTT_Ptr_Medium) 291 | 292 | and there are many more. 293 | 294 | #### Many other libraries are depending on this library's DRD and MRD feature 295 | 296 | All examples of these following libraries are using DRD/MRD feature of this [ESP_DoubleResetDetector Library](https://github.com/khoih-prog/ESP_DoubleResetDetector) or [ESP_MultiResetDetector Library](https://github.com/khoih-prog/ESP_MultiResetDetector) 297 | 298 | 299 | * [ 1. Blynk_WM](https://github.com/khoih-prog/Blynk_WM) 300 | * [ 2. Blynk_Async_WM](https://github.com/khoih-prog/Blynk_Async_WM) 301 | * [ 3. BlynkEthernet_WM](https://github.com/khoih-prog/BlynkEthernet_WM) 302 | * [ 4. BlynkESP32_BT_WF](https://github.com/khoih-prog/BlynkESP32_BT_WF) 303 | * [ 5. BlynkGSM_Manager](https://github.com/khoih-prog/BlynkEthernet_WM) 304 | * [ 6. Blynk_Async_ESP32_BT_WF](https://github.com/khoih-prog/Blynk_Async_ESP32_BT_WF) 305 | * [ 7. Blynk_Async_GSM_Manager](https://github.com/khoih-prog/Blynk_Async_GSM_Manager) 306 | * [ 8. Ethernet_Manager](https://github.com/khoih-prog/Ethernet_Manager) 307 | 308 | 309 | --- 310 | --- 311 | 312 | ### Example [checkWaitingMRD](examples/checkWaitingMRD) 313 | 314 | https://github.com/khoih-prog/ESP_MultiResetDetector/blob/c878d5e4df520f5b1be0f42e74be3462e4d87ac0/examples/checkWaitingMRD/checkWaitingMRD.ino#L16-L150 315 | 316 | 317 | --- 318 | --- 319 | 320 | ### Debug Terminal Output Samples 321 | 322 | #### 1. ESP32_FSWebServer_DRD on ESP32_DEV 323 | 324 | This is terminal debug output when running [ESP32_FSWebServer_DRD](https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ESP32_FSWebServer_DRD) on ***ESP32 ESP32_DEV.***. Config Portal was requested by DRD to input and save Credentials. The boards then connected to WiFi AP **HueNet1** using new Static IP successfully. WiFi AP **HueNet1** is then lost, and board **autoreconnects** itself to backup WiFi AP **HueNet2**. 325 | 326 | ```cpp 327 | Starting ESP32_FSWebServer_DRD with DoubleResetDetect using SPIFFS on ESP32_DEV 328 | ESP_WiFiManager v1.12.1 329 | ESP_MultiResetDetector v1.3.2 330 | FS File: /ConfigSW.json, size: 150B 331 | FS File: /CanadaFlag_1.png, size: 40.25KB 332 | FS File: /CanadaFlag_2.png, size: 8.12KB 333 | FS File: /CanadaFlag_3.jpg, size: 10.89KB 334 | FS File: /edit.htm.gz, size: 4.02KB 335 | FS File: /favicon.ico, size: 1.12KB 336 | FS File: /graphs.js.gz, size: 1.92KB 337 | FS File: /index.htm, size: 3.63KB 338 | FS File: /drd.dat, size: 4B 339 | FS File: /wifi_cred.dat, size: 192B 340 | 341 | [WM] RFC925 Hostname = ESP32-FSWebServerDRD 342 | [WM] setAPStaticIPConfig 343 | [WM] setSTAStaticIPConfig for USE_CONFIGURABLE_DNS 344 | [WM] Set CORS Header to : Your Access-Control-Allow-Origin 345 | Stored: SSID = HueNet2, Pass = 12345678 346 | [WM] * Add SSID = HueNet2 , PW = 12345678 347 | Got stored Credentials. Timeout 120s for Config Portal 348 | SPIFFS Flag read = 0xd0d04321 349 | No multiResetDetected 350 | Saving config file... 351 | Saving config file OK 352 | [WM] LoadWiFiCfgFile 353 | [WM] OK 354 | [WM] * Add SSID = HueNet1 , PW = 12345678 355 | [WM] * Add SSID = HueNet2 , PW = 12345678 356 | ConnectMultiWiFi in setup 357 | [WM] ConnectMultiWiFi with : 358 | [WM] * Flash-stored Router_SSID = HueNet2 , Router_Pass = 12345678 359 | [WM] * Additional SSID = HueNet1 , PW = 12345678 360 | [WM] * Additional SSID = HueNet2 , PW = 12345678 361 | [WM] Connecting MultiWifi... 362 | [WM] WiFi connected after time: 1 363 | [WM] SSID: HueNet1 ,RSSI= -27 364 | [WM] Channel: 2 ,IP address: 192.168.2.232 365 | After waiting 3.16 secs more in setup(), connection result is connected. Local IP: 192.168.2.232 366 | HTTP server started @ 192.168.2.232 367 | Open http://esp32-fs-browser.local/edit to see the file browser 368 | [WM] freeing allocated params! 369 | Stop multiResetDetecting 370 | Saving config file... 371 | Saving config file OK 372 | 373 | WiFi lost. Call connectMultiWiFi in loop 374 | [WM] ConnectMultiWiFi with : 375 | [WM] * Flash-stored Router_SSID = HueNet2 , Router_Pass = 12345678 376 | [WM] * Additional SSID = HueNet1 , PW = 12345678 377 | [WM] * Additional SSID = HueNet2 , PW = 12345678 378 | [WM] Connecting MultiWifi... 379 | [WM] WiFi connected after time: 3 380 | [WM] SSID: HueNet2 ,RSSI= -59 381 | [WM] Channel: 4 ,IP address: 192.168.2.232 382 | HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH 383 | ``` 384 | 385 | --- 386 | 387 | #### 2. minimal on ESP32_DEV 388 | 389 | This is terminal debug output when running [minimal](examples/minimal) on ***ESP32 ESP32_DEV using LittleFS.***. Config Portal was requested by MRD to input and save Credentials. 390 | 391 | 392 | #### 2.1 Data Corrupted => reset to 0 393 | 394 | ```cpp 395 | Starting ESP_MultiResetDetector minimal on ESP32_DEV using LittleFS 396 | ESP_MultiResetDetector v1.3.2 397 | /home/kh/Arduino/libraries/LITTLEFS-master/src/lfs.c:1003:error: Corrupted dir pair at {0x0, 0x1} 398 | E (241) esp_littlefs: mount failed, (-84) 399 | E (245) esp_littlefs: Failed to initialize LittleFS 400 | multiResetDetectorFlag = 0xFEFEFEFE 401 | lowerBytes = 0xFEFE, upperBytes = 0x0101 402 | lowerBytes = 0xFEFE, upperBytes = 0x0101 403 | detectRecentlyResetFlag: Data corrupted. Reset to 0 404 | No multiResetDetected, number of times = 0 405 | Saving config file... 406 | Saving config file OK 407 | No Multi Reset Detected 408 | Stop multiResetDetecting 409 | Saving config file... 410 | Saving config file OK 411 | ``` 412 | 413 | #### 2.2 Reset Detected => Reporting 1 414 | 415 | ```cpp 416 | Starting ESP_MultiResetDetector minimal on ESP32_DEV using LittleFS 417 | ESP_MultiResetDetector v1.3.2 418 | LittleFS Flag read = 0xFFFE0001 419 | multiResetDetectorFlag = 0xFFFE0001 420 | lowerBytes = 0x0001, upperBytes = 0x0001 421 | No multiResetDetected, number of times = 1 422 | LittleFS Flag read = 0xFFFE0001 423 | Saving config file... 424 | Saving config file OK 425 | No Multi Reset Detected 426 | ``` 427 | 428 | #### 2.3 Reset Detected => Reporting 2 429 | 430 | ```cpp 431 | Starting ESP_MultiResetDetector minimal on ESP32_DEV using LittleFS 432 | ESP_MultiResetDetector v1.3.2 433 | LittleFS Flag read = 0xFFFD0002 434 | multiResetDetectorFlag = 0xFFFD0002 435 | lowerBytes = 0x0002, upperBytes = 0x0002 436 | No multiResetDetected, number of times = 2 437 | LittleFS Flag read = 0xFFFD0002 438 | Saving config file... 439 | Saving config file OK 440 | No Multi Reset Detected 441 | ``` 442 | 443 | #### 2.4 Reset Detected => Reporting 3 444 | 445 | ```cpp 446 | Starting ESP_MultiResetDetector minimal on ESP32_DEV using LittleFS 447 | ESP_MultiResetDetector v1.3.2 448 | LittleFS Flag read = 0xFFFC0003 449 | multiResetDetectorFlag = 0xFFFC0003 450 | lowerBytes = 0x0003, upperBytes = 0x0003 451 | No multiResetDetected, number of times = 3 452 | LittleFS Flag read = 0xFFFC0003 453 | Saving config file... 454 | Saving config file OK 455 | No Multi Reset Detected 456 | ``` 457 | 458 | #### 2.5 Reset Detected => Reporting 4 459 | 460 | ```cpp 461 | Starting ESP_MultiResetDetector minimal on ESP32_DEV using LittleFS 462 | ESP_MultiResetDetector v1.3.2 463 | LittleFS Flag read = 0xFFFB0004 464 | multiResetDetectorFlag = 0xFFFB0004 465 | lowerBytes = 0x0004, upperBytes = 0x0004 466 | No multiResetDetected, number of times = 4 467 | LittleFS Flag read = 0xFFFB0004 468 | Saving config file... 469 | Saving config file OK 470 | No Multi Reset Detected 471 | ``` 472 | 473 | #### 2.6 Reset Detected => Reporting 5. Multi Reset Detected 474 | 475 | ```cpp 476 | Starting ESP_MultiResetDetector minimal on ESP32_DEV using LittleFS 477 | ESP_MultiResetDetector v1.3.2 478 | LittleFS Flag read = 0xFFFA0005 479 | multiResetDetectorFlag = 0xFFFA0005 480 | lowerBytes = 0x0005, upperBytes = 0x0005 481 | multiResetDetected, number of times = 5 482 | Saving config file... 483 | Saving config file OK 484 | Multi Reset Detected 485 | ``` 486 | 487 | #### 2.7 Timed out => reset to 1 488 | 489 | ```cpp 490 | Starting ESP_MultiResetDetector minimal on ESP32_DEV using LittleFS 491 | ESP_MultiResetDetector v1.3.2 492 | LittleFS Flag read = 0xFFFB0004 493 | multiResetDetectorFlag = 0xFFFB0004 494 | lowerBytes = 0x0004, upperBytes = 0x0004 495 | No multiResetDetected, number of times = 4 496 | LittleFS Flag read = 0xFFFB0004 497 | Saving config file... 498 | Saving config file OK 499 | No Multi Reset Detected 500 | Stop multiResetDetecting 501 | Saving config file... 502 | Saving config file OK 503 | ``` 504 | 505 | #### 2.8 Reset Detected => Reporting 1 506 | 507 | ```cpp 508 | 509 | Starting ESP_MultiResetDetector minimal on ESP32_DEV using LittleFS 510 | ESP_MultiResetDetector v1.3.2 511 | LittleFS Flag read = 0xFFFE0001 512 | multiResetDetectorFlag = 0xFFFE0001 513 | lowerBytes = 0x0001, upperBytes = 0x0001 514 | No multiResetDetected, number of times = 1 515 | LittleFS Flag read = 0xFFFE0001 516 | Saving config file... 517 | Saving config file OK 518 | No Multi Reset Detected 519 | 520 | ``` 521 | 522 | --- 523 | 524 | #### 3. minimal on ESP8266_NODEMCU 525 | 526 | This is terminal debug output when running [minimal](examples/minimal) on ***ESP8266_NODEMCU using LittleFS.***. Config Portal was requested by MRD to input and save Credentials. 527 | 528 | 529 | #### 3.1 Data Corrupted => reset to 0 530 | 531 | ```cpp 532 | Starting ESP_MultiResetDetector minimal on ESP8266_NODEMCU using LittleFS 533 | ESP_MultiResetDetector v1.3.2 534 | multiResetDetectorFlag = 0x00000000 535 | lowerBytes = 0x0000, upperBytes = 0xFFFF 536 | lowerBytes = 0x0000, upperBytes = 0xFFFF 537 | detectRecentlyResetFlag: Data corrupted. Reset to 0 538 | No multiResetDetected, number of times = 0 539 | Saving config file... 540 | Saving config file OK 541 | No Multi Reset Detected 542 | ``` 543 | 544 | #### 3.2 Reset Detected => Reporting 1 545 | 546 | ```cpp 547 | Starting ESP_MultiResetDetector minimal on ESP8266_NODEMCU using LittleFS 548 | ESP_MultiResetDetector v1.3.2 549 | LittleFS Flag read = 0xFFFE0001 550 | multiResetDetectorFlag = 0xFFFE0001 551 | lowerBytes = 0x0001, upperBytes = 0x0001 552 | No multiResetDetected, number of times = 1 553 | LittleFS Flag read = 0xFFFE0001 554 | Saving config file... 555 | Saving config file OK 556 | No Multi Reset Detected 557 | ``` 558 | 559 | #### 3.3 Reset Detected => Reporting 2 560 | 561 | ```cpp 562 | Starting ESP_MultiResetDetector minimal on ESP8266_NODEMCU using LittleFS 563 | ESP_MultiResetDetector v1.3.2 564 | LittleFS Flag read = 0xFFFD0002 565 | multiResetDetectorFlag = 0xFFFD0002 566 | lowerBytes = 0x0002, upperBytes = 0x0002 567 | No multiResetDetected, number of times = 2 568 | LittleFS Flag read = 0xFFFD0002 569 | Saving config file... 570 | Saving config file OK 571 | No Multi Reset Detected 572 | ``` 573 | 574 | #### 3.4 Reset Detected => Reporting 3 575 | 576 | ```cpp 577 | Starting ESP_MultiResetDetector minimal on ESP8266_NODEMCU using LittleFS 578 | ESP_MultiResetDetector v1.3.2 579 | LittleFS Flag read = 0xFFFC0003 580 | multiResetDetectorFlag = 0xFFFC0003 581 | lowerBytes = 0x0003, upperBytes = 0x0003 582 | No multiResetDetected, number of times = 3 583 | LittleFS Flag read = 0xFFFC0003 584 | Saving config file... 585 | Saving config file OK 586 | No Multi Reset Detected 587 | ``` 588 | 589 | #### 3.5 Reset Detected => Reporting 4 590 | 591 | ```cpp 592 | Starting ESP_MultiResetDetector minimal on ESP8266_NODEMCU using LittleFS 593 | ESP_MultiResetDetector v1.3.2 594 | LittleFS Flag read = 0xFFFB0004 595 | multiResetDetectorFlag = 0xFFFB0004 596 | lowerBytes = 0x0004, upperBytes = 0x0004 597 | No multiResetDetected, number of times = 4 598 | LittleFS Flag read = 0xFFFB0004 599 | Saving config file... 600 | Saving config file OK 601 | ``` 602 | 603 | #### 3.6 Reset Detected => Reporting 5. Multi Reset Detected 604 | 605 | ```cpp 606 | Starting ESP_MultiResetDetector minimal on ESP8266_NODEMCU using LittleFS 607 | ESP_MultiResetDetector v1.3.2 608 | LittleFS Flag read = 0xFFFA0005 609 | multiResetDetectorFlag = 0xFFFA0005 610 | lowerBytes = 0x0005, upperBytes = 0x0005 611 | multiResetDetected, number of times = 5 612 | Saving config file... 613 | Saving config file OK 614 | Multi Reset Detected 615 | ``` 616 | 617 | #### 3.7 Timed out => reset to 1 618 | 619 | ```cpp 620 | Starting ESP_MultiResetDetector minimal on ESP8266_NODEMCU using LittleFS 621 | ESP_MultiResetDetector v1.3.2 622 | LittleFS Flag read = 0xFFFB0004 623 | multiResetDetectorFlag = 0xFFFB0004 624 | lowerBytes = 0x0004, upperBytes = 0x0004 625 | No multiResetDetected, number of times = 4 626 | LittleFS Flag read = 0xFFFB0004 627 | Saving config file... 628 | Saving config file OK 629 | No Multi Reset Detected 630 | Stop multiResetDetecting 631 | Saving config file... 632 | Saving config file OK 633 | ``` 634 | 635 | #### 3.8 Reset Detected => Reporting 1 636 | 637 | ```cpp 638 | Starting ESP_MultiResetDetector minimal on ESP8266_NODEMCU using LittleFS 639 | ESP_MultiResetDetector v1.3.2 640 | LittleFS Flag read = 0xFFFE0001 641 | multiResetDetectorFlag = 0xFFFE0001 642 | lowerBytes = 0x0001, upperBytes = 0x0001 643 | No multiResetDetected, number of times = 1 644 | LittleFS Flag read = 0xFFFE0001 645 | Saving config file... 646 | Saving config file OK 647 | No Multi Reset Detected 648 | ``` 649 | 650 | --- 651 | 652 | #### 4. ESPAsync_WiFi using LittleFS on ESP32S3_DEV 653 | 654 | This is terminal debug output when running [ESPAsync_WiFi](https://github.com/khoih-prog/ESPAsync_WiFiManager_Lite/tree/main/examples/ESPAsync_WiFi) on ***ESP32 ESP32S3_DEV.***. Config Portal was requested by MRD to input and save Credentials. 655 | 656 | 657 | ```cpp 658 | Starting ESPAsync_WiFi using LittleFS on ESP32S3_DEV 659 | ESPAsync_WiFiManager_Lite v1.9.0 660 | ESP_MultiResetDetector v1.3.2 661 | LittleFS Flag read = 0xFFFC0003 662 | multiResetDetectorFlag = 0xFFFC0003 663 | lowerBytes = 0x0003, upperBytes = 0x0003 664 | multiResetDetected, number of times = 3 665 | Saving config file... 666 | Saving config file OK 667 | [WML] Hdr=ESP_WM_LITE,SSID=HueNet1,PW=12345678 668 | [WML] SSID1=HueNet2,PW1=12345678 669 | [WML] BName=ESP32_S3 670 | [WML] Hdr=ESP_WM_LITE,SSID=HueNet1,PW=12345678 671 | [WML] SSID1=HueNet2,PW1=12345678 672 | [WML] BName=ESP32_S3 673 | [WML] WiFi networks found: 674 | [WML] 1: HueNetTek, -30dB 675 | [WML] 2: HueNet, -31dB 676 | [WML] 3: HueNet1, -36dB 677 | [WML] 4: HueNet2, -55dB 678 | [WML] 5: SmartRG-02a2, -75dB 679 | [WML] 6: AT_301_WLREL6325F_f66d, -75dB 680 | [WML] 7: Linksys00043, -77dB 681 | [WML] 8: El khoury, -79dB 682 | [WML] 9: house, -79dB 683 | [WML] 10: Waterhome, -87dB 684 | [WML] 11: Offline5, -89dB 685 | [WML] 12: Access, -90dB 686 | [WML] 13: ESP151CD5, -90dB 687 | [WML] 14: Jessie, -90dB 688 | [WML] 15: AdeyemiHome, -90dB 689 | [WML] 16: BELL627, -90dB 690 | [WML] 17: JJ Realestate Investments, -90dB 691 | [WML] 18: BELL042, -92dB 692 | [WML] 19: VIRGIN874, -93dB 693 | [WML] 20: BELL905, -95dB 694 | [WML] 695 | stConf:SSID=ESP_E1A1DF7C,PW=MyESP_E1A1DF7C 696 | [WML] IP=192.168.4.1,ch=6 697 | F 698 | Your stored Credentials : 699 | Blynk Server1 = account.duckdns.org 700 | Token1 = token1 701 | Blynk Server2 = account.ddns.net 702 | Token2 = token2 703 | Port = 8080 704 | MQTT Server = mqtt.duckdns.org 705 | ``` 706 | 707 | --- 708 | --- 709 | 710 | ### Libraries using ESP_MultiResetDetector, ESP_DoubleResetDetector or DoubleResetDetector_Generic library 711 | 712 | You can also see how [`ESP_MultiResetDetector`](https://github.com/khoih-prog/ESP_MultiResetDetector) and [`DoubleResetDetector_Generic`](https://github.com/khoih-prog/DoubleResetDetector_Generic) are applied in many other libraries, such as: 713 | 714 | 1. [Blynk_WM](https://github.com/khoih-prog/Blynk_WM) 715 | 2. [BlynkEthernet_WM](https://github.com/khoih-prog/BlynkEthernet_WM) 716 | 3. [WiFiManager_NINA_Lite](https://github.com/khoih-prog/WiFiManager_NINA_Lite) 717 | 4. [BlynkESP32_BT_WF](https://github.com/khoih-prog/BlynkESP32_BT_WF), 718 | 5. [Blynk_GSM_Manager](https://github.com/khoih-prog/Blynk_GSM_Manager), 719 | 6. [Blynk_Esp8266AT_WM](https://github.com/khoih-prog/Blynk_Esp8266AT_WM), 720 | 7. [Blynk_WiFiNINA_WM](https://github.com/khoih-prog/Blynk_WiFiNINA_WM), 721 | 8. [Blynk_Async_WM](https://github.com/khoih-prog/Blynk_Async_WM), 722 | 9. [Blynk_Async_ESP32_BT_WF](https://github.com/khoih-prog/Blynk_Async_ESP32_BT_WF), 723 | 10. [Blynk_Async_GSM_Manager](https://github.com/khoih-prog/Blynk_Async_GSM_Manager), 724 | 11. [ESP_WiFiManager](https://github.com/khoih-prog/ESP_WiFiManager) 725 | 12. [ESPAsync_WiFiManager](https://github.com/khoih-prog/ESPAsync_WiFiManager) 726 | 13. [WiFiManager_NINA_Lite](https://github.com/khoih-prog/WiFiManager_NINA_Lite) 727 | 14. [BlynkEthernet_STM32_WM](https://github.com/khoih-prog/BlynkEthernet_STM32_WM), 728 | 15. [ESP_AT_WM_Lite](https://github.com/khoih-prog/ESP_AT_WM_Lite) 729 | 16. [WIOTerminal_WiFiManager](https://github.com/khoih-prog/WIOTerminal_WiFiManager) 730 | 17. [Ethernet_Manager](https://github.com/khoih-prog/Ethernet_Manager) 731 | 18. [Ethernet_Manager_STM32](https://github.com/khoih-prog/Ethernet_Manager_STM32) 732 | 733 | and the list is growing fast. 734 | 735 | --- 736 | --- 737 | 738 | ### Debug 739 | 740 | Debug is disabled by default. To enable debug: 741 | 742 | ```cpp 743 | // Use this to output debug msgs to Serial 744 | #define MULTIRESETDETECTOR_DEBUG true 745 | ``` 746 | 747 | --- 748 | 749 | ### Troubleshooting 750 | 751 | If you get compilation errors, more often than not, you may need to install a newer version of the `ESP32 / ESP8266` core for Arduino. 752 | 753 | Sometimes, the library will only work if you update the `ESP32 / ESP8266` core to the latest version because I am using some newly added function. 754 | 755 | --- 756 | --- 757 | 758 | 759 | ### Issues ### 760 | 761 | Submit issues to: [ESP_MultiResetDetector issues](https://github.com/khoih-prog/ESP_MultiResetDetector/issues) 762 | 763 | --- 764 | --- 765 | 766 | ### TO DO 767 | 768 | 1. Search for bug and improvement. 769 | 2. Similar features for Arduino (UNO, Mega, SAM DUE, SAMD21/SAMD51, nRF52, STM32, Teensy, etc.). Look at [**DoubleResetDetector_Generic**](https://github.com/khoih-prog/DoubleResetDetector_Generic) 770 | 771 | 772 | ### DONE 773 | 774 | 1. Multi Reset Detector for ESP32 (EEPROM, SPIFFS and LittleFS) and ESP8266 (RTC, EEPROM, SPIFFS and LittleFS). 775 | 2. Add support to `ESP32_C3`, `ESP32_S2` 776 | 3. Add support to `ESP32_S3` using ESP32 core v2.0.2+ 777 | 4. Add waitingForMRD() function to signal in MRD waiting period. 778 | 6. Fix ESP32 chipID for example`ConfigOnMultiReset` 779 | 7. Remove dependency on `LittleFS_esp32` library to prevent PIO error when using new ESP32 core v1.0.6+ 780 | 8. Add astyle using `allman` style. Restyle the library 781 | 782 | 783 | --- 784 | --- 785 | 786 | ### Contributions and thanks 787 | 788 | 1. Thanks to [kbssa](https://github.com/kbssa) for request enhancement in [Issue 9: Not an issue, but a question](https://github.com/khoih-prog/ESP_DoubleResetDetector/issues/9), leading to this new [ESP_MultiResetDetector Library](https://github.com/khoih-prog/ESP_MultiResetDetector) 789 | 2. Thanks to [Tochi Moreno](https://github.com/tochimoreno) for enhancement request in [DRD is waiting for a double reset? #14](https://github.com/khoih-prog/ESP_DoubleResetDetector/discussions/14) leading to v1.3.1 to add `waitingForMRD()` function to signal in MRD waiting period 790 | 791 | 792 | 793 | 794 | 795 | 796 |
kbssa
kbssa

tochimoreno
Tochi Moreno

797 | 798 | --- 799 | 800 | ### Contributing 801 | 802 | If you want to contribute to this project: 803 | - Report bugs and errors 804 | - Ask for enhancements 805 | - Create issues and pull requests 806 | - Tell other people about this library 807 | 808 | --- 809 | 810 | ### License 811 | 812 | - The library is licensed under [MIT](https://github.com/khoih-prog/ESP_MultiResetDetector/blob/main/LICENSE) 813 | 814 | --- 815 | 816 | ### Copyright 817 | 818 | Copyright (c) 2020- Khoi Hoang 819 | 820 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | ## ESP_MultiResetDetector Library 2 | 3 | [![arduino-library-badge](https://www.ardu-badge.com/badge/ESP_MultiResetDetector.svg?)](https://www.ardu-badge.com/ESP_MultiResetDetector) 4 | [![GitHub release](https://img.shields.io/github/release/khoih-prog/ESP_MultiResetDetector.svg)](https://github.com/khoih-prog/ESP_MultiResetDetector/releases) 5 | [![GitHub](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/khoih-prog/ESP_MultiResetDetector/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_MultiResetDetector.svg)](http://github.com/khoih-prog/ESP_MultiResetDetector/issues) 8 | 9 | 10 | Donate to my libraries using BuyMeACoffee 11 | 12 | 13 | --- 14 | --- 15 | 16 | ## Table of Contents 17 | 18 | 19 | * [Changelog](#changelog) 20 | * [Releases v1.3.2](#releases-v132) 21 | * [Releases v1.3.1](#releases-v131) 22 | * [Releases v1.3.0](#releases-v130) 23 | * [Releases v1.2.1](#releases-v121) 24 | * [Releases v1.2.0](#releases-v120) 25 | * [Releases v1.1.2](#releases-v112) 26 | * [Releases v1.1.1](#releases-v111) 27 | 28 | --- 29 | --- 30 | 31 | ## Changelog 32 | 33 | ### Releases v1.3.2 34 | 35 | 1. Fix ESP32 chipID for example `ConfigOnMultiReset` 36 | 2. Remove dependency on `LittleFS_esp32` library to prevent PIO error when using new ESP32 core v1.0.6+ 37 | 38 | ### Releases v1.3.1 39 | 40 | 1. Add waitingForMRD() function to signal in MRD waiting period. Check [DRD is waiting for a double reset? #14](https://github.com/khoih-prog/ESP_DoubleResetDetector/discussions/14) 41 | 2. Add example [checkWaitingMRD](https://github.com/khoih-prog/ESP_MultiResetDetector/tree/main/examples/checkWaitingMRD) to demo how to use the new feature. 42 | 43 | ### Releases v1.3.0 44 | 45 | 1. Add support to `ESP32_S3` using [ESP32 core, esp32-s3-support branch, v2.0.2+](https://github.com/espressif/arduino-esp32/tree/esp32-s3-support) 46 | 47 | ### Releases v1.2.1 48 | 49 | 1. Fix compile error for ESP32 core v1.0.5- 50 | 51 | ### Releases v1.2.0 52 | 53 | 1. Auto detect ESP32 core and use either built-in LittleFS or [LITTLEFS](https://github.com/lorol/LITTLEFS) library 54 | 2. Update `library.json` to use new `headers` for PIO 55 | 3. Update `platformio.ini` 56 | 57 | ### Releases v1.1.2 58 | 59 | 1. Update `platform.ini` and `library.json` to use original `khoih-prog` instead of `khoih.prog` after PIO fix 60 | 61 | ### Releases v1.1.1 62 | 63 | 1. Initial coding to support Multiple Reset Detection. 64 | 2. Sync with ESP_DoubleResetDetector v1.1.1 65 | 66 | 67 | -------------------------------------------------------------------------------- /examples/ConfigOnMRD_ESP32_minimal/ConfigOnMRD_ESP32_minimal.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | ConfigOnMRD_ESP32_minimal.ino 3 | For ESP8266 / ESP32 boards 4 | 5 | ESP_MultiResetDetector is a library for the ESP8266/Arduino platform 6 | to enable trigger configure mode by resetting ESP32 / ESP8266 multiple times. 7 | 8 | Based on and modified from 9 | 1) DataCute https://github.com/datacute/MultiResetDetector 10 | 2) Khoi Hoang https://github.com/khoih-prog/ESP_MultiResetDetector 11 | 12 | Built by Khoi Hoang https://github.com/khoih-prog/ESP_MultiResetDetector 13 | Licensed under MIT license 14 | *****************************************************************************************************************************/ 15 | 16 | #if defined(ESP32) 17 | #define USE_SPIFFS true 18 | #define ESP_MRD_USE_LITTLEFS false 19 | #define ESP_MRD_USE_SPIFFS true 20 | #define ESP_MRD_USE_EEPROM false 21 | #else 22 | #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting. 23 | #endif 24 | #include //https://github.com/khoih-prog/ESP_WiFiManager 25 | #define MRD_TIMES 3 26 | #define MRD_TIMEOUT 10 27 | #define MRD_ADDRESS 0 28 | #define MULTIRESETDETECTOR_DEBUG true 29 | #include //https://github.com/khoih-prog/ESP_MultiResetDetector 30 | MultiResetDetector* mrd; 31 | const int PIN_LED = 2; 32 | bool initialConfig = false; 33 | 34 | void setup() 35 | { 36 | pinMode(PIN_LED, OUTPUT); 37 | Serial.begin(115200); 38 | 39 | while (!Serial) 40 | ; 41 | 42 | delay(200); 43 | Serial.print(F("\nStarting ConfigOnMRD_ESP32_minimal on ")); 44 | Serial.print(ARDUINO_BOARD); 45 | #if ESP_MRD_USE_LITTLEFS 46 | Serial.println(F(" using LittleFS")); 47 | #elif ESP_MRD_USE_SPIFFS 48 | Serial.println(F(" using SPIFFS")); 49 | #else 50 | Serial.println(F(" using EEPROM")); 51 | #endif 52 | Serial.println(ESP_WIFIMANAGER_VERSION); 53 | Serial.println(ESP_MULTI_RESET_DETECTOR_VERSION); 54 | mrd = new MultiResetDetector(MRD_TIMEOUT, MRD_ADDRESS); 55 | 56 | if (mrd->detectMultiReset()) 57 | { 58 | Serial.println(F("MRD")); 59 | initialConfig = true; 60 | } 61 | 62 | ESP_WiFiManager ESP_wifiManager("ConfigOnMRD_ESP32_minimal"); 63 | 64 | if (ESP_wifiManager.WiFi_SSID() == "") 65 | { 66 | Serial.println(F("No AP credentials")); 67 | initialConfig = true; 68 | } 69 | 70 | if (initialConfig) 71 | { 72 | Serial.println(F("Starting Config Portal")); 73 | digitalWrite(PIN_LED, HIGH); 74 | 75 | if (!ESP_wifiManager.startConfigPortal()) 76 | { 77 | Serial.println(F("Not connected to WiFi")); 78 | } 79 | else 80 | { 81 | Serial.println(F("connected")); 82 | } 83 | } 84 | else 85 | { 86 | WiFi.mode(WIFI_STA); 87 | WiFi.begin(); 88 | } 89 | 90 | unsigned long startedAt = millis(); 91 | digitalWrite(PIN_LED, LOW); 92 | Serial.print(F("After waiting ")); 93 | int connRes = WiFi.waitForConnectResult(); 94 | float waited = (millis() - startedAt); 95 | Serial.print(waited / 1000); 96 | Serial.print(F(" secs , Connection result is ")); 97 | Serial.println(connRes); 98 | 99 | if (WiFi.status() != WL_CONNECTED) 100 | { 101 | Serial.println(F("Failed to connect")); 102 | } 103 | else 104 | { 105 | Serial.print(F("Local IP: ")); 106 | Serial.println(WiFi.localIP()); 107 | } 108 | } 109 | void loop() 110 | { 111 | mrd->loop(); 112 | } 113 | -------------------------------------------------------------------------------- /examples/ConfigOnMRD_ESP8266_minimal/ConfigOnMRD_ESP8266_minimal.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | ConfigOnMRD_ES8266_minimal.ino 3 | For ESP8266 / ESP32 boards 4 | 5 | ESP_MultiResetDetector is a library for the ESP8266/Arduino platform 6 | to enable trigger configure mode by resetting ESP32 / ESP8266 multiple times. 7 | 8 | Based on and modified from 9 | 1) DataCute https://github.com/datacute/MultiResetDetector 10 | 2) Khoi Hoang https://github.com/khoih-prog/ESP_MultiResetDetector 11 | 12 | Built by Khoi Hoang https://github.com/khoih-prog/ESP_MultiResetDetector 13 | Licensed under MIT license 14 | *****************************************************************************************************************************/ 15 | 16 | #if defined(ESP8266) 17 | #define USE_LITTLEFS true 18 | #define ESP_MRD_USE_LITTLEFS true 19 | #define ESP_MRD_USE_SPIFFS false 20 | #define ESP_MRD_USE_EEPROM false 21 | #else 22 | #error This code is intended to run on the ESP8266 or ESP32 platform! Please check your Tools->Board setting. 23 | #endif 24 | #include //https://github.com/khoih-prog/ESP_WiFiManager 25 | #define MRD_TIMES 3 26 | #define MRD_TIMEOUT 10 27 | #define MRD_ADDRESS 0 28 | #define MULTIRESETDETECTOR_DEBUG true 29 | #include //https://github.com/khoih-prog/ESP_MultiResetDetector 30 | MultiResetDetector* mrd; 31 | const int PIN_LED = 2; 32 | bool initialConfig = false; 33 | 34 | void setup() 35 | { 36 | pinMode(PIN_LED, OUTPUT); 37 | Serial.begin(115200); 38 | 39 | while (!Serial) 40 | ; 41 | 42 | delay(200); 43 | Serial.print(F("\nStarting ConfigOnMRD_ES8266_minimal on ")); 44 | Serial.print(ARDUINO_BOARD); 45 | #if ESP_MRD_USE_LITTLEFS 46 | Serial.println(F(" using LittleFS")); 47 | #elif ESP_MRD_USE_SPIFFS 48 | Serial.println(F(" using SPIFFS")); 49 | #else 50 | Serial.println(F(" using EEPROM")); 51 | #endif 52 | Serial.println(ESP_WIFIMANAGER_VERSION); 53 | Serial.println(ESP_MULTI_RESET_DETECTOR_VERSION); 54 | 55 | if (WiFi.SSID() == "") 56 | { 57 | Serial.println(F("No AP credentials")); 58 | initialConfig = true; 59 | } 60 | 61 | mrd = new MultiResetDetector(MRD_TIMEOUT, MRD_ADDRESS); 62 | 63 | if (mrd->detectMultiReset()) 64 | { 65 | Serial.println(F("MRD")); 66 | initialConfig = true; 67 | } 68 | 69 | if (initialConfig) 70 | { 71 | Serial.println(F("Starting Config Portal")); 72 | digitalWrite(PIN_LED, LOW); 73 | ESP_WiFiManager ESP_wifiManager("ConfigOnMRD_ES8266_minimal"); 74 | ESP_wifiManager.setConfigPortalTimeout(0); 75 | 76 | if (!ESP_wifiManager.startConfigPortal()) 77 | { 78 | Serial.println(F("Not connected to WiFi")); 79 | } 80 | else 81 | { 82 | Serial.println(F("connected")); 83 | } 84 | } 85 | 86 | digitalWrite(PIN_LED, HIGH); 87 | Serial.print(F("After waiting ")); //WiFi.mode(WIFI_STA); 88 | unsigned long startedAt = millis(); 89 | int connRes = WiFi.waitForConnectResult(); 90 | float waited = (millis() - startedAt); 91 | Serial.print(waited / 1000); 92 | Serial.print(F(" secs , Connection result is ")); 93 | Serial.println(connRes); 94 | 95 | if (WiFi.status() != WL_CONNECTED) 96 | { 97 | Serial.println(F("Failed to connect")); 98 | } 99 | else 100 | { 101 | Serial.print(F("Local IP: ")); 102 | Serial.println(WiFi.localIP()); 103 | } 104 | } 105 | void loop() 106 | { 107 | mrd->loop(); 108 | } 109 | -------------------------------------------------------------------------------- /examples/ConfigOnMultiReset/ConfigOnMultiReset.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | ConfigOnMultiReset.ino 3 | For ESP8266 / ESP32 boards 4 | 5 | ESP_MultiResetDetector is a library for the ESP8266/Arduino platform 6 | to enable trigger configure mode by resetting ESP32 / ESP8266 multiple times. 7 | 8 | Based on and modified from 9 | 1) DataCute https://github.com/datacute/MultiResetDetector 10 | 2) Khoi Hoang https://github.com/khoih-prog/ESP_MultiResetDetector 11 | 12 | Built by Khoi Hoang https://github.com/khoih-prog/ESP_MultiResetDetector 13 | Licensed under MIT license 14 | *****************************************************************************************************************************/ 15 | /**************************************************************************************************************************** 16 | This example will open a configuration portal when the reset button is pressed twice. 17 | This method works well on Wemos boards which have a single reset button on board. It avoids using a pin for launching the configuration portal. 18 | 19 | How It Works 20 | 1) ESP8266 21 | Save data in RTC memory, EPPROM, LittleFS or SPIFFS 22 | 2) ESP32 23 | Save data in 24 | a) EEPROM from address 256, size 512 bytes (both configurable) 25 | b) SPIFFS 26 | 27 | For LittleFS or SPIFFS, file name is "/mrd.dat" 28 | 29 | So when the device starts up it checks this region of ram for a flag to see if it has been recently reset. 30 | If so it launches a configuration portal, if not it sets the reset flag. After running for a while this flag is cleared so that 31 | it will only launch the configuration portal in response to closely spaced resets. 32 | 33 | Settings 34 | There are values to be set in the sketch. 35 | MRD_TIMES - Number of subsequent resets during MRD_TIMEOUT to activate 36 | MRD_TIMEOUT - Number of seconds to wait for the second reset. Set to 10 in the example. 37 | MRD_ADDRESS - The address in ESP8266 RTC RAM/EEPROM address to store the flag. Must not be used in the same sketch 38 | 39 | This example, originally relied on the Double Reset Detector library from https://github.com/datacute/DoubleResetDetector 40 | To support ESP32, use ESP_MultiResetDetector library from //https://github.com/khoih-prog/ESP_MultiResetDetector 41 | *****************************************************************************************************************************/ 42 | 43 | #if !( defined(ESP8266) || defined(ESP32) ) 44 | #error This code is intended to run on the ESP8266 or ESP32 platform! Please check your Tools->Board setting. 45 | #endif 46 | 47 | // Use from 0 to 4. Higher number, more debugging messages and memory usage. 48 | #define _WIFIMGR_LOGLEVEL_ 3 49 | 50 | #include 51 | 52 | //Ported to ESP32 53 | #ifdef ESP32 54 | #include 55 | #include 56 | #include 57 | 58 | // From v1.1.0 59 | #include 60 | WiFiMulti wifiMulti; 61 | 62 | // LittleFS has higher priority than SPIFFS 63 | #define USE_LITTLEFS true 64 | #define USE_SPIFFS false 65 | 66 | #if USE_LITTLEFS 67 | // Use LittleFS 68 | #include "FS.h" 69 | 70 | // Check cores/esp32/esp_arduino_version.h and cores/esp32/core_version.h 71 | //#if ( ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 0) ) //(ESP_ARDUINO_VERSION_MAJOR >= 2) 72 | #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) ) 73 | #warning Using ESP32 Core 1.0.6 or 2.0.0+ 74 | // The library has been merged into esp32 core from release 1.0.6 75 | #include 76 | 77 | FS* filesystem = &LittleFS; 78 | #define FileFS LittleFS 79 | #define FS_Name "LittleFS" 80 | #else 81 | #warning Using ESP32 Core 1.0.5-. You must install LITTLEFS library 82 | // The library has been merged into esp32 core from release 1.0.6 83 | #include // https://github.com/lorol/LITTLEFS 84 | 85 | FS* filesystem = &LITTLEFS; 86 | #define FileFS LITTLEFS 87 | #define FS_Name "LittleFS" 88 | #endif 89 | 90 | #elif USE_SPIFFS 91 | #include 92 | FS* filesystem = &SPIFFS; 93 | #define FileFS SPIFFS 94 | #define FS_Name "SPIFFS" 95 | #else 96 | // Use FFat 97 | #include 98 | FS* filesystem = &FFat; 99 | #define FileFS FFat 100 | #define FS_Name "FFat" 101 | #endif 102 | ////// 103 | 104 | #define LED_BUILTIN 2 105 | #define LED_ON HIGH 106 | #define LED_OFF LOW 107 | 108 | #else 109 | #include //https://github.com/esp8266/Arduino 110 | //needed for library 111 | #include 112 | #include 113 | 114 | // From v1.1.0 115 | #include 116 | ESP8266WiFiMulti wifiMulti; 117 | 118 | #define USE_LITTLEFS true 119 | 120 | #if USE_LITTLEFS 121 | #include 122 | FS* filesystem = &LittleFS; 123 | #define FileFS LittleFS 124 | #define FS_Name "LittleFS" 125 | #else 126 | FS* filesystem = &SPIFFS; 127 | #define FileFS SPIFFS 128 | #define FS_Name "SPIFFS" 129 | #endif 130 | ////// 131 | 132 | #define ESP_getChipId() (ESP.getChipId()) 133 | 134 | #define LED_ON LOW 135 | #define LED_OFF HIGH 136 | #endif 137 | 138 | // These defines must be put before #include 139 | // to select where to store MultiResetDetector's variable. 140 | // For ESP32, You must select one to be true (EEPROM or SPIFFS) 141 | // For ESP8266, You must select one to be true (RTC, EEPROM, SPIFFS or LITTLEFS) 142 | // Otherwise, library will use default EEPROM storage 143 | #ifdef ESP32 144 | 145 | // These defines must be put before #include 146 | // to select where to store MultiResetDetector's variable. 147 | // For ESP32, You must select one to be true (EEPROM or SPIFFS) 148 | // Otherwise, library will use default EEPROM storage 149 | #if USE_LITTLEFS 150 | #define ESP_MRD_USE_LITTLEFS true 151 | #define ESP_MRD_USE_SPIFFS false 152 | #define ESP_MRD_USE_EEPROM false 153 | #elif USE_SPIFFS 154 | #define ESP_MRD_USE_LITTLEFS false 155 | #define ESP_MRD_USE_SPIFFS true 156 | #define ESP_MRD_USE_EEPROM false 157 | #else 158 | #define ESP_MRD_USE_LITTLEFS false 159 | #define ESP_MRD_USE_SPIFFS false 160 | #define ESP_MRD_USE_EEPROM true 161 | #endif 162 | 163 | #else //ESP8266 164 | 165 | // For MRD 166 | // These defines must be put before #include 167 | // to select where to store MultiResetDetector's variable. 168 | // For ESP8266, You must select one to be true (RTC, EEPROM, SPIFFS or LITTLEFS) 169 | // Otherwise, library will use default EEPROM storage 170 | #if USE_LITTLEFS 171 | #define ESP_MRD_USE_LITTLEFS true 172 | #define ESP_MRD_USE_SPIFFS false 173 | #else 174 | #define ESP_MRD_USE_LITTLEFS false 175 | #define ESP_MRD_USE_SPIFFS true 176 | #endif 177 | 178 | #define ESP_MRD_USE_EEPROM false 179 | #define ESP8266_MRD_USE_RTC false 180 | #endif 181 | 182 | #define MULTIRESETDETECTOR_DEBUG true //false 183 | 184 | // These definitions must be placed before #include to be used 185 | // Otherwise, default values (MRD_TIMES = 3, MRD_TIMEOUT = 10 seconds and MRD_ADDRESS = 0) will be used 186 | // Number of subsequent resets during MRD_TIMEOUT to activate 187 | #define MRD_TIMES 3 188 | 189 | // Number of seconds after reset during which a subseqent reset will be considered a mlti reset. 190 | #define MRD_TIMEOUT 10 191 | 192 | // RTC/EEPPROM Address for the MultiResetDetector to use 193 | #define MRD_ADDRESS 0 194 | 195 | #include //https://github.com/khoih-prog/ESP_MultiResetDetector 196 | 197 | //MultiResetDetector mrd(MRD_TIMEOUT, MRD_ADDRESS); 198 | MultiResetDetector* mrd;////// 199 | 200 | // Onboard LED I/O pin on NodeMCU board 201 | const int PIN_LED = 2; // D4 on NodeMCU and WeMos. GPIO2/ADC12 of ESP32. Controls the onboard LED. 202 | 203 | // From v1.1.0 204 | // You only need to format the filesystem once 205 | //#define FORMAT_FILESYSTEM true 206 | #define FORMAT_FILESYSTEM false 207 | 208 | #define MIN_AP_PASSWORD_SIZE 8 209 | 210 | #define SSID_MAX_LEN 32 211 | //From v1.0.10, WPA2 passwords can be up to 63 characters long. 212 | #define PASS_MAX_LEN 64 213 | 214 | typedef struct 215 | { 216 | char wifi_ssid[SSID_MAX_LEN]; 217 | char wifi_pw [PASS_MAX_LEN]; 218 | } WiFi_Credentials; 219 | 220 | typedef struct 221 | { 222 | String wifi_ssid; 223 | String wifi_pw; 224 | } WiFi_Credentials_String; 225 | 226 | #define NUM_WIFI_CREDENTIALS 2 227 | 228 | typedef struct 229 | { 230 | WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS]; 231 | } WM_Config; 232 | 233 | WM_Config WM_config; 234 | 235 | #define CONFIG_FILENAME F("/wifi_cred.dat") 236 | ////// 237 | 238 | // Indicates whether ESP has WiFi credentials saved from previous session, or mlti reset detected 239 | bool initialConfig = false; 240 | 241 | // Use false if you don't like to display Available Pages in Information Page of Config Portal 242 | // Comment out or use true to display Available Pages in Information Page of Config Portal 243 | // Must be placed before #include 244 | #define USE_AVAILABLE_PAGES false 245 | 246 | // From v1.0.10 to permit disable/enable StaticIP configuration in Config Portal from sketch. Valid only if DHCP is used. 247 | // You'll loose the feature of dynamically changing from DHCP to static IP, or vice versa 248 | // You have to explicitly specify false to disable the feature. 249 | //#define USE_STATIC_IP_CONFIG_IN_CP false 250 | 251 | // Use false to disable NTP config. Advisable when using Cellphone, Tablet to access Config Portal. 252 | // See Issue 23: On Android phone ConfigPortal is unresponsive (https://github.com/khoih-prog/ESP_WiFiManager/issues/23) 253 | #define USE_ESP_WIFIMANAGER_NTP false 254 | 255 | // Use true to enable CloudFlare NTP service. System can hang if you don't have Internet access while accessing CloudFlare 256 | // See Issue #21: CloudFlare link in the default portal (https://github.com/khoih-prog/ESP_WiFiManager/issues/21) 257 | #define USE_CLOUDFLARE_NTP false 258 | 259 | // New in v1.0.11 260 | #define USING_CORS_FEATURE true 261 | ////// 262 | 263 | // Use USE_DHCP_IP == true for dynamic DHCP IP, false to use static IP which you have to change accordingly to your network 264 | #if (defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP) 265 | // Force DHCP to be true 266 | #if defined(USE_DHCP_IP) 267 | #undef USE_DHCP_IP 268 | #endif 269 | #define USE_DHCP_IP true 270 | #else 271 | // You can select DHCP or Static IP here 272 | #define USE_DHCP_IP true 273 | //#define USE_DHCP_IP false 274 | #endif 275 | 276 | #if ( USE_DHCP_IP || ( defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP ) ) 277 | // Use DHCP 278 | #warning Using DHCP IP 279 | IPAddress stationIP = IPAddress(0, 0, 0, 0); 280 | IPAddress gatewayIP = IPAddress(192, 168, 2, 1); 281 | IPAddress netMask = IPAddress(255, 255, 255, 0); 282 | #else 283 | // Use static IP 284 | #warning Using static IP 285 | #ifdef ESP32 286 | IPAddress stationIP = IPAddress(192, 168, 2, 232); 287 | #else 288 | IPAddress stationIP = IPAddress(192, 168, 2, 186); 289 | #endif 290 | 291 | IPAddress gatewayIP = IPAddress(192, 168, 2, 1); 292 | IPAddress netMask = IPAddress(255, 255, 255, 0); 293 | #endif 294 | 295 | #define USE_CONFIGURABLE_DNS true 296 | 297 | IPAddress dns1IP = gatewayIP; 298 | IPAddress dns2IP = IPAddress(8, 8, 8, 8); 299 | 300 | // New in v1.4.0 301 | IPAddress APStaticIP = IPAddress(192, 168, 100, 1); 302 | IPAddress APStaticGW = IPAddress(192, 168, 100, 1); 303 | IPAddress APStaticSN = IPAddress(255, 255, 255, 0); 304 | 305 | #include //https://github.com/khoih-prog/ESP_WiFiManager 306 | 307 | // SSID and PW for Config Portal 308 | String ssid = "ESP_" + String(ESP_getChipId(), HEX); 309 | const char* password = "your_password"; 310 | 311 | // SSID and PW for your Router 312 | String Router_SSID; 313 | String Router_Pass; 314 | 315 | 316 | // Function Prototypes 317 | uint8_t connectMultiWiFi(void); 318 | 319 | /////////////////////////////////////////// 320 | // New in v1.4.0 321 | /****************************************** 322 | // Defined in ESP_WiFiManager.h 323 | typedef struct 324 | { 325 | IPAddress _ap_static_ip; 326 | IPAddress _ap_static_gw; 327 | IPAddress _ap_static_sn; 328 | 329 | } WiFi_AP_IPConfig; 330 | 331 | typedef struct 332 | { 333 | IPAddress _sta_static_ip; 334 | IPAddress _sta_static_gw; 335 | IPAddress _sta_static_sn; 336 | #if USE_CONFIGURABLE_DNS 337 | IPAddress _sta_static_dns1; 338 | IPAddress _sta_static_dns2; 339 | #endif 340 | } WiFi_STA_IPConfig; 341 | ******************************************/ 342 | 343 | WiFi_AP_IPConfig WM_AP_IPconfig; 344 | WiFi_STA_IPConfig WM_STA_IPconfig; 345 | 346 | void initAPIPConfigStruct(WiFi_AP_IPConfig &in_WM_AP_IPconfig) 347 | { 348 | in_WM_AP_IPconfig._ap_static_ip = APStaticIP; 349 | in_WM_AP_IPconfig._ap_static_gw = APStaticGW; 350 | in_WM_AP_IPconfig._ap_static_sn = APStaticSN; 351 | } 352 | 353 | void initSTAIPConfigStruct(WiFi_STA_IPConfig &in_WM_STA_IPconfig) 354 | { 355 | in_WM_STA_IPconfig._sta_static_ip = stationIP; 356 | in_WM_STA_IPconfig._sta_static_gw = gatewayIP; 357 | in_WM_STA_IPconfig._sta_static_sn = netMask; 358 | #if USE_CONFIGURABLE_DNS 359 | in_WM_STA_IPconfig._sta_static_dns1 = dns1IP; 360 | in_WM_STA_IPconfig._sta_static_dns2 = dns2IP; 361 | #endif 362 | } 363 | 364 | void displayIPConfigStruct(WiFi_STA_IPConfig in_WM_STA_IPconfig) 365 | { 366 | LOGERROR3(F("stationIP ="), in_WM_STA_IPconfig._sta_static_ip, ", gatewayIP =", in_WM_STA_IPconfig._sta_static_gw); 367 | LOGERROR1(F("netMask ="), in_WM_STA_IPconfig._sta_static_sn); 368 | #if USE_CONFIGURABLE_DNS 369 | LOGERROR3(F("dns1IP ="), in_WM_STA_IPconfig._sta_static_dns1, ", dns2IP =", in_WM_STA_IPconfig._sta_static_dns2); 370 | #endif 371 | } 372 | 373 | void configWiFi(WiFi_STA_IPConfig in_WM_STA_IPconfig) 374 | { 375 | #if USE_CONFIGURABLE_DNS 376 | // Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5 377 | WiFi.config(in_WM_STA_IPconfig._sta_static_ip, in_WM_STA_IPconfig._sta_static_gw, in_WM_STA_IPconfig._sta_static_sn, 378 | in_WM_STA_IPconfig._sta_static_dns1, in_WM_STA_IPconfig._sta_static_dns2); 379 | #else 380 | // Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2. 381 | WiFi.config(in_WM_STA_IPconfig._sta_static_ip, in_WM_STA_IPconfig._sta_static_gw, in_WM_STA_IPconfig._sta_static_sn); 382 | #endif 383 | } 384 | 385 | /////////////////////////////////////////// 386 | 387 | uint8_t connectMultiWiFi() 388 | { 389 | #if ESP32 390 | // For ESP32, this better be 0 to shorten the connect time 391 | #define WIFI_MULTI_1ST_CONNECT_WAITING_MS 0 392 | #else 393 | // For ESP8266, this better be 2200 to enable connect the 1st time 394 | #define WIFI_MULTI_1ST_CONNECT_WAITING_MS 2200L 395 | #endif 396 | 397 | #define WIFI_MULTI_CONNECT_WAITING_MS 100L 398 | 399 | uint8_t status; 400 | 401 | LOGERROR(F("ConnectMultiWiFi with :")); 402 | 403 | if ( (Router_SSID != "") && (Router_Pass != "") ) 404 | { 405 | LOGERROR3(F("* Flash-stored Router_SSID = "), Router_SSID, F(", Router_Pass = "), Router_Pass ); 406 | } 407 | 408 | for (uint8_t i = 0; i < NUM_WIFI_CREDENTIALS; i++) 409 | { 410 | // Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8) 411 | if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) != "") 412 | && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) ) 413 | { 414 | LOGERROR3(F("* Additional SSID = "), WM_config.WiFi_Creds[i].wifi_ssid, F(", PW = "), WM_config.WiFi_Creds[i].wifi_pw ); 415 | } 416 | } 417 | 418 | LOGERROR(F("Connecting MultiWifi...")); 419 | 420 | WiFi.mode(WIFI_STA); 421 | 422 | #if !USE_DHCP_IP 423 | // New in v1.4.0 424 | configWiFi(WM_STA_IPconfig); 425 | ////// 426 | #endif 427 | 428 | int i = 0; 429 | status = wifiMulti.run(); 430 | delay(WIFI_MULTI_1ST_CONNECT_WAITING_MS); 431 | 432 | while ( ( i++ < 20 ) && ( status != WL_CONNECTED ) ) 433 | { 434 | status = wifiMulti.run(); 435 | 436 | if ( status == WL_CONNECTED ) 437 | break; 438 | else 439 | delay(WIFI_MULTI_CONNECT_WAITING_MS); 440 | } 441 | 442 | if ( status == WL_CONNECTED ) 443 | { 444 | LOGERROR1(F("WiFi connected after time: "), i); 445 | LOGERROR3(F("SSID:"), WiFi.SSID(), F(",RSSI="), WiFi.RSSI()); 446 | LOGERROR3(F("Channel:"), WiFi.channel(), F(",IP address:"), WiFi.localIP() ); 447 | } 448 | else 449 | LOGERROR(F("WiFi not connected")); 450 | 451 | return status; 452 | } 453 | 454 | void heartBeatPrint(void) 455 | { 456 | static int num = 1; 457 | 458 | if (WiFi.status() == WL_CONNECTED) 459 | Serial.print("H"); // H means connected to WiFi 460 | else 461 | Serial.print("F"); // F means not connected to WiFi 462 | 463 | if (num == 80) 464 | { 465 | Serial.println(); 466 | num = 1; 467 | } 468 | else if (num++ % 10 == 0) 469 | { 470 | Serial.print(" "); 471 | } 472 | } 473 | 474 | void check_WiFi(void) 475 | { 476 | if ( (WiFi.status() != WL_CONNECTED) ) 477 | { 478 | Serial.println("\nWiFi lost. Call connectMultiWiFi in loop"); 479 | connectMultiWiFi(); 480 | } 481 | } 482 | 483 | void check_status(void) 484 | { 485 | static ulong checkstatus_timeout = 0; 486 | static ulong checkwifi_timeout = 0; 487 | 488 | static ulong current_millis; 489 | 490 | #define WIFICHECK_INTERVAL 1000L 491 | #define HEARTBEAT_INTERVAL 10000L 492 | 493 | current_millis = millis(); 494 | 495 | // Check WiFi every WIFICHECK_INTERVAL (1) seconds. 496 | if ((current_millis > checkwifi_timeout) || (checkwifi_timeout == 0)) 497 | { 498 | check_WiFi(); 499 | checkwifi_timeout = current_millis + WIFICHECK_INTERVAL; 500 | } 501 | 502 | // Print hearbeat every HEARTBEAT_INTERVAL (10) seconds. 503 | if ((current_millis > checkstatus_timeout) || (checkstatus_timeout == 0)) 504 | { 505 | heartBeatPrint(); 506 | checkstatus_timeout = current_millis + HEARTBEAT_INTERVAL; 507 | } 508 | } 509 | 510 | void loadConfigData() 511 | { 512 | File file = FileFS.open(CONFIG_FILENAME, "r"); 513 | LOGERROR(F("LoadWiFiCfgFile ")); 514 | 515 | memset(&WM_config, 0, sizeof(WM_config)); 516 | 517 | // New in v1.4.0 518 | memset(&WM_STA_IPconfig, 0, sizeof(WM_STA_IPconfig)); 519 | ////// 520 | 521 | if (file) 522 | { 523 | file.readBytes((char *) &WM_config, sizeof(WM_config)); 524 | 525 | // New in v1.4.0 526 | file.readBytes((char *) &WM_STA_IPconfig, sizeof(WM_STA_IPconfig)); 527 | ////// 528 | 529 | file.close(); 530 | LOGERROR(F("OK")); 531 | 532 | // New in v1.4.0 533 | displayIPConfigStruct(WM_STA_IPconfig); 534 | ////// 535 | } 536 | else 537 | { 538 | LOGERROR(F("failed")); 539 | } 540 | } 541 | 542 | void saveConfigData() 543 | { 544 | File file = FileFS.open(CONFIG_FILENAME, "w"); 545 | LOGERROR(F("SaveWiFiCfgFile ")); 546 | 547 | if (file) 548 | { 549 | file.write((uint8_t*) &WM_config, sizeof(WM_config)); 550 | 551 | // New in v1.4.0 552 | file.write((uint8_t*) &WM_STA_IPconfig, sizeof(WM_STA_IPconfig)); 553 | ////// 554 | 555 | file.close(); 556 | LOGERROR(F("OK")); 557 | } 558 | else 559 | { 560 | LOGERROR(F("failed")); 561 | } 562 | } 563 | 564 | void setup() 565 | { 566 | // put your setup code here, to run once: 567 | // initialize the LED digital pin as an output. 568 | pinMode(PIN_LED, OUTPUT); 569 | 570 | Serial.begin(115200); 571 | 572 | while (!Serial); 573 | 574 | delay(200); 575 | 576 | Serial.print("\nStarting ConfigOnMultiReset with MultiResetDetect using " + String(FS_Name)); 577 | Serial.println(" on " + String(ARDUINO_BOARD)); 578 | Serial.println(ESP_WIFIMANAGER_VERSION); 579 | Serial.println(ESP_MULTI_RESET_DETECTOR_VERSION); 580 | 581 | Serial.setDebugOutput(false); 582 | 583 | if (FORMAT_FILESYSTEM) 584 | FileFS.format(); 585 | 586 | // Format FileFS if not yet 587 | #ifdef ESP32 588 | 589 | if (!FileFS.begin(true)) 590 | #else 591 | if (!FileFS.begin()) 592 | #endif 593 | { 594 | Serial.print(FS_Name); 595 | Serial.println(F(" failed! AutoFormatting.")); 596 | 597 | #ifdef ESP8266 598 | FileFS.format(); 599 | #endif 600 | } 601 | 602 | mrd = new MultiResetDetector(MRD_TIMEOUT, MRD_ADDRESS); 603 | 604 | unsigned long startedAt = millis(); 605 | 606 | // New in v1.4.0 607 | initAPIPConfigStruct(WM_AP_IPconfig); 608 | initSTAIPConfigStruct(WM_STA_IPconfig); 609 | ////// 610 | 611 | //Local intialization. Once its business is done, there is no need to keep it around 612 | // Use this to default DHCP hostname to ESP8266-XXXXXX or ESP32-XXXXXX 613 | //ESP_WiFiManager ESP_wifiManager; 614 | // Use this to personalize DHCP hostname (RFC952 conformed) 615 | ESP_WiFiManager ESP_wifiManager("ConfigOnMultiReset"); 616 | 617 | //set custom ip for portal 618 | // New in v1.4.0 619 | ESP_wifiManager.setAPStaticIPConfig(WM_AP_IPconfig); 620 | ////// 621 | 622 | ESP_wifiManager.setMinimumSignalQuality(-1); 623 | 624 | // From v1.0.10 only 625 | // Set config portal channel, default = 1. Use 0 => random channel from 1-13 626 | ESP_wifiManager.setConfigPortalChannel(0); 627 | ////// 628 | 629 | #if !USE_DHCP_IP 630 | // Set (static IP, Gateway, Subnetmask, DNS1 and DNS2) or (IP, Gateway, Subnetmask). New in v1.0.5 631 | // New in v1.4.0 632 | ESP_wifiManager.setSTAStaticIPConfig(WM_STA_IPconfig); 633 | ////// 634 | #endif 635 | 636 | // New from v1.1.1 637 | #if USING_CORS_FEATURE 638 | ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin"); 639 | #endif 640 | 641 | // We can't use WiFi.SSID() in ESP32 as it's only valid after connected. 642 | // SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot 643 | // Have to create a new function to store in EEPROM/SPIFFS for this purpose 644 | Router_SSID = ESP_wifiManager.WiFi_SSID(); 645 | Router_Pass = ESP_wifiManager.WiFi_Pass(); 646 | 647 | //Remove this line if you do not want to see WiFi password printed 648 | Serial.println("Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass); 649 | 650 | // SSID to uppercase 651 | ssid.toUpperCase(); 652 | 653 | // From v1.1.0, Don't permit NULL password 654 | if ( (Router_SSID != "") && (Router_Pass != "") ) 655 | { 656 | LOGERROR3(F("* Add SSID = "), Router_SSID, F(", PW = "), Router_Pass); 657 | wifiMulti.addAP(Router_SSID.c_str(), Router_Pass.c_str()); 658 | 659 | ESP_wifiManager.setConfigPortalTimeout(120); //If no access point name has been previously entered disable timeout. 660 | Serial.println("Got stored Credentials. Timeout 120s for Config Portal"); 661 | } 662 | else 663 | { 664 | Serial.println("Open Config Portal without Timeout: No stored Credentials."); 665 | initialConfig = true; 666 | } 667 | 668 | if (mrd->detectMultiReset()) 669 | { 670 | // MRD, disable timeout. 671 | ESP_wifiManager.setConfigPortalTimeout(0); 672 | 673 | Serial.println("Open Config Portal without Timeout: Multi Reset Detected"); 674 | initialConfig = true; 675 | } 676 | 677 | if (initialConfig) 678 | { 679 | Serial.println("Starting configuration portal."); 680 | digitalWrite(PIN_LED, LED_ON); // turn the LED on by making the voltage LOW to tell us we are in configuration mode. 681 | 682 | //sets timeout in seconds until configuration portal gets turned off. 683 | //If not specified device will remain in configuration mode until 684 | //switched off via webserver or device is restarted. 685 | //ESP_wifiManager.setConfigPortalTimeout(600); 686 | 687 | // Starts an access point 688 | if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), password)) 689 | Serial.println("Not connected to WiFi but continuing anyway."); 690 | else 691 | { 692 | Serial.println("WiFi connected...yeey :)"); 693 | } 694 | 695 | // Stored for later usage, from v1.1.0, but clear first 696 | memset(&WM_config, 0, sizeof(WM_config)); 697 | 698 | for (uint8_t i = 0; i < NUM_WIFI_CREDENTIALS; i++) 699 | { 700 | String tempSSID = ESP_wifiManager.getSSID(i); 701 | String tempPW = ESP_wifiManager.getPW(i); 702 | 703 | if (strlen(tempSSID.c_str()) < sizeof(WM_config.WiFi_Creds[i].wifi_ssid) - 1) 704 | strcpy(WM_config.WiFi_Creds[i].wifi_ssid, tempSSID.c_str()); 705 | else 706 | strncpy(WM_config.WiFi_Creds[i].wifi_ssid, tempSSID.c_str(), sizeof(WM_config.WiFi_Creds[i].wifi_ssid) - 1); 707 | 708 | if (strlen(tempPW.c_str()) < sizeof(WM_config.WiFi_Creds[i].wifi_pw) - 1) 709 | strcpy(WM_config.WiFi_Creds[i].wifi_pw, tempPW.c_str()); 710 | else 711 | strncpy(WM_config.WiFi_Creds[i].wifi_pw, tempPW.c_str(), sizeof(WM_config.WiFi_Creds[i].wifi_pw) - 1); 712 | 713 | // Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8) 714 | if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) != "") 715 | && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) ) 716 | { 717 | LOGERROR3(F("* Add SSID = "), WM_config.WiFi_Creds[i].wifi_ssid, F(", PW = "), WM_config.WiFi_Creds[i].wifi_pw ); 718 | wifiMulti.addAP(WM_config.WiFi_Creds[i].wifi_ssid, WM_config.WiFi_Creds[i].wifi_pw); 719 | } 720 | } 721 | 722 | // New in v1.4.0 723 | ESP_wifiManager.getSTAStaticIPConfig(WM_STA_IPconfig); 724 | displayIPConfigStruct(WM_STA_IPconfig); 725 | ////// 726 | 727 | saveConfigData(); 728 | } 729 | 730 | digitalWrite(PIN_LED, LED_OFF); // Turn led off as we are not in configuration mode. 731 | 732 | startedAt = millis(); 733 | 734 | if (!initialConfig) 735 | { 736 | // Load stored data, the addAP ready for MultiWiFi reconnection 737 | loadConfigData(); 738 | 739 | for (uint8_t i = 0; i < NUM_WIFI_CREDENTIALS; i++) 740 | { 741 | // Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8) 742 | if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) != "") 743 | && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) ) 744 | { 745 | LOGERROR3(F("* Add SSID = "), WM_config.WiFi_Creds[i].wifi_ssid, F(", PW = "), WM_config.WiFi_Creds[i].wifi_pw ); 746 | wifiMulti.addAP(WM_config.WiFi_Creds[i].wifi_ssid, WM_config.WiFi_Creds[i].wifi_pw); 747 | } 748 | } 749 | 750 | if ( WiFi.status() != WL_CONNECTED ) 751 | { 752 | Serial.println("ConnectMultiWiFi in setup"); 753 | 754 | connectMultiWiFi(); 755 | } 756 | } 757 | 758 | Serial.print("After waiting "); 759 | Serial.print((float) (millis() - startedAt) / 1000L); 760 | Serial.print(" secs more in setup(), connection result is "); 761 | 762 | if (WiFi.status() == WL_CONNECTED) 763 | { 764 | Serial.print("connected. Local IP: "); 765 | Serial.println(WiFi.localIP()); 766 | } 767 | else 768 | Serial.println(ESP_wifiManager.getStatus(WiFi.status())); 769 | } 770 | 771 | void loop() 772 | { 773 | // Call the mlti reset detector loop method every so often, 774 | // so that it can recognise when the timeout expires. 775 | // You can also call mrd.stop() when you wish to no longer 776 | // consider the next reset as a mlti reset. 777 | mrd->loop(); 778 | 779 | // put your main code here, to run repeatedly 780 | check_status(); 781 | 782 | } 783 | -------------------------------------------------------------------------------- /examples/checkWaitingMRD/checkWaitingMRD.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | checkWaitingMRD.ino 3 | For ESP8266 / ESP32 boards 4 | 5 | ESP_MultiResetDetector is a library for the ESP8266/Arduino platform 6 | to enable trigger configure mode by resetting ESP32 / ESP8266 multiple times. 7 | 8 | Based on and modified from 9 | 1) DataCute https://github.com/datacute/MultiResetDetector 10 | 2) Khoi Hoang https://github.com/khoih-prog/ESP_MultiResetDetector 11 | 12 | Built by Khoi Hoang https://github.com/khoih-prog/ESP_MultiResetDetector 13 | Licensed under MIT license 14 | *****************************************************************************************************************************/ 15 | 16 | // These defines must be put before #include 17 | // to select where to store MultiResetDetector's variable. 18 | // For ESP32, You must select one to be true (EEPROM or SPIFFS) 19 | // For ESP8266, You must select one to be true (RTC, EEPROM, LITTLEFS or SPIFFS) 20 | // Otherwise, library will use default EEPROM storage 21 | 22 | // This example demonstrates how to use new function waitingForMRD() to signal the stage of MRD 23 | // waitingForMRD() returns true if in MRD_TIMEOUT, false when out of MRD_TIMEOUT 24 | // In this example, LED_BUILTIN will blink in MRD_TIMEOUT period, ON when DR has been detected, OFF otherwise 25 | 26 | #ifdef ESP8266 27 | #define ESP8266_MRD_USE_RTC false //true 28 | #endif 29 | 30 | #define ESP_MRD_USE_LITTLEFS true 31 | #define ESP_MRD_USE_SPIFFS false 32 | #define ESP_MRD_USE_EEPROM false 33 | 34 | // Uncomment to have debug 35 | //#define MULTIRESETDETECTOR_DEBUG true 36 | 37 | // These definitions must be placed before #include to be used 38 | // Otherwise, default values (MRD_TIMES = 3, MRD_TIMEOUT = 10 seconds and MRD_ADDRESS = 0) will be used 39 | // Number of subsequent resets during MRD_TIMEOUT to activate 40 | #define MRD_TIMES 3 41 | 42 | // Number of seconds after reset during which a 43 | // subsequent reset will be considered a multi reset. 44 | #define MRD_TIMEOUT 10 45 | 46 | // RTC/EEPROM Memory Address for the MultiResetDetector to use 47 | #define MRD_ADDRESS 0 48 | 49 | #include //https://github.com/khoih-prog/ESP_MultiResetDetector 50 | 51 | MultiResetDetector* mrd; 52 | 53 | #ifdef ESP32 54 | 55 | // For ESP32 56 | #ifndef LED_BUILTIN 57 | #define LED_BUILTIN 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED 58 | #endif 59 | 60 | #define LED_OFF LOW 61 | #define LED_ON HIGH 62 | 63 | #else 64 | 65 | // For ESP8266 66 | #define LED_ON LOW 67 | #define LED_OFF HIGH 68 | 69 | #endif 70 | 71 | bool MRD_Detected = false; 72 | 73 | void check_status() 74 | { 75 | static ulong checkstatus_timeout = 0; 76 | static bool LEDState = LED_OFF; 77 | 78 | static ulong current_millis; 79 | 80 | #define MRD_CHECK_INTERVAL 500L 81 | 82 | current_millis = millis(); 83 | 84 | // If MRD_Detected, don't need to blink, just keep LED_BUILTIN ON 85 | if ( !MRD_Detected && ((current_millis > checkstatus_timeout) || (checkstatus_timeout == 0)) ) 86 | { 87 | // If in MRD checking loop, blinking the LED_BUILTIN 88 | if ( mrd->waitingForMRD() ) 89 | { 90 | digitalWrite(LED_BUILTIN, LEDState); 91 | 92 | LEDState = !LEDState; 93 | } 94 | else 95 | { 96 | digitalWrite(LED_BUILTIN, LED_OFF); 97 | } 98 | 99 | checkstatus_timeout = current_millis + MRD_CHECK_INTERVAL; 100 | } 101 | } 102 | 103 | void setup() 104 | { 105 | pinMode(LED_BUILTIN, OUTPUT); 106 | 107 | Serial.begin(115200); 108 | 109 | while (!Serial); 110 | 111 | delay(200); 112 | 113 | Serial.print("\nStarting checkWaitingMRD on"); 114 | Serial.println(ARDUINO_BOARD); 115 | 116 | #if ESP_MRD_USE_LITTLEFS 117 | Serial.println(F(" using LittleFS")); 118 | #elif ESP_MRD_USE_SPIFFS 119 | Serial.println(F(" using SPIFFS")); 120 | #else 121 | Serial.println(F(" using EEPROM")); 122 | #endif 123 | 124 | Serial.println(ESP_MULTI_RESET_DETECTOR_VERSION); 125 | 126 | mrd = new MultiResetDetector(MRD_TIMEOUT, MRD_ADDRESS); 127 | 128 | if (mrd->detectMultiReset()) 129 | { 130 | Serial.println("Multi Reset Detected"); 131 | digitalWrite(LED_BUILTIN, LED_ON); 132 | MRD_Detected = true; 133 | } 134 | else 135 | { 136 | Serial.println("No Multi Reset Detected"); 137 | digitalWrite(LED_BUILTIN, LED_OFF); 138 | } 139 | } 140 | 141 | void loop() 142 | { 143 | // Call the double reset detector loop method every so often, 144 | // so that it can recognise when the timeout expires. 145 | // You can also call mrd.stop() when you wish to no longer 146 | // consider the next reset as a double reset. 147 | mrd->loop(); 148 | 149 | check_status(); 150 | } 151 | -------------------------------------------------------------------------------- /examples/minimal/minimal.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | minimal.ino 3 | For ESP8266 / ESP32 boards 4 | 5 | ESP_MultiResetDetector is a library for the ESP8266/Arduino platform 6 | to enable trigger configure mode by resetting ESP32 / ESP8266 multiple times. 7 | 8 | Based on and modified from 9 | 1) DataCute https://github.com/datacute/MultiResetDetector 10 | 2) Khoi Hoang https://github.com/khoih-prog/ESP_MultiResetDetector 11 | 12 | Built by Khoi Hoang https://github.com/khoih-prog/ESP_MultiResetDetector 13 | Licensed under MIT license 14 | *****************************************************************************************************************************/ 15 | 16 | // These defines must be put before #include 17 | // to select where to store MultiResetDetector's variable. 18 | // For ESP32, You must select one to be true (EEPROM or SPIFFS) 19 | // For ESP8266, You must select one to be true (RTC, EEPROM, LITTLEFS or SPIFFS) 20 | // Otherwise, library will use default EEPROM storage 21 | 22 | #ifdef ESP8266 23 | #define ESP8266_MRD_USE_RTC false //true 24 | #endif 25 | 26 | #define ESP_MRD_USE_LITTLEFS true 27 | #define ESP_MRD_USE_SPIFFS false 28 | #define ESP_MRD_USE_EEPROM false 29 | 30 | #define MULTIRESETDETECTOR_DEBUG true //false 31 | 32 | // These definitions must be placed before #include to be used 33 | // Otherwise, default values (MRD_TIMES = 3, MRD_TIMEOUT = 10 seconds and MRD_ADDRESS = 0) will be used 34 | // Number of subsequent resets during MRD_TIMEOUT to activate 35 | #define MRD_TIMES 5 36 | 37 | // Number of seconds after reset during which a 38 | // subsequent reset will be considered a multi reset. 39 | #define MRD_TIMEOUT 10 40 | 41 | // RTC/EEPROM Memory Address for the MultiResetDetector to use 42 | #define MRD_ADDRESS 0 43 | 44 | #include //https://github.com/khoih-prog/ESP_MultiResetDetector 45 | 46 | MultiResetDetector* mrd; 47 | 48 | #ifdef ESP32 49 | 50 | // For ESP32 51 | #ifndef LED_BUILTIN 52 | #define LED_BUILTIN 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED 53 | #endif 54 | 55 | #define LED_OFF LOW 56 | #define LED_ON HIGH 57 | 58 | #else 59 | 60 | // For ESP8266 61 | #define LED_ON LOW 62 | #define LED_OFF HIGH 63 | 64 | #endif 65 | 66 | void setup() 67 | { 68 | pinMode(LED_BUILTIN, OUTPUT); 69 | 70 | Serial.begin(115200); 71 | 72 | while (!Serial); 73 | 74 | delay(200); 75 | 76 | Serial.print(F("\nStarting ESP_MultiResetDetector minimal on ")); 77 | Serial.print(ARDUINO_BOARD); 78 | 79 | #if ESP_MRD_USE_LITTLEFS 80 | Serial.println(F(" using LittleFS")); 81 | #elif ESP_MRD_USE_SPIFFS 82 | Serial.println(F(" using SPIFFS")); 83 | #else 84 | Serial.println(F(" using EEPROM")); 85 | #endif 86 | 87 | Serial.println(ESP_MULTI_RESET_DETECTOR_VERSION); 88 | 89 | mrd = new MultiResetDetector(MRD_TIMEOUT, MRD_ADDRESS); 90 | 91 | if (mrd->detectMultiReset()) 92 | { 93 | Serial.println("Multi Reset Detected"); 94 | digitalWrite(LED_BUILTIN, LED_ON); 95 | } 96 | else 97 | { 98 | Serial.println("No Multi Reset Detected"); 99 | digitalWrite(LED_BUILTIN, LED_OFF); 100 | } 101 | 102 | } 103 | 104 | void loop() 105 | { 106 | // Call the multi reset detector loop method every so often, 107 | // so that it can recognise when the timeout expires. 108 | // You can also call mrd.stop() when you wish to no longer 109 | // consider the next reset as a multi reset. 110 | mrd->loop(); 111 | } 112 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | MultiResetDetector 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | detectMultiReset KEYWORD2 16 | waitingForMRD KEYWORD2 17 | loop KEYWORD2 18 | stop KEYWORD2 19 | 20 | ####################################### 21 | # Instances (KEYWORD2) 22 | ####################################### 23 | 24 | ####################################### 25 | # Constants (LITERAL1) 26 | ####################################### 27 | 28 | ESP_MULTI_RESET_DETECTOR_VERSION LITERAL1 29 | ESP_MULTIRESETDETECTOR_VERSION LITERAL1 30 | 31 | ESP_MULTI_RESET_DETECTOR_VERSION_MAJOR LITERAL1 32 | ESP_MULTI_RESET_DETECTOR_VERSION_MINOR LITERAL1 33 | ESP_MULTI_RESET_DETECTOR_VERSION_PATCH LITERAL1 34 | ESP_MULTI_RESET_DETECTOR_VERSION_INT LITERAL1 35 | 36 | FLAG_DATA_SIZE LITERAL1 37 | EEPROM_SIZE LITERAL1 38 | EEPROM_START LITERAL1 39 | 40 | ESP_MRD_USE_LITTLEFS LITERAL1 41 | ESP_MRD_USE_SPIFFS LITERAL1 42 | FileFS LITERAL1 43 | FS_Name LITERAL1 44 | 45 | MULTIRESETDETECTOR_DEBUG LITERAL1 46 | 47 | MRD_TIMES LITERAL1 48 | MRD_TIMEOUT LITERAL1 49 | MRD_ADDRESS LITERAL1 50 | 51 | USING_INVERTED LITERAL1 52 | MULTIRESETDETECTOR_FLAG_BEGIN LITERAL1 53 | MULTIRESETDETECTOR_FLAG_CLEAR LITERAL1 54 | 55 | MRD_FILENAME LITERAL1 56 | 57 | 58 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ESP_MultiResetDetector", 3 | "version": "1.3.2", 4 | "keywords": "rtc, eeprom, littlefs, spiffs, reset, data, esp32, esp32-c3, esp32-s2, esp32-s3, esp8266, double-reset, multi-reset, detector, double-reset-detector, multi-reset-detector, esp-wifimanager, espasync-wifimanager", 5 | "description": "Library to detect a multi reset within a predetermined time, using RTC Memory, EEPROM, LittleFS or SPIFFS for ESP8266 and ESP32, ESP32_C3, ESP32_S2, ESP32_S3. An alternative start-up mode can be used. One example use is to allow re-configuration of device WiFi credentials", 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_MultiResetDetector" 16 | }, 17 | "homepage": "https://github.com/khoih-prog/ESP_MultiResetDetector", 18 | "export": { 19 | "exclude": [ 20 | "linux", 21 | "extras", 22 | "tests" 23 | ] 24 | }, 25 | "dependencies": 26 | [ 27 | ], 28 | "license": "MIT", 29 | "frameworks": "arduino", 30 | "platforms": [ "espressif32", "espressif8266" ], 31 | "examples": "examples/*/*/*.ino", 32 | "headers": "ESP_MultiResetDetector.h" 33 | } 34 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=ESP_MultiResetDetector 2 | version=1.3.2 3 | author=Khoi Hoang 4 | maintainer=Khoi Hoang 5 | license=MIT 6 | sentence=Library to detect a multi reset within a predetermined time, using RTC Memory, EEPROM, LittleFS or SPIFFS for ESP8266 and ESP32, ESP32_C3, ESP32_S2, ESP32_S3 7 | paragraph=An alternative start-up mode can be used. One example use is to allow re-configuration of device WiFi credentials 8 | category=Device Control 9 | url=https://github.com/khoih-prog/ESP_MultiResetDetector 10 | architectures=esp8266,esp32 11 | includes=ESP_MultiResetDetector.h 12 | 13 | -------------------------------------------------------------------------------- /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 | ; ============================================================ 17 | default_envs = ESP8266 18 | ;default_envs = ESP32 19 | 20 | [env] 21 | ; ============================================================ 22 | ; Serial configuration 23 | ; choose upload speed, serial-monitor speed 24 | ; ============================================================ 25 | upload_speed = 921600 26 | ;upload_port = COM11 27 | ;monitor_speed = 9600 28 | ;monitor_port = COM11 29 | 30 | ; Checks for the compatibility with frameworks and dev/platforms 31 | lib_compat_mode = strict 32 | lib_ldf_mode = chain+ 33 | ;lib_ldf_mode = deep+ 34 | 35 | lib_deps = 36 | ; PlatformIO 4.x 37 | ; LittleFS_esp32@>=1.0.6 38 | ; PlatformIO 5.x 39 | ; lorol/LittleFS_esp32@>=1.0.6 40 | 41 | 42 | build_flags = 43 | ; set your debug output (default=Serial) 44 | -D DEBUG_ESP_PORT=Serial 45 | ; comment the following line to enable WiFi debugging 46 | -D NDEBUG 47 | 48 | [env:ESP8266] 49 | platform = espressif8266 50 | framework = arduino 51 | ; ============================================================ 52 | ; Board configuration 53 | ; choose your board by uncommenting one of the following lines 54 | ; ============================================================ 55 | ;board = gen4iod 56 | ;board = huzzah 57 | ;board = oak 58 | ;board = esp_wroom_02 59 | ;board = espduino 60 | ;board = espectro 61 | ;board = espino 62 | ;board = espresso_lite_v1 63 | ;board = espresso_lite_v2 64 | ;board = esp12e 65 | ;board = esp01_1m 66 | ;board = esp01 67 | ;board = esp07 68 | ;board = esp8285 69 | ;board = heltec_wifi_kit_8 70 | ;board = inventone 71 | ;board = nodemcu 72 | board = nodemcuv2 73 | ;board = modwifi 74 | ;board = phoenix_v1 75 | ;board = phoenix_v2 76 | ;board = sparkfunBlynk 77 | ;board = thing 78 | ;board = thingdev 79 | ;board = esp210 80 | ;board = espinotee 81 | ;board = d1 82 | ;board = d1_mini 83 | ;board = d1_mini_lite 84 | ;board = d1_mini_pro 85 | ;board = wifi_slot 86 | ;board = wifiduino 87 | ;board = wifinfo 88 | ;board = wio_link 89 | ;board = wio_node 90 | ;board = xinabox_cw01 91 | ;board = esp32doit-devkit-v1 92 | 93 | [env:ESP32] 94 | platform = espressif32 95 | framework = arduino 96 | ; ============================================================ 97 | ; Board configuration 98 | ; choose your board by uncommenting one of the following lines 99 | ; ============================================================ 100 | ;board = esp32cam 101 | ;board = alksesp32 102 | ;board = featheresp32 103 | ;board = espea32 104 | ;board = bpi-bit 105 | ;board = d-duino-32 106 | board = esp32doit-devkit-v1 107 | ;board = pocket_32 108 | ;board = fm-devkit 109 | ;board = pico32 110 | ;board = esp32-evb 111 | ;board = esp32-gateway 112 | ;board = esp32-pro 113 | ;board = esp32-poe 114 | ;board = oroca_edubot 115 | ;board = onehorse32dev 116 | ;board = lopy 117 | ;board = lopy4 118 | ;board = wesp32 119 | ;board = esp32thing 120 | ;board = sparkfun_lora_gateway_1-channel 121 | ;board = ttgo-lora32-v1 122 | ;board = ttgo-t-beam 123 | ;board = turta_iot_node 124 | ;board = lolin_d32 125 | ;board = lolin_d32_pro 126 | ;board = lolin32 127 | ;board = wemosbat 128 | ;board = widora-air 129 | ;board = xinabox_cw02 130 | ;board = iotbusio 131 | ;board = iotbusproteus 132 | ;board = nina_w10 133 | -------------------------------------------------------------------------------- /src/ESP_MultiResetDetector.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | ESP_MultiResetDetector.h 3 | For ESP8266 / ESP32 boards 4 | 5 | ESP_MultiResetDetector is a library for the ESP8266/Arduino platform 6 | to enable trigger configure mode by resetting ESP32 / ESP8266 twice. 7 | 8 | Based on and modified from 9 | 1) DataCute https://github.com/datacute/DoubleResetDetector 10 | 2) Khoi Hoang https://github.com/khoih-prog/ESP_DoubleResetDetector 11 | 12 | Built by Khoi Hoang https://github.com/khoih-prog/ESP_MultiResetDetector 13 | Licensed under MIT license 14 | Version: 1.3.2 15 | 16 | Version Modified By Date Comments 17 | ------- ----------- ---------- ----------- 18 | 1.1.1 K Hoang 30/12/2020 Initial coding to support Multiple Reset Detection. Sync with ESP_DoubleResetDetector v1.1.1 19 | 1.1.2 K Hoang 10/10/2021 Update `platform.ini` and `library.json` 20 | 1.2.0 K Hoang 26/11/2021 Auto detect ESP32 core and use either built-in LittleFS or LITTLEFS library 21 | 1.2.1 K Hoang 26/11/2021 Fix compile error for ESP32 core v1.0.5- 22 | 1.3.0 K Hoang 10/02/2022 Add support to new ESP32-S3 23 | 1.3.1 K Hoang 04/03/2022 Add waitingForMRD() function to signal in MRD wating period 24 | 1.3.2 K Hoang 09/09/2022 Fix ESP32 chipID for example ConfigOnMultiReset 25 | *****************************************************************************************************************************/ 26 | 27 | #pragma once 28 | 29 | #ifndef ESP_MultiResetDetector_H 30 | #define ESP_MultiResetDetector_H 31 | 32 | #ifndef MULTIRESETDETECTOR_DEBUG 33 | #define MULTIRESETDETECTOR_DEBUG false 34 | #endif 35 | 36 | #if defined(ARDUINO) && (ARDUINO >= 100) 37 | #include 38 | #else 39 | #include 40 | #endif 41 | 42 | #ifndef ESP_MULTI_RESET_DETECTOR_VERSION 43 | #define ESP_MULTI_RESET_DETECTOR_VERSION "ESP_MultiResetDetector v1.3.2" 44 | 45 | #define ESP_MULTI_RESET_DETECTOR_VERSION_MAJOR 1 46 | #define ESP_MULTI_RESET_DETECTOR_VERSION_MINOR 3 47 | #define ESP_MULTI_RESET_DETECTOR_VERSION_PATCH 2 48 | 49 | #define ESP_MULTI_RESET_DETECTOR_VERSION_INT 1003002 50 | #endif 51 | 52 | #define ESP_MULTIRESETDETECTOR_VERSION ESP_MULTI_RESET_DETECTOR_VERSION 53 | 54 | //#define ESP_MRD_USE_EEPROM false 55 | //#define ESP_MRD_USE_LITTLEFS false 56 | //#define ESP_MRD_USE_SPIFFS false 57 | //#define ESP8266_MRD_USE_RTC false //true 58 | 59 | #ifdef ESP32 60 | #if (!ESP_MRD_USE_EEPROM && !ESP_MRD_USE_SPIFFS && !ESP_MRD_USE_LITTLEFS) 61 | #if (MULTIRESETDETECTOR_DEBUG) 62 | #warning Neither EEPROM, SPIFFS nor LittleFS selected. Default to EEPROM 63 | #endif 64 | 65 | #ifdef ESP_MRD_USE_EEPROM 66 | #undef ESP_MRD_USE_EEPROM 67 | #define ESP_MRD_USE_EEPROM true 68 | #endif 69 | #endif 70 | #endif 71 | 72 | #ifdef ESP8266 73 | #if (!ESP8266_MRD_USE_RTC && !ESP_MRD_USE_EEPROM && !ESP_MRD_USE_SPIFFS && !ESP_MRD_USE_LITTLEFS) 74 | #if (MULTIRESETDETECTOR_DEBUG) 75 | #warning Neither RTC, EEPROM, LITTLEFS nor SPIFFS selected. Default to EEPROM 76 | #endif 77 | 78 | #ifdef ESP_MRD_USE_EEPROM 79 | #undef ESP_MRD_USE_EEPROM 80 | #define ESP_MRD_USE_EEPROM true 81 | #endif 82 | #endif 83 | #endif 84 | 85 | //default to use EEPROM, otherwise, use LITTLEFS (higher priority), then SPIFFS 86 | #if ESP_MRD_USE_EEPROM 87 | #include 88 | 89 | #define FLAG_DATA_SIZE 4 90 | 91 | #ifndef EEPROM_SIZE 92 | #define EEPROM_SIZE 512 93 | #endif 94 | 95 | #ifndef EEPROM_START 96 | #define EEPROM_START 256 97 | #endif 98 | 99 | #elif ( ESP_MRD_USE_LITTLEFS || ESP_MRD_USE_SPIFFS ) 100 | 101 | #include 102 | 103 | #ifdef ESP32 104 | 105 | #if ESP_MRD_USE_LITTLEFS 106 | // Check cores/esp32/esp_arduino_version.h and cores/esp32/core_version.h 107 | //#if ( ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 0) ) //(ESP_ARDUINO_VERSION_MAJOR >= 2) 108 | #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) ) 109 | #if (MULTIRESETDETECTOR_DEBUG) 110 | #warning Using ESP32 Core 1.0.6 or 2.0.0+ 111 | #endif 112 | 113 | // The library has been merged into esp32 core from release 1.0.6 114 | #include 115 | 116 | #define FileFS LittleFS 117 | #define FS_Name "LittleFS" 118 | #else 119 | #if (MULTIRESETDETECTOR_DEBUG) 120 | #warning Using ESP32 Core 1.0.5-. You must install LITTLEFS library 121 | #endif 122 | 123 | // The library has been merged into esp32 core from release 1.0.6 124 | #include // https://github.com/lorol/LITTLEFS 125 | 126 | #define FileFS LITTLEFS 127 | #define FS_Name "LittleFS" 128 | #endif 129 | #else 130 | #include "SPIFFS.h" 131 | // ESP32 core 1.0.4 still uses SPIFFS 132 | #define FileFS SPIFFS 133 | #endif 134 | 135 | #else 136 | // From ESP8266 core 2.7.1 137 | #include 138 | 139 | #if ESP_MRD_USE_LITTLEFS 140 | #define FileFS LittleFS 141 | #else 142 | #define FileFS SPIFFS 143 | #endif 144 | 145 | #endif // #if ESP_MRD_USE_EEPROM 146 | 147 | #define MRD_FILENAME "/mrd.dat" 148 | 149 | #endif //#if ESP_MRD_USE_EEPROM 150 | 151 | /////////////////// 152 | // Default values if not specified in sketch 153 | 154 | #ifndef MRD_TIMES 155 | #define MRD_TIMES 3 156 | #endif 157 | 158 | #ifndef MRD_TIMEOUT 159 | #define MRD_TIMEOUT 10 160 | #endif 161 | 162 | #ifndef MRD_ADDRESS 163 | #define MRD_ADDRESS 0 164 | #endif 165 | 166 | /////////////////// 167 | 168 | // Flag clear to 0xFFFE0001 if no MRD within MRD_TIMEOUT. Flag will increase 1 for each reset within MRD_TIMEOUT 169 | // So MULTIRESETDETECTOR_FLAG_SET is not necessary. 170 | // Will use upper 2 bytes to verify if corrupted data. 171 | 172 | #define USING_INVERTED true 173 | 174 | #if USING_INVERTED 175 | #define MULTIRESETDETECTOR_FLAG_BEGIN 0xFFFE0001 // Used when beginning a new cycle 176 | #define MULTIRESETDETECTOR_FLAG_CLEAR 0x00000000 // Used when data corrupted, such as reformat LittleFS/SPIFFS 177 | #else 178 | #define MULTIRESETDETECTOR_FLAG_BEGIN 0x00010001 // Used when beginning a new cycle 179 | #define MULTIRESETDETECTOR_FLAG_CLEAR 0x00000000 // Used when data corrupted, such as reformat LittleFS/SPIFFS 180 | #endif 181 | 182 | class MultiResetDetector 183 | { 184 | public: 185 | MultiResetDetector(int timeout, int address) 186 | { 187 | mrd_times = MRD_TIMES; 188 | 189 | #if ESP_MRD_USE_EEPROM 190 | #if (MULTIRESETDETECTOR_DEBUG) 191 | Serial.printf("EEPROM size = %d, start = %d\n", EEPROM_SIZE, EEPROM_START); 192 | #endif 193 | 194 | EEPROM.begin(EEPROM_SIZE); 195 | #elif ( ESP_MRD_USE_LITTLEFS || ESP_MRD_USE_SPIFFS ) 196 | // LittleFS / SPIFFS code. Format FileFS if not yet 197 | #ifdef ESP32 198 | 199 | if (!FileFS.begin(true)) 200 | #else 201 | if (!FileFS.begin()) 202 | #endif 203 | { 204 | #if (MULTIRESETDETECTOR_DEBUG) 205 | 206 | #if ESP_MRD_USE_LITTLEFS 207 | Serial.println(F("LittleFS failed!. Please use SPIFFS or EEPROM.")); 208 | #else 209 | Serial.println(F("SPIFFS failed!. Please use LittleFS or EEPROM.")); 210 | #endif 211 | 212 | #endif 213 | multiResetDetectorFlag = MULTIRESETDETECTOR_FLAG = 0; 214 | } 215 | 216 | #else 217 | #ifdef ESP8266 218 | //RTC only for ESP8266 219 | #endif 220 | #endif 221 | 222 | this->timeout = timeout * 1000; 223 | this->address = address; 224 | multiResetDetected = false; 225 | waitingForMultiReset = false; 226 | }; 227 | 228 | bool detectMultiReset() 229 | { 230 | multiResetDetected = detectRecentlyResetFlag(); 231 | 232 | if (multiResetDetected) 233 | { 234 | #if (MULTIRESETDETECTOR_DEBUG) 235 | Serial.printf("multiResetDetected, number of times = %d\n", MRD_TIMES); 236 | #endif 237 | 238 | clearRecentlyResetFlag(); 239 | } 240 | else 241 | { 242 | #if (MULTIRESETDETECTOR_DEBUG) 243 | Serial.printf("No multiResetDetected, number of times = %d\n", (uint16_t) (multiResetDetectorFlag & 0x0000FFFF) ); 244 | #endif 245 | 246 | setRecentlyResetFlag(); 247 | waitingForMultiReset = true; 248 | } 249 | 250 | return multiResetDetected; 251 | 252 | }; 253 | 254 | bool waitingForMRD() 255 | { 256 | return waitingForMultiReset; 257 | } 258 | 259 | void loop() 260 | { 261 | if (waitingForMultiReset && millis() > timeout) 262 | { 263 | #if (MULTIRESETDETECTOR_DEBUG) 264 | Serial.println(F("Stop multiResetDetecting")); 265 | #endif 266 | 267 | stop(); 268 | } 269 | }; 270 | 271 | void stop() 272 | { 273 | clearRecentlyResetFlag(); 274 | waitingForMultiReset = false; 275 | }; 276 | 277 | bool multiResetDetected; 278 | 279 | 280 | private: 281 | 282 | uint32_t MULTIRESETDETECTOR_FLAG; 283 | 284 | unsigned long mrd_times; 285 | 286 | unsigned long timeout; 287 | 288 | int address; 289 | bool waitingForMultiReset; 290 | 291 | uint32_t multiResetDetectorFlag; 292 | 293 | bool readRecentlyResetFlag() 294 | { 295 | #if (ESP_MRD_USE_EEPROM) 296 | EEPROM.get(EEPROM_START, MULTIRESETDETECTOR_FLAG); 297 | multiResetDetectorFlag = MULTIRESETDETECTOR_FLAG; 298 | 299 | #if (MULTIRESETDETECTOR_DEBUG) 300 | Serial.printf("EEPROM Flag read = 0x%08X\n", MULTIRESETDETECTOR_FLAG); 301 | #endif 302 | #elif ( ESP_MRD_USE_LITTLEFS || ESP_MRD_USE_SPIFFS ) 303 | 304 | // LittleFS / SPIFFS code 305 | if (FileFS.exists(MRD_FILENAME)) 306 | { 307 | // if config file exists, load 308 | File file = FileFS.open(MRD_FILENAME, "r"); 309 | 310 | if (!file) 311 | { 312 | #if (MULTIRESETDETECTOR_DEBUG) 313 | Serial.println(F("Loading config file failed")); 314 | #endif 315 | return false; 316 | } 317 | 318 | file.readBytes((char *) &MULTIRESETDETECTOR_FLAG, sizeof(MULTIRESETDETECTOR_FLAG)); 319 | multiResetDetectorFlag = MULTIRESETDETECTOR_FLAG; 320 | 321 | #if (MULTIRESETDETECTOR_DEBUG) 322 | 323 | #if ESP_MRD_USE_LITTLEFS 324 | Serial.printf("LittleFS Flag read = 0x%08X\n", MULTIRESETDETECTOR_FLAG); 325 | #else 326 | Serial.printf("SPIFFS Flag read = 0x%08X\n", MULTIRESETDETECTOR_FLAG); 327 | #endif 328 | 329 | #endif 330 | 331 | file.close(); 332 | } 333 | 334 | #else 335 | #ifdef ESP8266 336 | //RTC only for ESP8266 337 | ESP.rtcUserMemoryRead(address, &multiResetDetectorFlag, sizeof(multiResetDetectorFlag)); 338 | #endif 339 | #endif 340 | 341 | return true; 342 | } 343 | 344 | bool detectRecentlyResetFlag() 345 | { 346 | if (!readRecentlyResetFlag()) 347 | return false; 348 | 349 | //multiResetDetected = (multiResetDetectorFlag == MULTIRESETDETECTOR_FLAG_SET); 350 | // Check lower 2 bytes is > 0 and upper 2 bytes agrees 351 | 352 | #if USING_INVERTED 353 | uint16_t upperBytes = ~(multiResetDetectorFlag >> 16); 354 | #else 355 | uint16_t upperBytes = multiResetDetectorFlag >> 16; 356 | #endif 357 | 358 | uint16_t lowerBytes = multiResetDetectorFlag & 0x0000FFFF; 359 | 360 | #if (MULTIRESETDETECTOR_DEBUG) 361 | Serial.printf("multiResetDetectorFlag = 0x%08X\n", multiResetDetectorFlag); 362 | Serial.printf("lowerBytes = 0x%04X, upperBytes = 0x%04X\n", lowerBytes, upperBytes); 363 | #endif 364 | 365 | if ( ( lowerBytes >= MRD_TIMES ) && ( lowerBytes == upperBytes ) ) 366 | { 367 | multiResetDetected = true; 368 | } 369 | else 370 | { 371 | multiResetDetected = false; 372 | 373 | if (lowerBytes != upperBytes) 374 | { 375 | // To reset if data corrupted 376 | multiResetDetectorFlag = MULTIRESETDETECTOR_FLAG_CLEAR; 377 | #if (MULTIRESETDETECTOR_DEBUG) 378 | Serial.printf("lowerBytes = 0x%04X, upperBytes = 0x%04X\n", lowerBytes, upperBytes); 379 | Serial.println(F("detectRecentlyResetFlag: Data corrupted. Reset to 0")); 380 | #endif 381 | } 382 | } 383 | 384 | return multiResetDetected; 385 | }; 386 | 387 | void setRecentlyResetFlag() 388 | { 389 | // Add 1 every time detecting a reset 390 | // To read first, increase and update 2 checking bytes 391 | readRecentlyResetFlag(); 392 | 393 | #if USING_INVERTED 394 | // 2 lower bytes 395 | MULTIRESETDETECTOR_FLAG = (MULTIRESETDETECTOR_FLAG & 0x0000FFFF) + 1; 396 | 397 | // 2 upper bytes 398 | uint16_t upperBytes = ~MULTIRESETDETECTOR_FLAG; 399 | MULTIRESETDETECTOR_FLAG = (upperBytes << 16) | MULTIRESETDETECTOR_FLAG; 400 | #else 401 | // 2 lower bytes 402 | MULTIRESETDETECTOR_FLAG = (MULTIRESETDETECTOR_FLAG & 0x0000FFFF) + 1; 403 | 404 | // 2 upper bytes 405 | MULTIRESETDETECTOR_FLAG = (MULTIRESETDETECTOR_FLAG << 16) | MULTIRESETDETECTOR_FLAG; 406 | #endif 407 | 408 | multiResetDetectorFlag = MULTIRESETDETECTOR_FLAG; 409 | 410 | #if (ESP_MRD_USE_EEPROM) 411 | EEPROM.put(EEPROM_START, MULTIRESETDETECTOR_FLAG); 412 | EEPROM.commit(); 413 | 414 | #if (MULTIRESETDETECTOR_DEBUG) 415 | delay(1000); 416 | EEPROM.get(EEPROM_START, MULTIRESETDETECTOR_FLAG); 417 | 418 | Serial.printf("SetFlag write = 0x%08X\n", MULTIRESETDETECTOR_FLAG); 419 | #endif 420 | #elif ( ESP_MRD_USE_LITTLEFS || ESP_MRD_USE_SPIFFS ) 421 | // LittleFS / SPIFFS code 422 | File file = FileFS.open(MRD_FILENAME, "w"); 423 | #if (MULTIRESETDETECTOR_DEBUG) 424 | Serial.println(F("Saving config file...")); 425 | #endif 426 | 427 | if (file) 428 | { 429 | file.write((uint8_t *) &MULTIRESETDETECTOR_FLAG, sizeof(MULTIRESETDETECTOR_FLAG)); 430 | file.close(); 431 | #if (MULTIRESETDETECTOR_DEBUG) 432 | Serial.println(F("Saving config file OK")); 433 | #endif 434 | } 435 | else 436 | { 437 | #if (MULTIRESETDETECTOR_DEBUG) 438 | Serial.println(F("Saving config file failed")); 439 | #endif 440 | } 441 | 442 | #else 443 | #ifdef ESP8266 444 | //RTC only for ESP8266 445 | ESP.rtcUserMemoryWrite(address, &multiResetDetectorFlag, sizeof(multiResetDetectorFlag)); 446 | #endif 447 | #endif 448 | }; 449 | 450 | 451 | void clearRecentlyResetFlag() 452 | { 453 | multiResetDetectorFlag = MULTIRESETDETECTOR_FLAG_BEGIN; 454 | MULTIRESETDETECTOR_FLAG = MULTIRESETDETECTOR_FLAG_BEGIN; 455 | 456 | #if (ESP_MRD_USE_EEPROM) 457 | //MULTIRESETDETECTOR_FLAG = MULTIRESETDETECTOR_FLAG_BEGIN; 458 | EEPROM.put(EEPROM_START, MULTIRESETDETECTOR_FLAG); 459 | EEPROM.commit(); 460 | 461 | #if (MULTIRESETDETECTOR_DEBUG) 462 | delay(1000); 463 | EEPROM.get(EEPROM_START, MULTIRESETDETECTOR_FLAG); 464 | 465 | Serial.printf("ClearFlag write = 0x%08X\n", MULTIRESETDETECTOR_FLAG); 466 | #endif 467 | #elif ( ESP_MRD_USE_LITTLEFS || ESP_MRD_USE_SPIFFS ) 468 | // LittleFS / SPIFFS code 469 | File file = FileFS.open(MRD_FILENAME, "w"); 470 | #if (MULTIRESETDETECTOR_DEBUG) 471 | Serial.println(F("Saving config file...")); 472 | #endif 473 | 474 | if (file) 475 | { 476 | file.write((uint8_t *) &MULTIRESETDETECTOR_FLAG, sizeof(MULTIRESETDETECTOR_FLAG)); 477 | file.close(); 478 | #if (MULTIRESETDETECTOR_DEBUG) 479 | Serial.println(F("Saving config file OK")); 480 | #endif 481 | } 482 | else 483 | { 484 | #if (MULTIRESETDETECTOR_DEBUG) 485 | Serial.println(F("Saving config file failed")); 486 | #endif 487 | } 488 | 489 | #else 490 | #ifdef ESP8266 491 | //RTC only for ESP8266 492 | ESP.rtcUserMemoryWrite(address, &multiResetDetectorFlag, sizeof(multiResetDetectorFlag)); 493 | #endif 494 | #endif 495 | }; 496 | }; 497 | #endif // ESP_MultiResetDetector_H 498 | -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------