Compare commits

...
74 Commits
Author SHA1 Message Date
Alex Tudorache ba1aa5496d added more examples,
updated readme
made it compile on older versions
2016-02-01 12:34:29 +02:00
Alex Tudorache 6217ef8e6a bump ver 2016-01-29 08:48:27 +02:00
Alex Tudorache 6e65f39895 added rescan option
added reset option
added info page
precomposed page for A LOT faster page sending
2016-01-25 10:51:25 +02:00
Alex Tudorache 031b7c97bc added ability of returning even if connection fails
added example that resets after configuration if connection is unsuccessful
2016-01-25 09:25:51 +02:00
Alex Tudorache bdc7da660a updated examples 2016-01-24 14:46:20 +02:00
Alex Tudorache f33cb4fb32 added feedback through LED blink example 2016-01-23 11:35:27 +02:00
Alex Tudorache c1038ea371 fixed check for gateway and subnet 2016-01-22 10:28:31 +02:00
tzapu 7b7a94bb51 Merge pull request #76 from ivankravets/patch-4
Update library.json
2016-01-19 17:25:45 +02:00
tzapu f840442549 Merge pull request #77 from ivankravets/patch-3
Delete typo file
2016-01-19 17:25:28 +02:00
Ivan Kravets 1208e03e61 Update library.json 2016-01-19 17:19:49 +02:00
Ivan Kravets 62c621f783 Delete typo file
Sorry, it was my typo. The file should be named as `library.json`
2016-01-19 17:19:27 +02:00
tzapu f83a482fb3 Merge pull request #74 from ivankravets/patch-1
@PlatformIO Library Registry manifest file
hi guys, 
thanks for this, need to get on the bandwagon 
:d
cheers
alex
2016-01-19 17:12:57 +02:00
Ivan Kravets 5691eb1604 @PlatformIO Library Registry manifest file
* This library in Web Registry: http://platformio.org/#!/lib/show/566/WifiManager
* Specification: [library.json](http://docs.platformio.org/en/latest/librarymanager/config.html)
* Library Manager:  http://docs.platformio.org/en/latest/librarymanager/index.html
2016-01-19 16:19:58 +02:00
tzapu 3eaa24b15a Merge pull request #73 from joagyl/patch-1
Fixed typo in  library.json

thank you.

need to get on platform io myself, so many good things i ve heard about it.

could you tell me how you go about using the lib with platform io without submitting it to them?
2016-01-19 15:36:03 +02:00
Joakim G e71b985c0d Fixed typo in library.json
Added missing comma that made the JSON invalid. Noticed this while trying to use the lib in platformio.
2016-01-19 13:51:48 +01:00
Alex Tudorache 823767cb8b char array would cut off strings that were too small in size 2016-01-18 16:34:25 +02:00
Alex Tudorache 0b06e465ce updated example due to memory issues
added more readme
2016-01-18 15:33:45 +02:00
Alex Tudorache 478d291bd2 more readme 2016-01-18 11:37:00 +02:00
Alex Tudorache 13fa4ffa3a added example on how to save static ip to FS config.json
added static ip to config portal, if set
2016-01-18 11:20:15 +02:00
Alex Tudorache e2bbd527d1 added static mode
thanks @jonathanendersby
renamed private variables for more clarity
readme update
2016-01-17 13:27:24 +02:00
Jonathan Endersby 598baf4451 Adding Static IP Support 2016-01-17 07:40:26 +02:00
Alex Tudorache b4e688a543 changed template
fix for web server returning empty pages in latest github
2016-01-14 20:29:58 +02:00
Alex Tudorache 217faa43a3 0.6 release
updated readme
2016-01-13 11:48:52 +02:00
Alex Tudorache f84d973236 change icon and fonts
thanks @markaswift
2016-01-12 23:12:04 +02:00
Alex Tudorache 1351245d09 added signal quality filter 2016-01-11 13:06:12 +02:00
Alex Tudorache 17dd3a4689 merge @riccibitti pull request
on demand better example
thanks
2016-01-11 10:57:40 +02:00
tzapu dfbb819e59 Merge pull request #54 from joe-average/master
Do not show clear text password in form input field
Thank you @joe-average
2016-01-11 09:04:15 +02:00
tzapu ab4f334723 Merge pull request #55 from franklinvv/master
perfect :D
thank you
2016-01-11 08:52:38 +02:00
Franklin van Velthuizen c77e9cbcc9 To show the config portal SSID in the callback, a global reference to the WiFiManager object was needed. To solve this, a pointer to the WiFiManager object is now passed to the callback. The feedback example is edited accordingly. 2016-01-10 00:28:39 +01:00
joe-average 93a7d280f1 Do not show clear text password in form input field 2016-01-09 23:17:58 +01:00
Alberto Ricci Bitti 5587532f01 Manually reverted to current tzapu/master after messing with git commits 2016-01-09 20:11:04 +01:00
Alberto Ricci Bitti 1150a76035 Merge commit '90bac5d5803dec56b53dbb396acf0fb94cfac591'
Conflicts:
	examples/OnDemandConfigPortal/OnDemandConfigPortal.ino
2016-01-09 19:41:49 +01:00
Alberto Ricci Bitti 3a79c6eb99 Merge commit '0780115c7bd861cb8565d40ef1d1e254fe934f28' 2016-01-09 19:08:18 +01:00
Alberto Ricci Bitti 9111febd19 Merge commit '1db01f08e6c3cd627ea5decab31c687dee10c6e6' 2016-01-09 19:07:29 +01:00
Alberto Ricci Bitti 687dc20f3e Changed to make it work on ESP-01 boards
(on ESP-01 pin cannot be checked at setup as its only available pins, gpio0 and gpio2, are shared with the bootloader)
- moved triggering of configuration portal into Arduino's loop() function
- changed pin from 4 to 0 (and made it  #define-able)
2016-01-09 18:52:42 +01:00
Alex Tudorache ec40e32c3f cleanup and get said name as per https://github.com/tzapu/WiFiManager/pull/52
added example of above
2016-01-09 18:54:42 +02:00
Alberto Ricci Bitti 7137082e74 Removed redundant #include 2016-01-09 17:50:09 +01:00
Alex Tudorache 90bac5d580 on demand example fixed 2016-01-09 18:28:23 +02:00
Franklin van Velthuizen 0780115c7b Renamed getConfigurationSSID() to getConfigPortalSSID() 2016-01-09 01:24:48 +01:00
Franklin van Velthuizen 1db01f08e6 Added method getConfigurationSSID(), so the config portal SSID that is created by the ESP8266 can be used in the callback (e.g. for output to a screen) 2016-01-09 01:17:16 +01:00
Alex Tudorache b05dff34b7 added example for on demand config portal
cleanup
2016-01-08 21:04:37 +02:00
Alex Tudorache 0bef4467b3 cleanup
moved ap creation logic to new function so it can be called on demand
implemented changes and suggestions from @riccibitti , thanks

Merge branch 'master' of https://github.com/riccibitti/WiFiManager

# Conflicts:
#	WiFiManager.cpp
#	WiFiManager.h
2016-01-08 18:42:27 +02:00
Alex Tudorache 53489e9c3d resolved conflicts with other libraries that might have used DEBUG_PRINT
thanks @SebiPanther
2016-01-08 13:18:23 +02:00
tzapu 92fe78f213 Merge pull request #51 from tzapu/dev
custom parameters thanks to @rpseng
2016-01-08 12:55:43 +02:00
Alex Tudorache 83177e9c55 a bit of cleanup
removed write on every connect of parameters, now it only writes parameters to FS if config portal is started and connection is successful
2016-01-08 12:51:10 +02:00
Alex Tudorache ab5902e273 added html template to repo 2016-01-08 11:44:50 +02:00
SebiPanther 5dfb2e9ad6 Fixed incompatibilities with DHT Library from https://github.com/adafruit/DHT-sensor-library 2016-01-07 22:18:28 +01:00
Alex Tudorache e0548dc4b4 modified custom parameters feature so user can provide their own storage mechanism
added FS json storage of parameters example
2016-01-07 17:52:29 +02:00
tzapu be2a9737ae Merge pull request #48 from rpseng/master
allow custom parameters by @rpseng 
thank you
2016-01-06 09:56:31 +02:00
Rafael de Pelegrini Soares 2bd9e7dd99 missing load parameters 2016-01-05 23:38:12 -02:00
Rafael de Pelegrini Soares f29d63018c Added support for additional parameters 2016-01-05 23:31:10 -02:00
Rafael de Pelegrini Soares c1d8249b10 Added support for additional parameters 2016-01-05 23:28:56 -02:00
Alex Tudorache 311c80d475 added Boards Manager instructions 2016-01-05 08:28:02 +02:00
Alberto Ricci Bitti 0c04092300 Merge commit '99f37db88ec59cf1b6738f500a8cfeda920b9da7' 2016-01-04 18:31:03 +01:00
Alex Tudorache 99f37db88e Merge branch 'master' of https://github.com/tzapu/WiFiManager 2016-01-04 16:48:33 +02:00
Alex Tudorache 2ad6d0897c changed category
fixed keywords
2016-01-04 16:48:17 +02:00
Alex Tudorache caa808c265 changed category 2016-01-04 16:42:35 +02:00
Alex Tudorache d8683d9f50 updated to 0.5 2016-01-04 16:32:32 +02:00
Alberto Ricci Bitti 807933270b Added "forceAP" parameter to autoconnect (defaulted to false, which leaves previous behaviour unchanged).
If true, starts the configuration portal anyway (in my case I have a physical button to enter configuration)
2016-01-04 13:17:06 +01:00
Alberto Ricci Bitti ead84aea36 Removed unused/commented code 2016-01-04 10:57:43 +01:00
Alberto Ricci Bitti 9fd11f13b6 connectWifi() now returns connection status, making its use more straightforward 2016-01-04 10:44:56 +01:00
Alex Tudorache 1a58897ab4 added some more thanks 2016-01-02 09:49:47 +02:00
tzapu 7ba1f3ada5 Merge pull request #41 from domonetic/patch-4
add library.json
thank you
2016-01-02 09:44:44 +02:00
tzapu e6cbb8fa05 Merge pull request #40 from domonetic/patch-5
add library.properties
THANK YOU, you are amazing
2016-01-02 09:44:00 +02:00
tzapu 81d48d7612 Merge pull request #39 from domonetic/patch-3
add keywords.txt 
THANK YOU GUYS
2016-01-02 09:42:41 +02:00
Maximiliano Duarte ab23ca7b18 change category 2015-12-31 09:53:35 -03:00
Maximiliano Duarte 94eef239eb change space for tabs 2015-12-30 12:49:53 -03:00
Maximiliano Duarte 30f5a220ce add library.properties
to standardize the library and appear in Library Manager
2015-12-30 12:16:42 -03:00
Maximiliano Duarte 9350856d33 add library.json
to standardize the library and appear in Library Manager
2015-12-30 12:14:22 -03:00
Maximiliano Duarte a69c5e2b93 add keywords.txt
to standardize the library and appear in Library Manager
2015-12-30 12:12:57 -03:00
Alex Tudorache 777c2fab1b presentation tweaks 2015-12-28 18:07:02 +02:00
Alex Tudorache ec1a55bffc new padlock icon 2015-12-28 14:32:36 +02:00
Alex Tudorache ffdc117a6e added AP quality
added padlock for secured networks
moved more stuff to PROGMEM
2015-12-27 11:17:29 +02:00
Alex Tudorache 44419e10a2 moved most stuff to PROGMEM
added warning for invalid password
2015-12-23 18:15:58 +02:00
14 changed files with 1465 additions and 337 deletions
+216 -41
View File
@@ -7,7 +7,29 @@ First attempt at a library. Lots more changes and fixes to do. Contributions are
#### This works with the ESP8266 Arduino platform with a recent stable release(2.0.0 or newer) https://github.com/esp8266/Arduino
## How It works
## Contents
- [How it works](#how-it-works)
- [Wishlist](#wishlist)
- [Quick start](#quick-start)
- Installing
- [Through Boards Manager](#install-through-boards-manager)
- [From Github](#checkout-from-github)
- [Using](#using)
- [Documentation](#documentation)
- [Access Point Password](#password-protect-the-configuration-access-point)
- [Callbacks](#callbacks)
- [Timeout](#timeout)
- [On Demand Configuration](#on-demand-configuration-portal)
- [Custom Parameters](#custom-parameters)
- [Custom IP Configuration](#custom-ip-configuration)
- [Filter Low Quality Networks](#filter-networks)
- [Debug Output](#debug)
- [Troubleshooting](#troubleshooting)
- [Releases](#releases)
- [Contributors](#contributions-and-thanks)
## How It Works
- when your ESP starts up, it sets it up in Station mode and tries to connect to a previously saved Access Point
- if this is unsuccessful (or no previous network saved) it moves the ESP into Access Point mode and spins up a DNS and WebServer (default ip 192.168.4.1)
- using any wifi enabled device with a browser (computer, phone, tablet) connect to the newly created Access Point
@@ -15,37 +37,41 @@ First attempt at a library. Lots more changes and fixes to do. Contributions are
- choose one of the access points scanned, enter password, click save
- ESP will try to connect. If successful, it relinquishes control back to your app. If not, reconnect to AP and reconfigure.
## Still left to do
## How It Looks
![ESP8266 WiFi Captive Portal Homepage](http://i.imgur.com/YPvW9eql.png) ![ESP8266 WiFi Captive Portal Configuration](http://i.imgur.com/oicWJ4gl.png)
## Wishlist
- ~~remove dependency on EEPROM library~~
- move HTML Strings to PROGMEM
- cleanup and streamline code
- ~~move HTML Strings to PROGMEM~~
- ~~cleanup and streamline code~~ (although this is ongoing)
- if timeout is set, extend it when a page is fetched in AP mode
- add ability to configure more parameters than ssid/password
- maybe allow setting ip of ESP after reboot
## Releases
#### v0.4 - user contributed changes - Thank you
- added ability to password protect the configuration Access Point
- callback for enter configuration mode
- memory allocation improvements
##### v0.3
- removed the need for EEPROM and works with the 2.0.0 and above stable release of the ESP8266 for Arduino IDE package
- removed restart on save of credentials
- updated examples
##### v0.2
needs the latest staging version (or at least a recent release of the staging version) to work
##### v0.1
works with the staging release ver. 1.6.5-1044-g170995a, built on Aug 10, 2015 of the ESP8266 Arduino library.
- ~~add ability to configure more parameters than ssid/password~~
- ~~maybe allow setting ip of ESP after reboot~~
- ~~add to Arduino Boards Manager~~
- ~~add to PlatformIO~~
- add multiple sets of network credentials
- allow users to customize CSS
## Quick Start
- Make sure you have a recent package of the ESP8266 for Arduino IDE
### Installing
You can either install through the Arduino Boards Manager or checkout the latest changes or a release from github
#### Install through Boards Manager
__Currently version 0.8 works with release 2.0.0 or newer of the [ESP8266 core for Arduino](https://github.com/esp8266/Arduino)__
- in Arduino IDE got to Sketch/Include Library/Manage Libraries
![Manage Libraries](http://i.imgur.com/9BkEBkR.png)
- search for WiFiManager
![WiFiManager package](http://i.imgur.com/18yIai8.png)
- click Install and start [using it](#using)
#### Checkout from github
__Github version works with release 2.0.0 or newer of the [ESP8266 core for Arduino](https://github.com/esp8266/Arduino)__
- Checkout library to your Arduino libraries folder
### Using
- Include in your sketch
```cpp
#include <DNSServer.h>
@@ -53,7 +79,7 @@ works with the staging release ver. 1.6.5-1044-g170995a, built on Aug 10, 2015 o
#include <WiFiManager.h>
```
- Initialise library, in your setup function add
- Initialize library, in your setup function add
```cpp
WiFiManager wifiManager;
```
@@ -75,16 +101,19 @@ wifiManager.autoConnect();
After you write your sketch and start the ESP, it will try to connect to WiFi. If it fails it starts in Access Point mode.
While in AP mode, connect to it then open a browser to the gateway IP, default 192.168.4.1, configure wifi, save and it should reboot and connect.
Also see examples.
Also see [examples](https://github.com/tzapu/WiFiManager/tree/master/examples).
### Password protect the configuration Access Point
## Documentation
#### Password protect the configuration Access Point
You can and should password protect the configuration access point. Simply add the password as a second parameter to `autoConnect`.
A short password seems to have unpredictable results so use one that's around 8 characters or more in length.
```
The guidelines are that a wifi password must consist of 8 to 63 ASCII-encoded characters in the range of 32 to 126 (decimal)
```cpp
wifiManager.autoConnect("AutoConnectAP", "password")
```
### Callbacks
#### Callbacks
##### Enter Config mode
Use this if you need to do something when your device enters configuration mode on failed WiFi connection attempt.
Before `autoConnect()`
@@ -93,13 +122,34 @@ wifiManager.setAPCallback(configModeCallback);
```
`configModeCallback` declaration and example
```cpp
void configModeCallback () {
void configModeCallback (WiFiManager *myWiFiManager) {
Serial.println("Entered config mode");
Serial.println(WiFi.softAPIP());
Serial.println(myWiFiManager->getConfigPortalSSID());
}
```
### Timeout
##### Save settings
This gets called when custom parameters have been set **AND** a connection has been established. Use it to set a flag, so when all the configuration finishes, you can save the extra parameters somewhere.
See [AutoConnectWithFSParameters Example](https://github.com/tzapu/WiFiManager/tree/master/examples/AutoConnectWithFSParameters).
```cpp
wifiManager.setSaveConfigCallback(saveConfigCallback);
```
`saveConfigCallback` declaration and example
```cpp
//flag for saving data
bool shouldSaveConfig = false;
//callback notifying us of the need to save config
void saveConfigCallback () {
Serial.println("Should save config");
shouldSaveConfig = true;
}
```
#### Timeout
If you need to set a timeout so the ESP doesn't hang waiting to be configured, for instance after a power failure, you can add
```cpp
wifiManager.setTimeout(180);
@@ -107,30 +157,155 @@ wifiManager.setTimeout(180);
which will wait 3 minutes (180 seconds). When the time passes, the autoConnect function will return, no matter the outcome.
Check for connection and if it's still not established do whatever is needed (on some modules I restart them to retry, on others I enter deep sleep)
### Debug
#### On Demand Configuration Portal
If you would rather start the configuration portal on demand rather than automatically on a failed connection attempt, then this is for you.
Instead of calling `autoConnect()` which does all the connecting and failover configuration portal setup for you, you need to use `startConfigPortal()`. __Do not use BOTH.__
Example usage
```cpp
void loop() {
// is configuration portal requested?
if ( digitalRead(TRIGGER_PIN) == LOW ) {
WiFiManager wifiManager;
wifiManager.startConfigPortal("OnDemandAP");
Serial.println("connected...yeey :)");
}
}
```
See example for a more complex version. [OnDemandConfigPortal](https://github.com/tzapu/WiFiManager/tree/master/examples/OnDemandConfigPortal)
### Custom Parameters
You can use WiFiManager to collect more parameters than just SSID and password.
This could be helpful for configuring stuff like MQTT host and port, [blynk](http://www.blynk.cc) or [emoncms](http://emoncms.org) tokens, just to name a few.
**You are responsible for saving and loading these custom values.** The library just collects and displays the data for you as a convenience.
Usage scenario would be:
- load values from somewhere (EEPROM/FS) or generate some defaults
- add the custom parameters to WiFiManager using
```cpp
// id/name, placeholder/prompt, default, length
WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40);
wifiManager.addParameter(&custom_mqtt_server);
```
- if connection to AP fails, configuration portal starts and you can set /change the values (or use on demand configuration portal)
- once configuration is done and connection is established [save config callback]() is called
- once WiFiManager returns control to your application, read and save the new values using the `WiFiManagerParameter` object.
```cpp
mqtt_server = custom_mqtt_server.getValue();
```
This feature is a lot more involved than all the others, so here are some examples to fully show how it is done
- Save and load custom parameters to file system in json form [AutoConnectWithFSParameters](https://github.com/tzapu/WiFiManager/tree/master/examples/AutoConnectWithFSParameters)
- *Save and load custom parameters to EEPROM* (not done yet)
### Custom Access Point IP Configuration
This will set your captive portal to a specific IP should you need/want such a feature. Add the following snippet before `autoConnect()`
```cpp
//set custom ip for portal
wifiManager.setAPStaticIPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));
```
### Custom Station (client) Static IP Configuration
This will make use the specified IP configuration instead of using DHCP in station mode.
```cpp
wifiManager.setSTAStaticIPConfig(IPAddress(192,168,0,99), IPAddress(192,168,0,1), IPAddress(255,255,255,0));
```
There are a couple of examples in the examples folder that show you how to set a static IP and even how to configure it through the web configuration portal.
#### Filter Networks
If you would like to filter low signal quality networks you can tell WiFiManager to not show networks below an arbitrary quality %;
```cpp
wifiManager.setMinimumSignalQuality(10);
```
will not show networks under 10% signal quality. If you omit the parameter it defaults to 8%;
#### Debug
Debug is enabled by default on Serial. To disable add before autoConnect
```cpp
wifiManager.setDebugOutput(false);
```
### Custom IP Configuration
This will set your captive portal to a specific IP should you need/want such a feature. Add the following snippet before `autoConnect()`
```cpp
//set custom ip for portal
wifiManager.setAPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));
```
## Troubleshooting
If you get compilation errors, more often than not, you may need to install a newer version of the ESP8266 core for Arduino.
Changes added on 0.8 should make the latest trunk work without compilation errors. Tested down to ESP8266 core 2.0.0. **Please update to version 0.8**
I am trying to keep releases working with release versions of the core, so they can be installed through boards manager, but if you checkout the latest version directly from github, sometimes, the library will only work if you update the ESP8266 core to the latest version because I am using some newly added function.
If you connect to the created configuration Access Point but the configuration portal does not show up, just open a browser and type in the IP of the web portal, by default `192.168.4.1`.
## Releases
#### 0.8
- made it compile on older versions of ESP8266 core as well, tested down to 2.0.0
- added simple example for Custom IP
##### 0.7
- added static IP in station mode
- added example of persisting custom IP to FS config.json
- more option on portal homepage
- added on PlatformIO
##### 0.6
- custom parameters
- prettier
- on demand config portal
- commit #100 :D
##### 0.5
- Added to Arduino Boards Manager - Thanks Max
- moved most stuff to PROGMEM
- added signal quality and a nice little padlock to show which networks are encrypted
##### v0.4 - all of it user contributed changes - Thank you
- added ability to password protect the configuration Access Point
- callback for enter configuration mode
- memory allocation improvements
##### v0.3
- removed the need for EEPROM and works with the 2.0.0 and above stable release of the ESP8266 for Arduino IDE package
- removed restart on save of credentials
- updated examples
##### v0.2
needs the latest staging version (or at least a recent release of the staging version) to work
##### v0.1
works with the staging release ver. 1.6.5-1044-g170995a, built on Aug 10, 2015 of the ESP8266 Arduino library.
### Contributions and thanks
The support and help I got from the community has been nothing short of phenomenal. I can't thank you guys enough. This is my first real attept in developing open source stuff and I must say, now I understand why people are so dedicated to it, it is because of all the wonderful people involved.
__THANK YOU__
[Maximiliano Duarte](https://github.com/domonetic)
[alltheblinkythings](https://github.com/alltheblinkythings)
[Niklas Wall](https://github.com/niklaswall)
[Jakub Piasecki](https://github.com/zaporylie)
[Maximiliano Duarte](https://github.com/domonetic)
[Peter Allan](https://github.com/alwynallan)
[John Little](https://github.com/j0hnlittle)
[markaswift](https://github.com/markaswift)
[franklinvv](https://github.com/franklinvv)
[Alberto Ricci Bitti](https://github.com/riccibitti)
[SebiPanther](https://github.com/SebiPanther)
[jonathanendersby](https://github.com/jonathanendersby)
[walthercarsten](https://github.com/walthercarsten)
Sorry if i have missed anyone.
#### Inspiration
- http://www.esp8266.com/viewtopic.php?f=29&t=2520
Executable → Regular
+416 -199
View File
@@ -1,59 +1,88 @@
/**************************************************************
* WiFiManager is a library for the ESP8266/Arduino platform
* (https://github.com/esp8266/Arduino) to enable easy
* configuration and reconfiguration of WiFi credentials and
* store them in EEPROM.
* inspired by:
* http://www.esp8266.com/viewtopic.php?f=29&t=2520
* https://github.com/chriscook8/esp-arduino-apboot
* https://github.com/esp8266/Arduino/tree/esp8266/hardware/esp8266com/esp8266/libraries/DNSServer/examples/CaptivePortalAdvanced
* Built by AlexT https://github.com/tzapu
* Licensed under MIT license
WiFiManager is a library for the ESP8266/Arduino platform
(https://github.com/esp8266/Arduino) to enable easy
configuration and reconfiguration of WiFi credentials using a Captive Portal
inspired by:
http://www.esp8266.com/viewtopic.php?f=29&t=2520
https://github.com/chriscook8/esp-arduino-apboot
https://github.com/esp8266/Arduino/tree/esp8266/hardware/esp8266com/esp8266/libraries/DNSServer/examples/CaptivePortalAdvanced
Built by AlexT https://github.com/tzapu
Licensed under MIT license
**************************************************************/
#include "WiFiManager.h"
WiFiManagerParameter::WiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length) {
_id = id;
_placeholder = placeholder;
_length = length;
_value = new char[length + 1];
for (int i = 0; i < length; i++) {
_value[i] = 0;
}
if (defaultValue != NULL) {
strncpy(_value, defaultValue, length);
}
}
const char* WiFiManagerParameter::getValue() {
return _value;
}
const char* WiFiManagerParameter::getID() {
return _id;
}
const char* WiFiManagerParameter::getPlaceholder() {
return _placeholder;
}
int WiFiManagerParameter::getValueLength() {
return _length;
}
WiFiManager::WiFiManager() {
}
void WiFiManager::begin() {
begin("NoNetESP");
void WiFiManager::addParameter(WiFiManagerParameter *p) {
_params[_paramsCount] = p;
_paramsCount++;
DEBUG_WM("Adding parameter");
DEBUG_WM(p->getID());
}
void WiFiManager::begin(char const *apName) {
begin(apName,NULL);
}
void WiFiManager::begin(char const *apName, char const *apPasswd) {
void WiFiManager::setupConfigPortal() {
dnsServer.reset(new DNSServer());
server.reset(new ESP8266WebServer(80));
DEBUG_PRINT("");
_apName = apName;
_apPasswd = apPasswd;
DEBUG_WM(F(""));
start = millis();
DEBUG_PRINT("Configuring access point... ");
DEBUG_PRINT(_apName);
if (_apPasswd != NULL)
DEBUG_PRINT(_apPasswd);
//optional soft ip config
if (_ip) {
DEBUG_PRINT("Custom IP/GW/Subnet");
WiFi.softAPConfig(_ip, _gw, _sn);
DEBUG_WM(F("Configuring access point... "));
DEBUG_WM(_apName);
if (_apPassword != NULL) {
if (strlen(_apPassword) < 8 || strlen(_apPassword) > 63) {
// fail passphrase to short or long!
DEBUG_WM(F("Invalid AccessPoint password. Ignoring"));
_apPassword = NULL;
}
DEBUG_WM(_apPassword);
}
if (_apPasswd != NULL)
WiFi.softAP(_apName, _apPasswd);//password option
else
//optional soft ip config
if (_ap_static_ip) {
DEBUG_WM(F("Custom AP IP/GW/Subnet"));
WiFi.softAPConfig(_ap_static_ip, _ap_static_gw, _ap_static_sn);
}
if (_apPassword != NULL) {
WiFi.softAP(_apName, _apPassword);//password option
} else {
WiFi.softAP(_apName);
}
delay(500); // Without delay I've seen the IP address blank
DEBUG_PRINT("AP IP address: ");
DEBUG_PRINT(WiFi.softAPIP());
DEBUG_WM(F("AP IP address: "));
DEBUG_WM(WiFi.softAPIP());
/* Setup the DNS server redirecting all the domains to the apIP */
/* Setup the DNS server redirecting all the domains to the apIP */
dnsServer->setErrorReplyCode(DNSReplyCode::NoError);
dnsServer->start(DNS_PORT, "*", WiFi.softAPIP());
@@ -62,154 +91,155 @@ void WiFiManager::begin(char const *apName, char const *apPasswd) {
server->on("/wifi", std::bind(&WiFiManager::handleWifi, this, true));
server->on("/0wifi", std::bind(&WiFiManager::handleWifi, this, false));
server->on("/wifisave", std::bind(&WiFiManager::handleWifiSave, this));
server->on("/i", std::bind(&WiFiManager::handleInfo, this));
server->on("/r", std::bind(&WiFiManager::handleReset, this));
server->on("/generate_204", std::bind(&WiFiManager::handle204, this)); //Android/Chrome OS captive portal check.
server->on("/fwlink", std::bind(&WiFiManager::handleRoot, this)); //Microsoft captive portal. Maybe not needed. Might be handled by notFound handler.
server->onNotFound (std::bind(&WiFiManager::handleNotFound, this));
server->begin(); // Web server start
DEBUG_PRINT("HTTP server started");
DEBUG_WM(F("HTTP server started"));
/*
String ip = "10.1.2.3";
optionalIPFromString(&_sta_static_ip, ip.c_str());
DEBUG_WM(_sta_static_ip);*/
}
boolean WiFiManager::autoConnect() {
String ssid = "ESP" + String(ESP.getChipId());
return autoConnect(ssid.c_str(),NULL);
return autoConnect(ssid.c_str(), NULL);
}
boolean WiFiManager::autoConnect(char const *apName) {
return autoConnect(apName,NULL);
}
boolean WiFiManager::autoConnect(char const *apName, char const *apPassword) {
DEBUG_WM(F(""));
DEBUG_WM(F("AutoConnect"));
boolean WiFiManager::autoConnect(char const *apName, char const *apPasswd) {
DEBUG_PRINT("");
DEBUG_PRINT("AutoConnect");
// read eeprom for ssid and pass
String ssid = getSSID();
String pass = getPassword();
//use SDK functions to get SSID and pass
//String ssid = WiFi.SSID();
//String pass = WiFi.psk();
//String ssid = getSSID();
//String pass = getPassword();
// attempt to connect; should it fail, fall back to AP
WiFi.mode(WIFI_STA);
connectWifi(ssid, pass);
int s = WiFi.status();
if (s == WL_CONNECTED) {
DEBUG_PRINT("IP Address:");
DEBUG_PRINT(WiFi.localIP());
if (connectWifi("", "") == WL_CONNECTED) {
DEBUG_WM(F("IP Address:"));
DEBUG_WM(WiFi.localIP());
//connected
return true;
}
//not connected
return startConfigPortal(apName, apPassword);
}
boolean WiFiManager::startConfigPortal(char const *apName, char const *apPassword) {
//setup AP
WiFi.mode(WIFI_AP);
//notify we entered AP mode
if( _apcallback != NULL) {
_apcallback();
}
connect = false;
begin(apName,apPasswd);
bool looping = true;
while(timeout == 0 || millis() < start + timeout) {
_apName = apName;
_apPassword = apPassword;
//notify we entered AP mode
if ( _apcallback != NULL) {
_apcallback(this);
}
connect = false;
setupConfigPortal();
while (timeout == 0 || millis() < start + timeout) {
//DNS
dnsServer->processNextRequest();
//HTTP
server->handleClient();
if(connect) {
delay(2000);
DEBUG_PRINT("Connecting to new AP");
if (connect) {
connect = false;
//ssid = getSSID();
//pass = getPassword();
connectWifi(_ssid, _pass);
int s = WiFi.status();
if (s != WL_CONNECTED) {
DEBUG_PRINT("Failed to connect.");
//not connected, should retry everything
//ESP.reset();
//delay(1000);
//return false;
delay(2000);
DEBUG_WM(F("Connecting to new AP"));
// using user-provided _ssid, _pass in place of system-stored ssid and pass
if (connectWifi(_ssid, _pass) != WL_CONNECTED) {
DEBUG_WM(F("Failed to connect."));
} else {
//connected
//connected
WiFi.mode(WIFI_STA);
//notify that configuration has changed and any optional parameters should be saved
if ( _savecallback != NULL) {
//todo: check if any custom parameters actually exist, and check if they really changed maybe
_savecallback();
}
break;
}
if (_shouldBreakAfterConfig) {
//flag set to exit after config after trying to connect
//notify that configuration has changed and any optional parameters should be saved
if ( _savecallback != NULL) {
//todo: check if any custom parameters actually exist, and check if they really changed maybe
_savecallback();
}
break;
}
}
yield();
yield();
}
server.reset();
dnsServer.reset();
return WiFi.status() == WL_CONNECTED;
}
void WiFiManager::connectWifi(String ssid, String pass) {
DEBUG_PRINT("Connecting as wifi client...");
//WiFi.disconnect();
WiFi.begin(ssid.c_str(), pass.c_str());
int WiFiManager::connectWifi(String ssid, String pass) {
DEBUG_WM(F("Connecting as wifi client..."));
// check if we've got static_ip settings, if we do, use those.
if (_sta_static_ip) {
DEBUG_WM(F("Custom STA IP/GW/Subnet"));
WiFi.config(_sta_static_ip, _sta_static_gw, _sta_static_sn);
DEBUG_WM(WiFi.localIP());
}
//check if we have ssid and pass and force those, if not, try with last saved values
if (ssid != "" && pass != "") {
WiFi.begin(ssid.c_str(), pass.c_str());
} else {
DEBUG_WM("Using last saved values, should be faster");
WiFi.begin();
}
int connRes = WiFi.waitForConnectResult();
DEBUG_PRINT ("Connection result: ");
DEBUG_PRINT ( connRes );
DEBUG_WM ("Connection result: ");
DEBUG_WM ( connRes );
return connRes;
}
String WiFiManager::getSSID() {
if (_ssid == "") {
DEBUG_PRINT("Reading EEPROM SSID");
_ssid = WiFi.SSID();//getEEPROMString(0, 32);
DEBUG_PRINT("SSID: ");
DEBUG_PRINT(_ssid);
DEBUG_WM(F("Reading SSID"));
_ssid = WiFi.SSID();
DEBUG_WM(F("SSID: "));
DEBUG_WM(_ssid);
}
return _ssid;
}
String WiFiManager::getPassword() {
if (_pass == "") {
DEBUG_PRINT("Reading EEPROM Password");
_pass = WiFi.psk();//getEEPROMString(32, 64);
DEBUG_PRINT("Password: " + _pass);
//DEBUG_PRINT(_pass);
DEBUG_WM(F("Reading Password"));
_pass = WiFi.psk();
DEBUG_WM("Password: " + _pass);
//DEBUG_WM(_pass);
}
return _pass;
}
/*
String WiFiManager::getEEPROMString(int start, int len) {
EEPROM.begin(512);
delay(10);
String string = "";
for (int i = _eepromStart + start; i < _eepromStart + start + len; i++) {
//DEBUG_PRINT(i);
string += char(EEPROM.read(i));
}
EEPROM.end();
return string;
String WiFiManager::getConfigPortalSSID() {
return _apName;
}
*/
/*
void WiFiManager::setEEPROMString(int start, int len, String string) {
EEPROM.begin(512);
delay(10);
int si = 0;
for (int i = _eepromStart + start; i < _eepromStart + start + len; i++) {
char c;
if (si < string.length()) {
c = string[si];
//DEBUG_PRINT("Wrote: ");
//DEBUG_PRINT(c);
} else {
c = 0;
}
EEPROM.write(i, c);
si++;
}
EEPROM.end();
DEBUG_PRINT("Wrote " + string);
}*/
String WiFiManager::urldecode(const char *src)
{
@@ -248,10 +278,10 @@ String WiFiManager::urldecode(const char *src)
}
void WiFiManager::resetSettings() {
//need to call it only after lib has been started with autoConnect or begin
DEBUG_PRINT("settings invalidated");
WiFi.disconnect();
delay(200);
DEBUG_WM(F("settings invalidated"));
DEBUG_WM(F("THIS MAY CAUSE AP NOT TO START UP PROPERLY. YOU NEED TO COMMENT IT OUT AFTER ERASING THE DATA."));
WiFi.disconnect(true);
//delay(200);
}
void WiFiManager::setTimeout(unsigned long seconds) {
@@ -262,118 +292,289 @@ void WiFiManager::setDebugOutput(boolean debug) {
_debug = debug;
}
void WiFiManager::setAPConfig(IPAddress ip, IPAddress gw, IPAddress sn) {
_ip = ip;
_gw = gw;
_sn = sn;
void WiFiManager::setAPStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn) {
_ap_static_ip = ip;
_ap_static_gw = gw;
_ap_static_sn = sn;
}
void WiFiManager::setSTAStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn) {
_sta_static_ip = ip;
_sta_static_gw = gw;
_sta_static_sn = sn;
}
void WiFiManager::setMinimumSignalQuality(int quality) {
_minimumQuality = quality;
}
void WiFiManager::setBreakAfterConfig(boolean shouldBreak) {
_shouldBreakAfterConfig = shouldBreak;
}
/** Handle root or redirect to captive portal */
void WiFiManager::handleRoot() {
DEBUG_PRINT("Handle root");
DEBUG_WM(F("Handle root"));
if (captivePortal()) { // If caprive portal redirect instead of displaying the page.
return;
}
server->sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
server->sendHeader("Pragma", "no-cache");
server->sendHeader("Expires", "-1");
server->send(200, "text/html", ""); // Empty content inhibits Content-length header so we have to close the socket ourselves.
String page = FPSTR(HTTP_HEAD);
page.replace("{v}", "Options");
page += FPSTR(HTTP_SCRIPT);
page += FPSTR(HTTP_STYLE);
page += FPSTR(HTTP_HEAD_END);
page += "<h1>";
page += _apName;
page += "</h1>";
page += F("<h3>WiFiManager</h3>");
page += FPSTR(HTTP_PORTAL_OPTIONS);
page += FPSTR(HTTP_END);
String head = HTTP_HEAD;
head.replace("{v}", "Options");
server->sendContent(head);
server->sendContent(HTTP_SCRIPT);
server->sendContent(HTTP_STYLE);
server->sendContent(HTTP_HEAD_END);
server->sendContent(
"<form action=\"/wifi\" method=\"get\"><button>Configure WiFi</button></form><br/>"
);
server->sendContent(
"<form action=\"/0wifi\" method=\"get\"><button>Configure WiFi (No Scan)</button></form>"
);
server->sendContent(HTTP_END);
server->send(200, "text/html", page);
server->client().stop(); // Stop is needed because we sent no content length
}
/** Wifi config page handler */
void WiFiManager::handleWifi(bool scan) {
void WiFiManager::handleWifi(boolean scan) {
server->sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
server->sendHeader("Pragma", "no-cache");
server->sendHeader("Expires", "-1");
server->setContentLength(CONTENT_LENGTH_UNKNOWN);
server->send(200, "text/html", ""); // Empty content inhibits Content-length header so we have to close the socket ourselves.
server->setContentLength(CONTENT_LENGTH_UNKNOWN);
String head = HTTP_HEAD;
String head = FPSTR(HTTP_HEAD);
head.replace("{v}", "Config ESP");
server->sendContent(head);
server->sendContent(HTTP_SCRIPT);
server->sendContent(HTTP_STYLE);
server->sendContent(HTTP_HEAD_END);
server->sendContent_P(HTTP_SCRIPT);
server->sendContent_P(HTTP_STYLE);
server->sendContent_P(HTTP_HEAD_END);
if (scan) {
int n = WiFi.scanNetworks();
DEBUG_PRINT("Scan done");
DEBUG_WM(F("Scan done"));
if (n == 0) {
DEBUG_PRINT("No networks found");
server->sendContent("<div>No networks found. Refresh to scan again.</div>");
DEBUG_WM(F("No networks found"));
server->sendContent("No networks found. Refresh to scan again.");
}
else {
for (int i = 0; i < n; ++i)
{
DEBUG_PRINT(WiFi.SSID(i));
DEBUG_PRINT(WiFi.RSSI(i));
String item = HTTP_ITEM;
item.replace("{v}", WiFi.SSID(i));
server->sendContent(item);
yield();
DEBUG_WM(WiFi.SSID(i));
DEBUG_WM(WiFi.RSSI(i));
int quality = getRSSIasQuality(WiFi.RSSI(i));
if (_minimumQuality == -1 || _minimumQuality < quality) {
String item = FPSTR(HTTP_ITEM);
String rssiQ;
rssiQ += quality;
item.replace("{v}", WiFi.SSID(i));
item.replace("{r}", rssiQ);
if (WiFi.encryptionType(i) != ENC_TYPE_NONE) {
item.replace("{i}", FPSTR(HTTP_ITEM_PADLOCK));
} else {
item.replace("{i}", "");
}
//DEBUG_WM(item);
server->sendContent(item);
delay(0);
} else {
DEBUG_WM(F("Skipping due to quality"));
}
}
server->sendContent("<br/>");
}
}
server->sendContent(HTTP_FORM);
server->sendContent(HTTP_END);
server->sendContent_P(HTTP_FORM_START);
char parLength[2];
// add the extra parameters to the form
for (int i = 0; i < _paramsCount; i++) {
if (_params[i] == NULL) {
break;
}
String pitem = FPSTR(HTTP_FORM_PARAM);
pitem.replace("{i}", _params[i]->getID());
pitem.replace("{n}", _params[i]->getID());
pitem.replace("{p}", _params[i]->getPlaceholder());
snprintf(parLength, 2, "%d", _params[i]->getValueLength());
pitem.replace("{l}", parLength);
pitem.replace("{v}", _params[i]->getValue());
server->sendContent(pitem);
}
if (_params[0] != NULL) {
server->sendContent_P("<br/>");
}
if (_sta_static_ip) {
String item = FPSTR(HTTP_FORM_PARAM);
item.replace("{i}", "ip");
item.replace("{n}", "ip");
item.replace("{p}", "Static IP");
item.replace("{l}", "15");
item.replace("{v}", _sta_static_ip.toString());
server->sendContent(item);
item = FPSTR(HTTP_FORM_PARAM);
item.replace("{i}", "gw");
item.replace("{n}", "gw");
item.replace("{p}", "Static Gateway");
item.replace("{l}", "15");
item.replace("{v}", _sta_static_gw.toString());
server->sendContent(item);
item = FPSTR(HTTP_FORM_PARAM);
item.replace("{i}", "sn");
item.replace("{n}", "sn");
item.replace("{p}", "Subnet");
item.replace("{l}", "15");
item.replace("{v}", _sta_static_sn.toString());
server->sendContent(item);
server->sendContent_P("<br/>");
}
server->sendContent_P(HTTP_FORM_END);
server->sendContent_P(HTTP_SCAN_LINK);
server->sendContent_P(HTTP_END);
server->client().stop();
DEBUG_PRINT("Sent config page");
DEBUG_WM(F("Sent config page"));
}
/** Handle the WLAN save form and redirect to WLAN config page again */
void WiFiManager::handleWifiSave() {
DEBUG_PRINT("WiFi save");
DEBUG_WM(F("WiFi save"));
//SAVE/connect here
_ssid = urldecode(server->arg("s").c_str());
_pass = urldecode(server->arg("p").c_str());
//parameters
for (int i = 0; i < _paramsCount; i++) {
if (_params[i] == NULL) {
break;
}
//read parameter
String value = urldecode(server->arg(_params[i]->getID()).c_str());
//store it in array
value.toCharArray(_params[i]->_value, _params[i]->_length);
DEBUG_WM(F("Parameter"));
DEBUG_WM(_params[i]->getID());
DEBUG_WM(value);
}
if (server->arg("ip") != "") {
DEBUG_WM(F("static ip"));
DEBUG_WM(server->arg("ip"));
//_sta_static_ip.fromString(server->arg("ip"));
String ip = server->arg("ip");
optionalIPFromString(&_sta_static_ip, ip.c_str());
}
if (server->arg("gw") != "") {
DEBUG_WM(F("static gateway"));
DEBUG_WM(server->arg("gw"));
String gw = server->arg("gw");
optionalIPFromString(&_sta_static_gw, gw.c_str());
}
if (server->arg("sn") != "") {
DEBUG_WM(F("static netmask"));
DEBUG_WM(server->arg("sn"));
String sn = server->arg("sn");
optionalIPFromString(&_sta_static_sn, sn.c_str());
}
server->sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
server->sendHeader("Pragma", "no-cache");
server->sendHeader("Expires", "-1");
server->setContentLength(CONTENT_LENGTH_UNKNOWN);
server->send(200, "text/html", ""); // Empty content inhibits Content-length header so we have to close the socket ourselves.
String head = HTTP_HEAD;
String head = FPSTR(HTTP_HEAD);
head.replace("{v}", "Credentials Saved");
server->sendContent(head);
server->sendContent(HTTP_SCRIPT);
server->sendContent(HTTP_STYLE);
server->sendContent(HTTP_HEAD_END);
server->sendContent(HTTP_SAVED);
server->sendContent_P(HTTP_SCRIPT);
server->sendContent_P(HTTP_STYLE);
server->sendContent_P(HTTP_HEAD_END);
server->sendContent(HTTP_END);
server->sendContent_P(HTTP_SAVED);
server->sendContent_P(HTTP_END);
server->client().stop();
DEBUG_PRINT("Sent wifi save page");
DEBUG_WM(F("Sent wifi save page"));
connect = true; //signal ready to connect/reset
}
/** Handle the info page */
void WiFiManager::handleInfo() {
DEBUG_WM(F("Info"));
String page = FPSTR(HTTP_HEAD);
page.replace("{v}", "Info");
page += FPSTR(HTTP_SCRIPT);
page += FPSTR(HTTP_STYLE);
page += FPSTR(HTTP_HEAD_END);
page += F("<dl>");
page += F("<dt>Chip ID</dt><dd>");
page += ESP.getChipId();
page += F("</dd>");
page += F("<dt>Flash Chip ID</dt><dd>");
page += ESP.getFlashChipId();
page += F("</dd>");
page += F("<dt>Flash Size</dt><dd>");
page += ESP.getFlashChipSize();
page += F(" bytes</dd>");
page += F("<dt>Soft AP IP</dt><dd>");
page += WiFi.softAPIP().toString();
page += F("</dd>");
page += F("<dt>Soft AP MAC</dt><dd>");
page += WiFi.softAPmacAddress();
page += F("</dd>");
page += F("<dt>Station MAC</dt><dd>");
page += WiFi.macAddress();
page += F("</dd>");
page += F("</dl>");
page += FPSTR(HTTP_END);
server->send(200, "text/html", page);
DEBUG_WM(F("Sent info page"));
}
/** Handle the reset page */
void WiFiManager::handleReset() {
DEBUG_WM(F("Reset"));
String page = FPSTR(HTTP_HEAD);
page.replace("{v}", "Info");
page += FPSTR(HTTP_SCRIPT);
page += FPSTR(HTTP_STYLE);
page += FPSTR(HTTP_HEAD_END);
page += F("Module will reset in a few seconds.");
page += FPSTR(HTTP_END);
server->send(200, "text/html", page);
DEBUG_WM(F("Sent reset page"));
delay(5000);
ESP.reset();
delay(2000);
}
void WiFiManager::handle204() {
DEBUG_PRINT("204 No Response");
DEBUG_WM(F("204 No Response"));
server->sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
server->sendHeader("Pragma", "no-cache");
server->sendHeader("Expires", "-1");
@@ -406,7 +607,7 @@ void WiFiManager::handleNotFound() {
/** Redirect to captive portal if we got a request for another domain. Return true in that case so the page handler do not try to handle the request again. */
boolean WiFiManager::captivePortal() {
if (!isIp(server->hostHeader()) ) {
DEBUG_PRINT("Request redirected to captive portal");
DEBUG_WM(F("Request redirected to captive portal"));
server->sendHeader("Location", String("http://") + toStringIp(server->client().localIP()), true);
server->send ( 302, "text/plain", ""); // Empty content inhibits Content-length header so we have to close the socket ourselves.
server->client().stop(); // Stop is needed because we sent no content length
@@ -416,21 +617,37 @@ boolean WiFiManager::captivePortal() {
}
//start up config portal callback
void WiFiManager::setAPCallback( void (*func)(void) ) {
void WiFiManager::setAPCallback( void (*func)(WiFiManager* myWiFiManager) ) {
_apcallback = func;
}
template <typename Generic>
void WiFiManager::DEBUG_PRINT(Generic text) {
if(_debug) {
Serial.print("*WM: ");
Serial.println(text);
}
//start up save config callback
void WiFiManager::setSaveConfigCallback( void (*func)(void) ) {
_savecallback = func;
}
template <typename Generic>
void WiFiManager::DEBUG_WM(Generic text) {
if (_debug) {
Serial.print("*WM: ");
Serial.println(text);
}
}
int WiFiManager::getRSSIasQuality(int RSSI) {
int quality = 0;
if (RSSI <= -100) {
quality = 0;
} else if (RSSI >= -50) {
quality = 100;
} else {
quality = 2 * (RSSI + 100);
}
return quality;
}
/** Is this an IP? */
boolean WiFiManager::isIp(String str) {
Executable → Regular
+149 -94
View File
@@ -1,116 +1,171 @@
/**************************************************************
* WiFiManager is a library for the ESP8266/Arduino platform
* (https://github.com/esp8266/Arduino) to enable easy
* configuration and reconfiguration of WiFi credentials and
* store them in EEPROM.
* inspired by http://www.esp8266.com/viewtopic.php?f=29&t=2520
* https://github.com/chriscook8/esp-arduino-apboot
* Built by AlexT https://github.com/tzapu
* Licensed under MIT license
WiFiManager is a library for the ESP8266/Arduino platform
(https://github.com/esp8266/Arduino) to enable easy
configuration and reconfiguration of WiFi credentials using a Captive Portal
inspired by:
http://www.esp8266.com/viewtopic.php?f=29&t=2520
https://github.com/chriscook8/esp-arduino-apboot
https://github.com/esp8266/Arduino/tree/esp8266/hardware/esp8266com/esp8266/libraries/DNSServer/examples/CaptivePortalAdvanced
Built by AlexT https://github.com/tzapu
Licensed under MIT license
**************************************************************/
#ifndef WiFiManager_h
#define WiFiManager_h
#include <ESP8266WiFi.h>
//#include <EEPROM.h>
//#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <DNSServer.h>
#include <memory>
class WiFiManager
{
public:
WiFiManager();
boolean autoConnect();
boolean autoConnect(char const *apName);
boolean autoConnect(char const *apName, char const *apPasswd);
String getSSID();
String getPassword();
const char HTTP_200[] PROGMEM = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
const char HTTP_HEAD[] PROGMEM = "<!DOCTYPE html><html lang=\"en\"><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\"/><title>{v}</title>";
const char HTTP_STYLE[] PROGMEM = "<style>div,input{padding:5px;font-size:1em;} input{width:95%;} body{text-align:center;font-family:verdana;} button{border:0;border-radius:0.3rem;background-color:#1fa3ec;color:#fff;line-height:2.4rem;font-size:1.2rem;width:100%;}</style>";
const char HTTP_SCRIPT[] PROGMEM = "<script>function c(l){document.getElementById('s').value=l.innerText||l.textContent;document.getElementById('p').focus();}</script>";
const char HTTP_HEAD_END[] PROGMEM = "</head><body><div style='text-align: left; display: inline-block;'>";
const char HTTP_PORTAL_OPTIONS[] PROGMEM = "<form action=\"/wifi\" method=\"get\"><button>Configure WiFi</button></form><br/><form action=\"/0wifi\" method=\"get\"><button>Configure WiFi (No Scan)</button></form><br/><form action=\"/i\" method=\"get\"><button>Info</button></form><br/><form action=\"/r\" method=\"post\"><button>Reset</button></form>";
const char HTTP_ITEM[] PROGMEM = "<div><a href='#' onclick='c(this)'>{v}</a> {r}% {i}</div>";
const char HTTP_ITEM_PADLOCK[] PROGMEM = "<img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAALVBMVEX///8EBwfBwsLw8PAzNjaCg4NTVVUjJiZDRUUUFxdiZGSho6OSk5Pg4eFydHTCjaf3AAAAZElEQVQ4je2NSw7AIAhEBamKn97/uMXEGBvozkWb9C2Zx4xzWykBhFAeYp9gkLyZE0zIMno9n4g19hmdY39scwqVkOXaxph0ZCXQcqxSpgQpONa59wkRDOL93eAXvimwlbPbwwVAegLS1HGfZAAAAABJRU5ErkJggg==' width='13px'/>";
const char HTTP_FORM_START[] PROGMEM = "<form method='get' action='wifisave'><input id='s' name='s' length=32 placeholder='SSID'><br/><input id='p' name='p' length=64 type='password' placeholder='password'><br/>";
const char HTTP_FORM_PARAM[] PROGMEM = "<br/><input id='{i}' name='{n}' length={l} placeholder='{p}' value='{v}'>";
const char HTTP_FORM_END[] PROGMEM = "<br/><button type='submit'>save</button></form>";
const char HTTP_SCAN_LINK[] PROGMEM = "<br/><div style=\"text-align: center\"><a href=\"/wifi\">Scan</a></div>";
void resetSettings();
//for convenience
String urldecode(const char*);
const char HTTP_SAVED[] PROGMEM = "<div>Credentials Saved<br />Trying to connect ESP to network.<br />If it fails reconnect to AP to try again</div>";
const char HTTP_END[] PROGMEM = "</div></body></html>";
//sets timeout before webserver loop ends and exits even if there has been no setup.
//usefully for devices that failed to connect at some point and got stuck in a webserver loop
//in seconds
void setTimeout(unsigned long seconds);
void setDebugOutput(boolean debug);
#define WIFI_MANAGER_MAX_PARAMS 10
//sets a custom ip /gateway /subnet configuration
void setAPConfig(IPAddress ip, IPAddress gw, IPAddress sn);
void setAPCallback( void (*func)(void) );
private:
std::unique_ptr<DNSServer> dnsServer;
std::unique_ptr<ESP8266WebServer> server;
class WiFiManagerParameter {
public:
WiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length);
const int WM_DONE = 0;
const int WM_WAIT = 10;
const String HTTP_404 = "HTTP/1.1 404 Not Found\r\n\r\n";
const String HTTP_200 = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
const String HTTP_HEAD = "<!DOCTYPE html><html lang=\"en\"><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/><title>{v}</title>";
const String HTTP_STYLE = "<style>div,input {margin-bottom: 5px;} body{width:200px;display:block;margin-left:auto;margin-right:auto;} button{padding:0.75rem 1rem;border:0;border-radius:0.317rem;background-color:#1fa3ec;color:#fff;line-height:1.5;cursor:pointer;}</style>";
const String HTTP_SCRIPT = "<script>function c(l){document.getElementById('s').value=l.innerText||l.textContent;document.getElementById('p').focus();}</script>";
const String HTTP_HEAD_END = "</head><body>";
const String HTTP_ITEM = "<div><a href='#' onclick='c(this)'>{v}</a></div>";
const String HTTP_FORM = "<form method='get' action='wifisave'><input id='s' name='s' length=32 placeholder='SSID'><input id='p' name='p' length=64 placeholder='password'><br/><button type='submit'>save</button></form>";
const String HTTP_SAVED = "<div>Credentials Saved<br />Trying to connect ESP to network.<br />If it fails reconnect to AP to try again</div>";
const String HTTP_END = "</body></html>";
//const char HTTP_END[] PROGMEM = R"=====(
//</body></html>
//)=====";
const char *getID();
const char *getValue();
const char *getPlaceholder();
int getValueLength();
private:
const char *_id;
const char *_placeholder;
char *_value;
int _length;
void begin();
void begin(char const *apName);
void begin(char const *apName, char const *apPasswd);
int _eepromStart;
const char* _apName = "no-net";
const char* _apPasswd = "no-net";
String _ssid = "";
String _pass = "";
unsigned long timeout = 0;
unsigned long start = 0;
IPAddress _ip;
IPAddress _gw;
IPAddress _sn;
String getEEPROMString(int start, int len);
void setEEPROMString(int start, int len, String string);
bool keepLooping = true;
int status = WL_IDLE_STATUS;
void connectWifi(String ssid, String pass);
void handleRoot();
void handleWifi(bool scan);
void handleWifiSave();
void handleNotFound();
void handle204();
boolean captivePortal();
// DNS server
const byte DNS_PORT = 53;
boolean isIp(String str);
String toStringIp(IPAddress ip);
boolean connect;
boolean _debug = true;
void (*_apcallback)(void) = NULL;
template <typename Generic>
void DEBUG_PRINT(Generic text);
friend class WiFiManager;
};
class WiFiManager
{
public:
WiFiManager();
boolean autoConnect();
boolean autoConnect(char const *apName, char const *apPassword = NULL);
//if you want to always start the config portal, without trying to connect first
boolean startConfigPortal(char const *apName, char const *apPassword = NULL);
String getSSID();
String getPassword();
// get the AP name of the config portal, so it can be used in the callback
String getConfigPortalSSID();
void resetSettings();
//for convenience
String urldecode(const char*);
//sets timeout before webserver loop ends and exits even if there has been no setup.
//usefully for devices that failed to connect at some point and got stuck in a webserver loop
//in seconds
void setTimeout(unsigned long seconds);
void setDebugOutput(boolean debug);
//defaults to not showing anything under 8% signal quality if called
void setMinimumSignalQuality(int quality = 8);
//sets a custom ip /gateway /subnet configuration
void setAPStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn);
//sets config for a static IP
void setSTAStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn);
//called when AP mode and config portal is started
void setAPCallback( void (*func)(WiFiManager*) );
//called when settings have been changed and connection was successful
void setSaveConfigCallback( void (*func)(void) );
//adds a custom parameter
void addParameter(WiFiManagerParameter *p);
//if this is set, it will exit after config, even if connection is unsucessful.
void setBreakAfterConfig(boolean shouldBreak);
private:
std::unique_ptr<DNSServer> dnsServer;
std::unique_ptr<ESP8266WebServer> server;
const int WM_DONE = 0;
const int WM_WAIT = 10;
//const String HTTP_HEAD = "<!DOCTYPE html><html lang=\"en\"><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/><title>{v}</title>";
void setupConfigPortal();
int _eepromStart;
const char* _apName = "no-net";
const char* _apPassword = NULL;
String _ssid = "";
String _pass = "";
unsigned long timeout = 0;
unsigned long start = 0;
IPAddress _ap_static_ip;
IPAddress _ap_static_gw;
IPAddress _ap_static_sn;
IPAddress _sta_static_ip;
IPAddress _sta_static_gw;
IPAddress _sta_static_sn;
int _paramsCount = 0;
int _minimumQuality = -1;
boolean _shouldBreakAfterConfig = false;
//String getEEPROMString(int start, int len);
//void setEEPROMString(int start, int len, String string);
int status = WL_IDLE_STATUS;
int connectWifi(String ssid, String pass);
void handleRoot();
void handleWifi(boolean scan);
void handleWifiSave();
void handleInfo();
void handleReset();
void handleNotFound();
void handle204();
boolean captivePortal();
// DNS server
const byte DNS_PORT = 53;
//helpers
int getRSSIasQuality(int RSSI);
boolean isIp(String str);
String toStringIp(IPAddress ip);
boolean connect;
boolean _debug = true;
void (*_apcallback)(WiFiManager*) = NULL;
void (*_savecallback)(void) = NULL;
WiFiManagerParameter* _params[WIFI_MANAGER_MAX_PARAMS];
template <typename Generic>
void DEBUG_WM(Generic text);
template <class T>
auto optionalIPFromString(T *obj, const char *s) -> decltype( obj->fromString(s) ) {
return obj->fromString(s);
}
auto optionalIPFromString(...) -> bool {
DEBUG_WM("NO fromString METHOD ON IPAddress, you need ESP8266 core 2.1.0 or newer for Custom IP configuration to work.");
return false;
}
};
#endif
@@ -0,0 +1,156 @@
#include <FS.h> //this needs to be first, or it all crashes and burns...
#include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
#include <ArduinoJson.h> //https://github.com/bblanchon/ArduinoJson
//define your default values here, if there are different values in config.json, they are overwritten.
char mqtt_server[40];
char mqtt_port[6] = "8080";
char blynk_token[34] = "YOUR_BLYNK_TOKEN";
//flag for saving data
bool shouldSaveConfig = false;
//callback notifying us of the need to save config
void saveConfigCallback () {
Serial.println("Should save config");
shouldSaveConfig = true;
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println();
//clean FS, for testing
//SPIFFS.format();
//read configuration from FS json
Serial.println("mounting FS...");
if (SPIFFS.begin()) {
Serial.println("mounted file system");
if (SPIFFS.exists("/config.json")) {
//file exists, reading and loading
Serial.println("reading config file");
File configFile = SPIFFS.open("/config.json", "r");
if (configFile) {
Serial.println("opened config file");
size_t size = configFile.size();
// Allocate a buffer to store contents of the file.
std::unique_ptr<char[]> buf(new char[size]);
configFile.readBytes(buf.get(), size);
DynamicJsonBuffer jsonBuffer;
JsonObject& json = jsonBuffer.parseObject(buf.get());
json.printTo(Serial);
if (json.success()) {
Serial.println("\nparsed json");
strcpy(mqtt_server, json["mqtt_server"]);
strcpy(mqtt_port, json["mqtt_port"]);
strcpy(blynk_token, json["blynk_token"]);
} else {
Serial.println("failed to load json config");
}
}
}
} else {
Serial.println("failed to mount FS");
}
//end read
// The extra parameters to be configured (can be either global or just in the setup)
// After connecting, parameter.getValue() will get you the configured value
// id/name placeholder/prompt default length
WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40);
WiFiManagerParameter custom_mqtt_port("port", "mqtt port", mqtt_port, 5);
WiFiManagerParameter custom_blynk_token("blynk", "blynk token", blynk_token, 32);
//WiFiManager
//Local intialization. Once its business is done, there is no need to keep it around
WiFiManager wifiManager;
//set config save notify callback
wifiManager.setSaveConfigCallback(saveConfigCallback);
//set static ip
wifiManager.setSTAStaticIPConfig(IPAddress(10,0,1,99), IPAddress(10,0,1,1), IPAddress(255,255,255,0));
//add all your parameters here
wifiManager.addParameter(&custom_mqtt_server);
wifiManager.addParameter(&custom_mqtt_port);
wifiManager.addParameter(&custom_blynk_token);
//reset settings - for testing
//wifiManager.resetSettings();
//set minimu quality of signal so it ignores AP's under that quality
//defaults to 8%
//wifiManager.setMinimumSignalQuality();
//sets timeout until configuration portal gets turned off
//useful to make it all retry or go to sleep
//in seconds
//wifiManager.setTimeout(120);
//fetches ssid and pass and tries to connect
//if it does not connect it starts an access point with the specified name
//here "AutoConnectAP"
//and goes into a blocking loop awaiting configuration
if (!wifiManager.autoConnect("AutoConnectAP", "password")) {
Serial.println("failed to connect and hit timeout");
delay(3000);
//reset and try again, or maybe put it to deep sleep
ESP.reset();
delay(5000);
}
//if you get here you have connected to the WiFi
Serial.println("connected...yeey :)");
//read updated parameters
strcpy(mqtt_server, custom_mqtt_server.getValue());
strcpy(mqtt_port, custom_mqtt_port.getValue());
strcpy(blynk_token, custom_blynk_token.getValue());
//save the custom parameters to FS
if (shouldSaveConfig) {
Serial.println("saving config");
DynamicJsonBuffer jsonBuffer;
JsonObject& json = jsonBuffer.createObject();
json["mqtt_server"] = mqtt_server;
json["mqtt_port"] = mqtt_port;
json["blynk_token"] = blynk_token;
File configFile = SPIFFS.open("/config.json", "w");
if (!configFile) {
Serial.println("failed to open config file for writing");
}
json.printTo(Serial);
json.printTo(configFile);
configFile.close();
//end save
}
Serial.println("local ip");
Serial.println(WiFi.localIP());
}
void loop() {
// put your main code here, to run repeatedly:
}
@@ -0,0 +1,188 @@
#include <FS.h> //this needs to be first, or it all crashes and burns...
#include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
#include <ArduinoJson.h> //https://github.com/bblanchon/ArduinoJson
//define your default values here, if there are different values in config.json, they are overwritten.
//length should be max size + 1
char mqtt_server[40];
char mqtt_port[6] = "8080";
char blynk_token[33] = "YOUR_BLYNK_TOKEN";
//default custom static IP
char static_ip[16] = "10.0.1.56";
char static_gw[16] = "10.0.1.1";
char static_sn[16] = "255.255.255.0";
//flag for saving data
bool shouldSaveConfig = false;
//callback notifying us of the need to save config
void saveConfigCallback () {
Serial.println("Should save config");
shouldSaveConfig = true;
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println();
//clean FS, for testing
//SPIFFS.format();
//read configuration from FS json
Serial.println("mounting FS...");
if (SPIFFS.begin()) {
Serial.println("mounted file system");
if (SPIFFS.exists("/config.json")) {
//file exists, reading and loading
Serial.println("reading config file");
File configFile = SPIFFS.open("/config.json", "r");
if (configFile) {
Serial.println("opened config file");
size_t size = configFile.size();
// Allocate a buffer to store contents of the file.
std::unique_ptr<char[]> buf(new char[size]);
configFile.readBytes(buf.get(), size);
DynamicJsonBuffer jsonBuffer;
JsonObject& json = jsonBuffer.parseObject(buf.get());
json.printTo(Serial);
if (json.success()) {
Serial.println("\nparsed json");
strcpy(mqtt_server, json["mqtt_server"]);
strcpy(mqtt_port, json["mqtt_port"]);
strcpy(blynk_token, json["blynk_token"]);
if(json["ip"]) {
Serial.println("setting custom ip from config");
//static_ip = json["ip"];
strcpy(static_ip, json["ip"]);
strcpy(static_gw, json["gateway"]);
strcpy(static_sn, json["subnet"]);
//strcat(static_ip, json["ip"]);
//static_gw = json["gateway"];
//static_sn = json["subnet"];
Serial.println(static_ip);
/* Serial.println("converting ip");
IPAddress ip = ipFromCharArray(static_ip);
Serial.println(ip);*/
} else {
Serial.println("no custom ip in config");
}
} else {
Serial.println("failed to load json config");
}
}
}
} else {
Serial.println("failed to mount FS");
}
//end read
Serial.println(static_ip);
Serial.println(blynk_token);
Serial.println(mqtt_server);
// The extra parameters to be configured (can be either global or just in the setup)
// After connecting, parameter.getValue() will get you the configured value
// id/name placeholder/prompt default length
WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40);
WiFiManagerParameter custom_mqtt_port("port", "mqtt port", mqtt_port, 5);
WiFiManagerParameter custom_blynk_token("blynk", "blynk token", blynk_token, 34);
//WiFiManager
//Local intialization. Once its business is done, there is no need to keep it around
WiFiManager wifiManager;
//set config save notify callback
wifiManager.setSaveConfigCallback(saveConfigCallback);
//set static ip
IPAddress _ip,_gw,_sn;
_ip.fromString(static_ip);
_gw.fromString(static_gw);
_sn.fromString(static_sn);
wifiManager.setSTAStaticIPConfig(_ip, _gw, _sn);
//add all your parameters here
wifiManager.addParameter(&custom_mqtt_server);
wifiManager.addParameter(&custom_mqtt_port);
wifiManager.addParameter(&custom_blynk_token);
//reset settings - for testing
//wifiManager.resetSettings();
//set minimu quality of signal so it ignores AP's under that quality
//defaults to 8%
wifiManager.setMinimumSignalQuality();
//sets timeout until configuration portal gets turned off
//useful to make it all retry or go to sleep
//in seconds
//wifiManager.setTimeout(120);
//fetches ssid and pass and tries to connect
//if it does not connect it starts an access point with the specified name
//here "AutoConnectAP"
//and goes into a blocking loop awaiting configuration
if (!wifiManager.autoConnect("AutoConnectAP", "password")) {
Serial.println("failed to connect and hit timeout");
delay(3000);
//reset and try again, or maybe put it to deep sleep
ESP.reset();
delay(5000);
}
//if you get here you have connected to the WiFi
Serial.println("connected...yeey :)");
//read updated parameters
strcpy(mqtt_server, custom_mqtt_server.getValue());
strcpy(mqtt_port, custom_mqtt_port.getValue());
strcpy(blynk_token, custom_blynk_token.getValue());
//save the custom parameters to FS
if (shouldSaveConfig) {
Serial.println("saving config");
DynamicJsonBuffer jsonBuffer;
JsonObject& json = jsonBuffer.createObject();
json["mqtt_server"] = mqtt_server;
json["mqtt_port"] = mqtt_port;
json["blynk_token"] = blynk_token;
json["ip"] = WiFi.localIP().toString();
json["gateway"] = WiFi.gatewayIP().toString();
json["subnet"] = WiFi.subnetMask().toString();
File configFile = SPIFFS.open("/config.json", "w");
if (!configFile) {
Serial.println("failed to open config file for writing");
}
json.prettyPrintTo(Serial);
json.printTo(configFile);
configFile.close();
//end save
}
Serial.println("local ip");
Serial.println(WiFi.localIP());
Serial.println(WiFi.gatewayIP());
Serial.println(WiFi.subnetMask());
}
void loop() {
// put your main code here, to run repeatedly:
}
@@ -3,11 +3,13 @@
//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
#include "WiFiManager.h" //https://github.com/tzapu/WiFiManager
void configModeCallback () {
void configModeCallback (WiFiManager *myWiFiManager) {
Serial.println("Entered config mode");
Serial.println(WiFi.softAPIP());
//if you used auto generated SSID, print it
Serial.println(myWiFiManager->getConfigPortalSSID());
}
void setup() {
@@ -22,11 +24,12 @@ void setup() {
//set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
wifiManager.setAPCallback(configModeCallback);
//fetches ssid and pass and tries to connect
//if it does not connect it starts an access point with the specified name
//here "AutoConnectAP"
//and goes into a blocking loop awaiting configuration
if(!wifiManager.autoConnect("AutoConnectAP")) {
if(!wifiManager.autoConnect()) {
Serial.println("failed to connect and hit timeout");
//reset and try again, or maybe put it to deep sleep
ESP.reset();
@@ -0,0 +1,68 @@
#include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
//for LED status
#include <Ticker.h>
Ticker ticker;
void tick()
{
//toggle state
int state = digitalRead(BUILTIN_LED); // get the current state of GPIO1 pin
digitalWrite(BUILTIN_LED, !state); // set pin to the opposite state
}
//gets called when WiFiManager enters configuration mode
void configModeCallback (WiFiManager *myWiFiManager) {
Serial.println("Entered config mode");
Serial.println(WiFi.softAPIP());
//if you used auto generated SSID, print it
Serial.println(myWiFiManager->getConfigPortalSSID());
//entered config mode, make led toggle faster
ticker.attach(0.2, tick);
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
//set led pin as output
pinMode(BUILTIN_LED, OUTPUT);
// start ticker with 0.5 because we start in AP mode and try to connect
ticker.attach(0.6, tick);
//WiFiManager
//Local intialization. Once its business is done, there is no need to keep it around
WiFiManager wifiManager;
//reset settings - for testing
//wifiManager.resetSettings();
//set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
wifiManager.setAPCallback(configModeCallback);
//fetches ssid and pass and tries to connect
//if it does not connect it starts an access point with the specified name
//here "AutoConnectAP"
//and goes into a blocking loop awaiting configuration
if (!wifiManager.autoConnect()) {
Serial.println("failed to connect and hit timeout");
//reset and try again, or maybe put it to deep sleep
ESP.reset();
delay(1000);
}
//if you get here you have connected to the WiFi
Serial.println("connected...yeey :)");
ticker.detach();
//keep LED on
digitalWrite(BUILTIN_LED, LOW);
}
void loop() {
// put your main code here, to run repeatedly:
}
@@ -0,0 +1,49 @@
#include <FS.h> //this needs to be first, or it all crashes and burns...
#include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println();
//WiFiManager
//Local intialization. Once its business is done, there is no need to keep it around
WiFiManager wifiManager;
//exit after config instead of connecting
wifiManager.setBreakAfterConfig(true);
//reset settings - for testing
//wifiManager.resetSettings();
//tries to connect to last known settings
//if it does not connect it starts an access point with the specified name
//here "AutoConnectAP" with password "password"
//and goes into a blocking loop awaiting configuration
if (!wifiManager.autoConnect("AutoConnectAP", "password")) {
Serial.println("failed to connect, we should reset as see if it connects");
delay(3000);
ESP.reset();
delay(5000);
}
//if you get here you have connected to the WiFi
Serial.println("connected...yeey :)");
Serial.println("local ip");
Serial.println(WiFi.localIP());
}
void loop() {
// put your main code here, to run repeatedly:
}
@@ -0,0 +1,75 @@
#include <FS.h> //this needs to be first, or it all crashes and burns...
#include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
/**************************************************************************************
* this example shows how to set a static IP configuration for the ESP
* although the IP shows in the config portal, the changes will revert
* to the IP set in the source file.
* if you want the ability to configure and persist the new IP configuration
* look at the FS examples, which save the config to file
*************************************************************************************/
//default custom static IP
//char static_ip[16] = "10.0.1.59";
//char static_gw[16] = "10.0.1.1";
//char static_sn[16] = "255.255.255.0";
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println();
//WiFiManager
//Local intialization. Once its business is done, there is no need to keep it around
WiFiManager wifiManager;
//reset settings - for testing
//wifiManager.resetSettings();
//set static ip
//the commented bit only works for ESP8266 core 2.1.0 or newer
/*IPAddress _ip,_gw,_sn;
_ip.fromString(static_ip);
_gw.fromString(static_gw);
_sn.fromString(static_sn);
*/
IPAddress _ip = IPAddress(10, 0, 1, 78);
IPAddress _gw = IPAddress(10, 0, 1, 1);
IPAddress _sn = IPAddress(255, 255, 255, 0);
wifiManager.setSTAStaticIPConfig(_ip, _gw, _sn);
//tries to connect to last known settings
//if it does not connect it starts an access point with the specified name
//here "AutoConnectAP" with password "password"
//and goes into a blocking loop awaiting configuration
if (!wifiManager.autoConnect("AutoConnectAP", "password")) {
Serial.println("failed to connect, we should reset as see if it connects");
delay(3000);
ESP.reset();
delay(5000);
}
//if you get here you have connected to the WiFi
Serial.println("connected...yeey :)");
Serial.println("local ip");
Serial.println(WiFi.localIP());
}
void loop() {
// put your main code here, to run repeatedly:
}
@@ -0,0 +1,60 @@
#include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
//needed for library
#include <ESP8266WebServer.h>
#include <DNSServer.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
// select wich pin will trigger the configuraton portal when set to LOW
// ESP-01 users please note: the only pins available (0 and 2), are shared
// with the bootloader, so always set them HIGH at power-up
#define TRIGGER_PIN 0
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("\n Starting");
pinMode(TRIGGER_PIN, INPUT);
}
void loop() {
// is configuration portal requested?
if ( digitalRead(TRIGGER_PIN) == LOW ) {
//WiFiManager
//Local intialization. Once its business is done, there is no need to keep it around
WiFiManager wifiManager;
//reset settings - for testing
//wifiManager.resetSettings();
//sets timeout until configuration portal gets turned off
//useful to make it all retry or go to sleep
//in seconds
//wifiManager.setTimeout(120);
//it starts an access point with the specified name
//here "AutoConnectAP"
//and goes into a blocking loop awaiting configuration
//WITHOUT THIS THE AP DOES NOT SEEM TO WORK PROPERLY WITH SDK 1.5 , update to at least 1.5.1
//WiFi.mode(WIFI_STA);
if (!wifiManager.startConfigPortal("OnDemandAP")) {
Serial.println("failed to connect and hit timeout");
delay(3000);
//reset and try again, or maybe put it to deep sleep
ESP.reset();
delay(5000);
}
//if you get here you have connected to the WiFi
Serial.println("connected...yeey :)");
}
// put your main code here, to run repeatedly:
}
+20
View File
@@ -0,0 +1,20 @@
<!DOCTYPE html><html lang=\"en\"><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\"/><title>{v}</title>
<style>.c{text-align: center} div,input{padding:5px;font-size:1em;} input{width:95%;} body{text-align: center;font-family:verdana;} button{border:0;border-radius:0.3rem;background-color:#1fa3ec;color:#fff;line-height:2.4rem;font-size:1.2rem;width:100%;}</style>
<script>function c(l){document.getElementById('s').value=l.innerText||l.textContent;document.getElementById('p').focus();}</script>
</head><body><div style="text-align: left; display: inline-block;">
<div><a href='#' onclick='c(this)'>{v}</a> {r}% {i}</div>
<div><a href='#' onclick='c(this)'>{v}</a> 100% <img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAKCAMAAAC+Ge+yAAAACVBMVEUAAAC7u7v///9etNz6AAAAI0lEQVQI133GsQ3AMAAEoXv2H9qNJacKFbEaWTQJ+uQB/nMdEaYAXeJkZ9AAAAAASUVORK5CYII='/></div>
<div><a href='#' onclick='c(this)'>Vila17</a> 95% <img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAADFBMVEUAAAAAtgD///8AAADV1YIHAAAAA3RSTlMAAAD6dsTeAAAAHUlEQVR4AWMAAmYgYGBkArHAAMoEYnQmMxSQywQAKvMA3+mlSFAAAAAASUVORK5CYII='/></div>
<div><a href='#'>LilRidingHoodz</a> 100% <img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAABlBMVEUAAAD///+l2Z/dAAAAIklEQVR4AWNgZGRkAAIQBURQDEZAgM5kgAJGEAQDwkxkbQAOhgBBk64+mQAAAABJRU5ErkJggg=='/></div>
<div><a href='#'>Marcelica</a> 100% <img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAACVBMVEUAAAC7u7v///9etNz6AAAAJ0lEQVR4AY3GsREAIBSDUD77D63x4tlKw0MdmD0ijTO9f6SFnv7YXB4qAIVn0xoMAAAAAElFTkSuQmCC'/></div>
<div><a href='#'>PMica</a> 110% <img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAALVBMVEX///8EBwfBwsLw8PAzNjaCg4NTVVUjJiZDRUUUFxdiZGSho6OSk5Pg4eFydHTCjaf3AAAAZElEQVQ4je2NSw7AIAhEBamKn97/uMXEGBvozkWb9C2Zx4xzWykBhFAeYp9gkLyZE0zIMno9n4g19hmdY39scwqVkOXaxph0ZCXQcqxSpgQpONa59wkRDOL93eAXvimwlbPbwwVAegLS1HGfZAAAAABJRU5ErkJggg==' width="13px"/></div>
<br/>
<form method='get' action='wifisave'><input id='s' name='s' length=32 placeholder='SSID'><br/><input id='p' name='p' length=64 placeholder='password'><br/><button type='submit'>save</button></form>
<br/><div></div>
<br/>
<form action=\"/wifi\" method=\"get\"><button>Configure WiFi</button></form><br/>
<form action=\"/0wifi\" method=\"get\"><button>Configure WiFi (No Scan)</button></form>
<br>
<div class="c"><a href=\"/wifi\">Scan</a></div>
</div>
</body></html>
+40
View File
@@ -0,0 +1,40 @@
#######################################
# Syntax Coloring Map For WifiManager
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
WiFiManager KEYWORD1
WiFiManagerParameter KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
autoConnect KEYWORD2
getSSID KEYWORD2
getPassword KEYWORD2
getConfigPortalSSID KEYWORD2
resetSettings KEYWORD2
urldecode KEYWORD2
setTimeout KEYWORD2
setDebugOutput KEYWORD2
setMinimumSignalQuality KEYWORD2
setAPStaticIPConfig KEYWORD2
setSTAStaticIPConfig KEYWORD2
setAPCallback KEYWORD2
setSaveConfigCallback KEYWORD2
addParameter KEYWORD2
getID KEYWORD2
getValue KEYWORD2
getPlaceholder KEYWORD2
getValueLength KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
# LITERAL1
+13
View File
@@ -0,0 +1,13 @@
{
"name": "WifiManager",
"keywords": "wifi, wi-fi",
"description": "ESP8266 WiFi Connection manager with fallback web configuration portal **USE version 0.6 together with stable 2.0.0 ESP8266 core for Arduino and use 0.7 for core 2.1.0.rc2 or newer**",
"repository":
{
"type": "git",
"url": "https://github.com/tzapu/WiFiManager.git"
},
"frameworks": "arduino",
"platforms": "espressif",
"version": "0.8"
}
+9
View File
@@ -0,0 +1,9 @@
name=WiFiManager
version=0.8
author=tzapu
maintainer=tzapu
sentence=ESP8266 WiFi Connection manager with fallback web configuration portal
paragraph=Library for configuring ESP8266 modules WiFi credentials at runtime. **USE version 0.6 together with stable 2.0.0 ESP8266 core for Arduino and use 0.7 for core 2.1.0.rc2 or newer**
category=Communication
url=https://github.com/tzapu/WiFiManager.git
architectures=esp8266