Skip to content

Instantly share code, notes, and snippets.

@toxicantidote
Last active May 22, 2023 01:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save toxicantidote/af13cfeb292dcbed0a0214208f5ca730 to your computer and use it in GitHub Desktop.
Save toxicantidote/af13cfeb292dcbed0a0214208f5ca730 to your computer and use it in GitHub Desktop.
ESP32 Wi-Fi search and connect to saved
#include <WiFi.h>
#include <Preferences.h>
#include <esp_task_wdt.h>
#define CMDPROMPT "ESP32> "
#define TIMEOUT 10000
// cmd line vars
char cmdBuffer[32];
int cmdBufferPosition = 0;
char cmdByte;
int cmdStatus = 0;
int echoInput = 1;
char command[32];
char argument1[32];
char argument2[32];
int wifiCount = 0;
bool connected = false;
bool countdown = false;
Preferences preferences;
String ssid;
String password;
void wifiScan(void);
void setup() {
Serial.begin(9600);
preferences.begin("wifi", false);
Serial.println("Booting..");
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(100);
ssid = preferences.getString("ssid", "");
password = preferences.getString("password", "");
if (ssid == "") {
Serial.println("No network saved");
wifiScan();
} else {
countdown = true;
Serial.print("Saved network SSID is ");
Serial.println(ssid);
Serial.print("Auto-connect in ");
unsigned int end = millis() + TIMEOUT;
int last_count = 0;
while (countdown == true) {
unsigned int remaining = end - millis();
if ((remaining < 0) || (remaining > TIMEOUT)) {
break;
} else {
int count = (remaining / 1000);
if (count != last_count) {
last_count = count;
Serial.print(count);
Serial.print("..");
if (Serial.available() > 1) {
countdown = false;
}
}
}
}
if (countdown == true) {
Serial.println("Connecting...");
connect(ssid.c_str(), password.c_str());
} else {
Serial.println("Connection aborted");
wifiScan();
}
}
esp_task_wdt_init(10, true); //enable panic so ESP32 restarts
esp_task_wdt_add(NULL); //add current thread to WDT watch
}
void loop() {
esp_task_wdt_reset();
checkSerial();
if ((WiFi.status() != WL_CONNECTED) && (connected == true)) {
Serial.println("Lost connection to Wi-Fi. Reconnecting...");
WiFi.disconnect();
connected = false;
delay(100);
connect(ssid.c_str(), password.c_str());
}
}
void wifiScan() {
Serial.println("Searching for APs..");
wifiCount = WiFi.scanNetworks();
Serial.println("Networks found:");
for (int i = 0; i < wifiCount; i++) {
Serial.print("\t[");
Serial.print(i);
Serial.print("]\t(");
Serial.print(WiFi.BSSIDstr(i));
Serial.print(") ");
Serial.print(WiFi.SSID(i));
Serial.print(" [Signal ");
Serial.print(WiFi.RSSI(i));
Serial.println("dBm]");
delay(10);
}
}
void checkSerial() {
// command stuff
for (int i = 0; i < Serial.available() && cmdStatus == 0; i++) { // if serial data is available to read
cmdStatus = 0;
cmdByte = Serial.read(); // read it
if (cmdByte == 0x0A || cmdByte == 0x0D) { // newline and carriage return
Serial.flush(); // clear the input buffer
if (cmdBufferPosition == 0) { // if command is blank
resetBuffers(); // reset buffers
} else { // if the command is not blank
cmdStatus = 1; // flag the command as 'ready for processing'
}
} else if (cmdByte == 0x7F) { // backspace
if (cmdBufferPosition != 0) { // don't backspace further than the prompt
cmdBufferPosition--;
if (echoInput == 1) { // if echo is enabled, backspace on the client
Serial.print('\b');
}
}
} else { // other char, add to buffer
// restrict to printable characters
if (cmdByte >= 0x20 && cmdByte <= 0x7E) {
cmdBuffer[cmdBufferPosition] = cmdByte; // append to buffer
cmdBufferPosition++; // increment buffer position
if (echoInput == 1) { // if echo is enabled, echo the character back to the client
Serial.print(cmdByte);
}
}
}
}
if (cmdStatus == 1) { // cmd received, but not processed
// in case of backspace, truncate command buffer
for (int i = cmdBufferPosition; i <= strlen(cmdBuffer); i++) {
cmdBuffer[i] = NULL;
}
handleCommand(cmdBuffer); // process the command
resetBuffers(); // clear the command buffers
}
}
void connectIndex(int index, char *password) {
ssid = WiFi.SSID(index);
const char *ssid_chr = ssid.c_str();
connect(ssid_chr, password);
}
void connect(const char *ssid, const char *password) {
Serial.println("Connecting to network...");
unsigned long start = millis();
unsigned long duration = 0;
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
duration = millis() - start;
if (duration > TIMEOUT) {
Serial.println("WiFi: Connection failed. Is the password correct?");
break;
}
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("WiFi: Connected to network");
preferences.putString("ssid", ssid);
preferences.putString("password", password);
Serial.print("IP address is ");
Serial.println(WiFi.localIP());
connected = true;
} else {
connected = false;
}
}
// serial command interpreter
void handleCommand(char* cmdBuffer) { // handles commands
// init vars
char *command = NULL;
char *argument1 = NULL;
char *argument2 = NULL;
char *buf = cmdBuffer;
command = strtok(buf, " "); // first word (command, before space)
argument1 = strtok(NULL, " "); // second word (argument, after space)
argument2 = strtok(NULL, " "); // third word (argument, after space)
Serial.println(""); // newline
// process command
if (strcasecmp(command, "HELP") == 0) {
Serial.println("Command help:");
Serial.println("\tSCAN - Scan for networks");
Serial.println("\tCONNECT <#> <password> - Connect to a listed network (passwords cannot have spaces)");
Serial.println("\tDISCONNECT - Disconnect from Wi-Fi");
Serial.println("\tFORGET - Forget saved Wi-Fi");
Serial.println("\tWSTATUS - Show current Wi-Fi status");
} else if (strcasecmp(command, "SCAN") == 0) {
wifiScan();
} else if (strcasecmp(command, "CONNECT") == 0) {
int index = atoi(argument1);
if (index <= wifiCount) {
connectIndex(index, argument2);
} else {
Serial.print("Invalid network. Select a number between 0 and ");
Serial.println(((int)wifiCount - 1));
}
} else if (strcasecmp(command, "DISCONNECT") == 0) {
if (connected == true) {
Serial.println("Disconnecting..");
connected = false;
WiFi.disconnect();
Serial.println("Disconnected!");
} else {
Serial.println("Not connected!");
}
} else if (strcasecmp(command, "FORGET") == 0) {
preferences.putString("ssid", "");
preferences.putString("password", "");
Serial.println("Saved network cleared");
} else if (strcasecmp(command, "WSTATUS") == 0) {
if (connected == false) {
Serial.println("Not connected to network");
} else {
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("RSSI: ");
Serial.print(WiFi.RSSI());
Serial.println("dBm");
Serial.print("Our IP: ");
Serial.println(WiFi.localIP());
Serial.print("Our MAC: ");
Serial.println(WiFi.macAddress());
}
} else {
Serial.println("Unknown command. Enter HELP for help.");
}
}
// reset the serial command buffers
void resetBuffers() { // resets command buffers and command state
cmdStatus = 0; // reset the processing state
cmdBufferPosition = 0; // reset the buffer position
for (int x = 0; x < 32; x++) { // clear the buffer
cmdBuffer[x] = NULL; // command buffer
command[x] = NULL; // command
argument1[x] = NULL; // command arguments
argument2[x] = NULL; // command arguments
}
if (echoInput == 1) { // if echo is enabled, print a prompt
Serial.println("");
Serial.print(CMDPROMPT);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment