Hello,
I am using NodeMCU Lua IOT-board (Internet Of Things) which is not exactly Arduino but is programmed through Arduino IDE and uses the same language. So I have a code that takes Dallas temperature sensor reading and uploads the value to internet server (https://m2x.att.com). Everything works fine but I would like that the IOT-board would connect automatically to multiple wifi networks (home, work, school ect). At the moment every time I have to re-program it with changed WIFI SSID and password. Is it somehow possible to insert multiple WIFI credentails so that the board will automatically try every predefined password and SSID?
#include <ESP8266WiFi.h>
#define ESP8266_PLATFORM
#include "M2XStreamClient.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 10
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
[b][color=red]
char ssid[] = "Thomson-08-73-FF-22-44-FR"; // your network SSID (name)
char pass[] = "856C9175BA"; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key Index number (needed only for WEP)
[/color][/b]
int status = WL_IDLE_STATUS;
char deviceId[] = "5ea8c66c47639bf4ed3b57fdaddssaddq4324"; // Device you want to push to
char streamName[] = "temperature"; // Stream you want to push to
char m2xKey[] = "f88f156305b9e960fd55fcdkjasakjhda"; // Your M2X access key
const int temperaturePin = 0;
WiFiClient client;
M2XStreamClient m2xClient(&client, m2xKey);
void setup() {
Serial.begin(9600);
sensors.begin();
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(30000);
}
Serial.println("Connected to wifi");
printWifiStatus();
}
void loop() {
float degreesC;
sensors.requestTemperatures();
degreesC = sensors.getTempCByIndex(0);
Serial.print(" deg C: ");
Serial.print(degreesC);
int response = m2xClient.updateStreamValue(deviceId, streamName, degreesC);
Serial.print("M2x client response code: ");
Serial.println(response);
delay(900000);
if (response == -1) while(1) ;
delay(5000);
}
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
check the WiFiScan example. this will show you how you can find which networks are available. Once you recognize an SSID you know about, then connect to that one.
D3C3PT1C0N:
Thank you! I will try to figure something out. Although probably fail..
come on you can do it! trust in yourself (and put some energy into learning)
in the setup what you do is:
initialise module for finding SSID as in the example
while there are new SSID to be found
get the next SSID name.
check if you know about it
if yes, connect, validate connexion and you're good to go, exit the search with success
if not try with the next one
if not found, exit the search with error
those c functions will come handy to compare the SSID you get to the ones you know stdlib.h string.h
Thank you. I was thinking not to scan but just to make it try one credentials, if not working, then try another.
Maybe something like this:
char ssid[] = "Work_Network"; // your network SSID (name)
char pass[] = "d78sad78d8a"; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;
char ssid2[] = "School_Network"; // your network SSID (name)
char pass2[] = "dsafdef3f4"; // your network password (use for WPA, or use as key for WEP)
int keyIndex2 = 0;
yes, it is not that important (i think...), although using SSID-scanning would be more secure.. did not think about that. I will try to Google for examples, maybe someone has done it before.
To be honest it's not that more secure because I can setup an SSID that just looks like your home and you'll try to connect. depending on level of security that's an opportunity for a man in the middle attack but you don't care too much probably (unless if the attacker knows where you live and then attacker can come near your home and connect to your home wifi too if they know the pwd)....
I tend to be a bit careful with those things... my gadgets are never on my personal network, I've a separate one just in case...
So everyone can use network sniffer and find out what this wifi development board is sending out?
If I go to school and turn on the development board (NodeMCU Lua) and it starts to try predefined SSIDs, all those that are being tried are somehow visible?
If anyone could share an example about Arduino as WIFI client with multiple SSIDs (+ passwords), I would be very thankful. Cannot seem to find anything.
can't you give it a try? it's not rocket science to take the network found by the scan one by one and compare with the ones from a list... if you can't write that, how can you plan to write anything a bit complicated.?
OK - I used my lunch break to quickly hack this together based on the source code of wifi Scan referenced above.
I've not tested it but should probably work. I tried to document what each sections does. please study carefully so that you should be able to do that by yourself in the future.
You need to have your serial console set at 115200 bauds to see something in the IDE console.
Left for you to do:
handle multiple different passwords for same network SSID
handle networks with no password
handle the case where the connexion at the end never succeeds
or only connect to password protected networks (check if WiFi.encryptionType(i) == ENC_TYPE_NONE)
use passwords and SSIDs saved in EEPROM
Propose a way for the end user to add/remove known networks in EEPROM (possibly booting up in Access point mode if no network is found and offering a web interface to do so).
// This is for a NodeMCU ESP12 / ESP12E module in "Arduino mode"
// simple example, does not support 2 SSIDs with same name, different pwd.
#include "ESP8266WiFi.h"
// DEFINE HERE THE KNOWN NETWORKS
const char* KNOWN_SSID[] = {"SSID0", "SSID1", "MyHomeNetwork", "SSID3"};
const char* KNOWN_PASSWORD[] = {"PassW0rd", "PassW1rd", "MyRealPwd", "PassW3rd"};
const int KNOWN_SSID_COUNT = sizeof(KNOWN_SSID) / sizeof(KNOWN_SSID[0]); // number of known networks
void setup() {
boolean wifiFound = false;
int i, n;
Serial.begin(115200);
// ----------------------------------------------------------------
// Set WiFi to station mode and disconnect from an AP if it was previously connected
// ----------------------------------------------------------------
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(100);
Serial.println("Setup done");
// ----------------------------------------------------------------
// WiFi.scanNetworks will return the number of networks found
// ----------------------------------------------------------------
Serial.println(F("scan start"));
int nbVisibleNetworks = WiFi.scanNetworks();
Serial.println(F("scan done"));
if (nbVisibleNetworks == 0) {
Serial.println(F("no networks found. Reset to try again"));
while (true); // no need to go further, hang in there, will auto launch the Soft WDT reset
}
// ----------------------------------------------------------------
// if you arrive here at least some networks are visible
// ----------------------------------------------------------------
Serial.print(nbVisibleNetworks);
Serial.println(" network(s) found");
// ----------------------------------------------------------------
// check if we recognize one by comparing the visible networks
// one by one with our list of known networks
// ----------------------------------------------------------------
for (i = 0; i < nbVisibleNetworks; ++i) {
Serial.println(WiFi.SSID(i)); // Print current SSID
for (n = 0; n < KNOWN_SSID_COUNT; n++) { // walk through the list of known SSID and check for a match
if (strcmp(KNOWN_SSID[n], WiFi.SSID(i).c_str())) {
Serial.print(F("\tNot matching "));
Serial.println(KNOWN_SSID[n]);
} else { // we got a match
wifiFound = true;
break; // n is the network index we found
}
} // end for each known wifi SSID
if (wifiFound) break; // break from the "for each visible network" loop
} // end for each visible network
if (!wifiFound) {
Serial.println(F("no Known network identified. Reset to try again"));
while (true); // no need to go further, hang in there, will auto launch the Soft WDT reset
}
// ----------------------------------------------------------------
// if you arrive here you found 1 known SSID
// ----------------------------------------------------------------
Serial.print(F("\nConnecting to "));
Serial.println(KNOWN_SSID[n]);
// ----------------------------------------------------------------
// We try to connect to the WiFi network we found
// ----------------------------------------------------------------
WiFi.begin(KNOWN_SSID[n], KNOWN_PASSWORD[n]);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
// ----------------------------------------------------------------
// SUCCESS, you are connected to the known WiFi network
// ----------------------------------------------------------------
Serial.println(F("WiFi connected, your IP address is "));
Serial.println(WiFi.localIP());
}
void loop() {}
Thank you. I actually have tried the WiFiMulti example, but was not able to get it work. Probably made a mistake when integrating it to my temperature measurement code. At the moment I am happy with the code J-M-L provided.
I made a temperature measurement box that has waterproof Dallas temperature sensor and one button. If i press the blue button the LED inside will blink and the device automatically connects to predefined wifi network, logs in to M2X database and sends temperature value in every 15 minutes (every time the LED inside blue button will blink 3 times). It works on 3 AA batteries. So far it has worked 3 days in a row.
Thank you!
So far all the projects that I have done, have not beed finalized. Usually a breadboard with a lot of wires and Arduino or Raspberry Pi. Since now I am trying to make a final product from every device that I create. These are high quality boxes (Made In Canada, Hammon) and are quite cheap ~ 3 euros.
Are you sleeping your arduino for power conservation? that's usually a big challenge for projects embedded in a box.
Also in the code I offered above, you can get rid of all the Serial.prints as they don't bring much in production code. was more for you to see what's going on when testing.
Yes, I commented out all Serial.Print-s. Also Serial.Begin .
I have not thought about power saving. The waiting is done by "delay(900000);" which is 15 minutes.
that's an active wait eating up your battery. you should read about power savings modes (depends on your type of arduino). Nick has a good introduction write up for the concept applying to the Atmega328P processor, so won't be exactly the same for you but worth exploring. there is this article you can read for an ESP
if you get your device up for only 10 seconds every 15 minutes your battery will last 90 times more,... which will be months instead of days, if you need it up only for 1 second every 15 min it will be 900 times longer, years instead of days (exaggerating a bit)... worth thinking about it