├── LICENSE ├── README.md ├── esp8266_wifi_setup └── esp8266_wifi_setup.ino └── schematic.png /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2015 Kei Yoshimura 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 | esp8266-wifi-setup 2 | ====== 3 | 4 | ESP8266 Wifi setup using SoftAP, Captive Portal and EEPROM. 5 | 6 | 1. booting and read Wifi config from EEPROM. 7 | 2. if Wifi config is not found, starting SoftAP at SSID "ESP8266_SETUP". 8 | 3. connect this Access point with your devices. (ex. iPhone, Android...) 9 | 4. Wifi Settings page will automatically open by Captive Portal. 10 | 5. select the SSID, enter the password. 11 | 6. writing SSID and password to EEPROM, then reboot ESP8266 automatically. 12 | 7. booting with STA(client) mode and get IP address from DHCP, then start web server. 13 | 8. now you can connect from within the same LAN. 14 | 15 | 日本語の解説は[ブログ](http://eleclog.quitsq.com/2015/08/esp8266-wifi-setup.html)を参照してください。 16 | 17 | ## Wiring 18 | 19 | Boot from flash memory: 20 | 21 | * GPIO 0 - Pulled HIGH with a 10k resistor 22 | * GPIO 2 - Pulled HIGH with a 10k resistor 23 | * GPIO 15 - Pulled LOW with a 10k resistor 24 | 25 | ![schematic](https://raw.githubusercontent.com/9SQ/esp8266-wifi-setup/master/schematic.png) 26 | 27 | If GPIO 0 pin is pulled low during power-up it will start firmware flashing mode. 28 | 29 | See also [official documents](https://github.com/espressif/esptool/wiki/ESP8266-Boot-Mode-Selection). 30 | 31 | ## Demo 32 | ### mobile 33 | ![sample](http://3.bp.blogspot.com/-ETIrnJynYj8/VdzTZQfJqLI/AAAAAAAATPU/_qUS0v57Bk0/esp8266-wifi-setup.gif) 34 | 35 | ### serial monitor 36 | ![sample_serial](http://2.bp.blogspot.com/-OOwLd6lHLTY/VdzWCOpQFUI/AAAAAAAATPg/9M1z1Lm3iWQ/s600/esp8266-wifi-setup_serial.png) 37 | 38 | ## Requirements 39 | 40 | * [Arduino core for ESP8266 WiFi chip](https://github.com/esp8266/Arduino) -------------------------------------------------------------------------------- /esp8266_wifi_setup/esp8266_wifi_setup.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | const IPAddress apIP(192, 168, 1, 1); 8 | const char* apSSID = "ESP8266_SETUP"; 9 | boolean settingMode; 10 | String ssidList; 11 | 12 | DNSServer dnsServer; 13 | ESP8266WebServer webServer(80); 14 | 15 | void setup() { 16 | Serial.begin(115200); 17 | EEPROM.begin(512); 18 | delay(10); 19 | if (restoreConfig()) { 20 | if (checkConnection()) { 21 | settingMode = false; 22 | startWebServer(); 23 | return; 24 | } 25 | } 26 | settingMode = true; 27 | setupMode(); 28 | } 29 | 30 | void loop() { 31 | if (settingMode) { 32 | dnsServer.processNextRequest(); 33 | } 34 | webServer.handleClient(); 35 | } 36 | 37 | boolean restoreConfig() { 38 | Serial.println("Reading EEPROM..."); 39 | String ssid = ""; 40 | String pass = ""; 41 | if (EEPROM.read(0) != 0) { 42 | for (int i = 0; i < 32; ++i) { 43 | ssid += char(EEPROM.read(i)); 44 | } 45 | Serial.print("SSID: "); 46 | Serial.println(ssid); 47 | for (int i = 32; i < 96; ++i) { 48 | pass += char(EEPROM.read(i)); 49 | } 50 | Serial.print("Password: "); 51 | Serial.println(pass); 52 | WiFi.begin(ssid.c_str(), pass.c_str()); 53 | return true; 54 | } 55 | else { 56 | Serial.println("Config not found."); 57 | return false; 58 | } 59 | } 60 | 61 | boolean checkConnection() { 62 | int count = 0; 63 | Serial.print("Waiting for Wi-Fi connection"); 64 | while ( count < 30 ) { 65 | if (WiFi.status() == WL_CONNECTED) { 66 | Serial.println(); 67 | Serial.println("Connected!"); 68 | return (true); 69 | } 70 | delay(500); 71 | Serial.print("."); 72 | count++; 73 | } 74 | Serial.println("Timed out."); 75 | return false; 76 | } 77 | 78 | void startWebServer() { 79 | if (settingMode) { 80 | Serial.print("Starting Web Server at "); 81 | Serial.println(WiFi.softAPIP()); 82 | webServer.on("/settings", []() { 83 | String s = "

Wi-Fi Settings

Please enter your password by selecting the SSID.

"; 84 | s += "

Password:
"; 87 | webServer.send(200, "text/html", makePage("Wi-Fi Settings", s)); 88 | }); 89 | webServer.on("/setap", []() { 90 | for (int i = 0; i < 96; ++i) { 91 | EEPROM.write(i, 0); 92 | } 93 | String ssid = urlDecode(webServer.arg("ssid")); 94 | Serial.print("SSID: "); 95 | Serial.println(ssid); 96 | String pass = urlDecode(webServer.arg("pass")); 97 | Serial.print("Password: "); 98 | Serial.println(pass); 99 | Serial.println("Writing SSID to EEPROM..."); 100 | for (int i = 0; i < ssid.length(); ++i) { 101 | EEPROM.write(i, ssid[i]); 102 | } 103 | Serial.println("Writing Password to EEPROM..."); 104 | for (int i = 0; i < pass.length(); ++i) { 105 | EEPROM.write(32 + i, pass[i]); 106 | } 107 | EEPROM.commit(); 108 | Serial.println("Write EEPROM done!"); 109 | String s = "

Setup complete.

device will be connected to \""; 110 | s += ssid; 111 | s += "\" after the restart."; 112 | webServer.send(200, "text/html", makePage("Wi-Fi Settings", s)); 113 | ESP.restart(); 114 | }); 115 | webServer.onNotFound([]() { 116 | String s = "

AP mode

Wi-Fi Settings

"; 117 | webServer.send(200, "text/html", makePage("AP mode", s)); 118 | }); 119 | } 120 | else { 121 | Serial.print("Starting Web Server at "); 122 | Serial.println(WiFi.localIP()); 123 | webServer.on("/", []() { 124 | String s = "

STA mode

Reset Wi-Fi Settings

"; 125 | webServer.send(200, "text/html", makePage("STA mode", s)); 126 | }); 127 | webServer.on("/reset", []() { 128 | for (int i = 0; i < 96; ++i) { 129 | EEPROM.write(i, 0); 130 | } 131 | EEPROM.commit(); 132 | String s = "

Wi-Fi settings was reset.

Please reset device.

"; 133 | webServer.send(200, "text/html", makePage("Reset Wi-Fi Settings", s)); 134 | }); 135 | } 136 | webServer.begin(); 137 | } 138 | 139 | void setupMode() { 140 | WiFi.mode(WIFI_STA); 141 | WiFi.disconnect(); 142 | delay(100); 143 | int n = WiFi.scanNetworks(); 144 | delay(100); 145 | Serial.println(""); 146 | for (int i = 0; i < n; ++i) { 147 | ssidList += ""; 152 | } 153 | delay(100); 154 | WiFi.mode(WIFI_AP); 155 | WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0)); 156 | WiFi.softAP(apSSID); 157 | dnsServer.start(53, "*", apIP); 158 | startWebServer(); 159 | Serial.print("Starting Access Point at \""); 160 | Serial.print(apSSID); 161 | Serial.println("\""); 162 | } 163 | 164 | String makePage(String title, String contents) { 165 | String s = ""; 166 | s += ""; 167 | s += ""; 168 | s += title; 169 | s += ""; 170 | s += contents; 171 | s += ""; 172 | return s; 173 | } 174 | 175 | String urlDecode(String input) { 176 | String s = input; 177 | s.replace("%20", " "); 178 | s.replace("+", " "); 179 | s.replace("%21", "!"); 180 | s.replace("%22", "\""); 181 | s.replace("%23", "#"); 182 | s.replace("%24", "$"); 183 | s.replace("%25", "%"); 184 | s.replace("%26", "&"); 185 | s.replace("%27", "\'"); 186 | s.replace("%28", "("); 187 | s.replace("%29", ")"); 188 | s.replace("%30", "*"); 189 | s.replace("%31", "+"); 190 | s.replace("%2C", ","); 191 | s.replace("%2E", "."); 192 | s.replace("%2F", "/"); 193 | s.replace("%2C", ","); 194 | s.replace("%3A", ":"); 195 | s.replace("%3A", ";"); 196 | s.replace("%3C", "<"); 197 | s.replace("%3D", "="); 198 | s.replace("%3E", ">"); 199 | s.replace("%3F", "?"); 200 | s.replace("%40", "@"); 201 | s.replace("%5B", "["); 202 | s.replace("%5C", "\\"); 203 | s.replace("%5D", "]"); 204 | s.replace("%5E", "^"); 205 | s.replace("%5F", "-"); 206 | s.replace("%60", "`"); 207 | return s; 208 | } 209 | 210 | -------------------------------------------------------------------------------- /schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/9SQ/esp8266-wifi-setup/4dcb08b84018c0da93e2ba1efe1e0c7465156e27/schematic.png --------------------------------------------------------------------------------