Closed madmacks59 closed 4 months ago
Yes, I know, I’ve read that…what I’m looking for is an example of the implementation in code. For example, do i use the call like…
WiFi.begin(“myssid”, “mypassword”, 7, “01:02:C1:33:F1”) Or do I define variables and pass them (which I’ve tried and get compile errors)?
When I try using variables I get a type error for the bssid as the variable type doesn’t match what the method wants, and I cant figure out how to implement the MAC address as the required variable type.
so there is no issue. ok.
? What ?
Running a WiFI scan sketch on the ESP8266 shows the following...
13:24:46.572 -> Starting WiFi scan... 13:24:48.779 -> 4 networks found: 13:24:48.779 -> 00: [CH 03] [3C:52:A1:D4:7F:B5] -68dBm V 802.11b/g/n WPS WIFI-24 13:24:48.779 -> 01: [CH 07] [E8:9C:25:71:85:70] -31dBm V 802.11b/g/n WPS WIFI-24 13:24:48.779 -> 02: [CH 07] [42:F5:20:05:FB:DB] -68dBm V 802.11b/g ESP-05FBDB 13:24:48.779 -> 03: [CH 10] [3C:84:6A:16:D8:0E] -81dBm * V 802.11b/g/n WPS WIFI-24
FYI the ESP shown above is a different device that is connected to the "01" AP, it is not the ESP in the set up I'm working on now...
=============================================================================
In the code I've imlemented the following...
// Variable definitions
const char ssid = "WIFI-24"; const char password = "sillyPassword; const byte bssid[] = {0xE8, 0x9C, 0x25, 0x71, 0x85, 0x70};
// Down in the conncect code
bool wifiConnect() { WiFi.mode(WIFI_STA); WiFi.begin(ssid, password, 07, bssid); if (WiFi.status() == WL_CONNECTED) { delay(1000); Serial.println("Connected to Wi-Fi network"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); return true; } else { Serial.println("Wi-Fi connection failed!"); Serial.println(WiFi.status()); return false; } }
When I run the code I get... 07:45:57.655 -> Wi-Fi connection failed! 07:45:57.655 -> 7
If I change the WiFi.begin code to "WiFi.begin(ssid, password);" and rename the SSID to a unique name like "WIFI-24-X" on the "01" AP and in the code things run just fine.
So it seems to me that the issue is that the ESP is seeing three APs advertising "WIFI-24" and fails to pick the strongest signal AP.
The methond WiFi.begin() implements things as follows as far as I can tell...
Parameters:
const char ssid const char passphrase = 0 int32_t channel = 0 (optional) const uint8_t * bssid = 0 (optional) bool connect = true (optional)
So I believe my basic issue is I really don't understand how to implement the bssid as a "const uint8_t" variable, which means my definition in the above example is crap. So, that's why I'm asking for a code snippet that shows how to define the variable properly to pass to the begin() method and possibly how to use the method without needing to specifiy the channel at all as it could change on router/AP reboot...
add WiFi.waitForConnectionResult() after WiFi.begin
Ok...I'll give that a try. Thank you.
But...
Isn't there anyone that can actually answer the question I'm asking? What I want to learn/understand is how to implement the method as it's defined and published. The library says you should be able to pass the MAC address of the AP you want to connect with, right? But nowhere in the example code or the document is there an actual explanation of how to actually do it. Google searches, and I've done a lot of searching, doesn't turn up a single example of how these parameters can be used.
you don't wait until it connected so you can't know if it connects to bssid or strongest or anything
The function is actually "WiFi.waitForConnectResult()" I think...at least that's what auto complete shows...not that it makes much of a diff. But the real question is the previous one, how to implement the WiFi.begin() properly using it's defined parms...
you have begin
right
Code is shown above. Yes... there is a WiFi.begin(). And after adding the waitFor the wait just times out (-1 returned using 2000 as the timeout). Second loop thru it does connect (using the unique ssid), so I'll play around with the timing and see if it's the radio taking a few seconds to fire up. But, still looing for the info on how to implement the bssid parm...
So... There was apparently some issue with timing.... I reset the router/ap to use the redundant wifi ssid, updated my code with a few delay(500) statements, added back in the bssid definition and the full bssid begin, unplugged, waited for a minute, and plugged back in, and was surprised that things apparently work now. Anyway, below is the code that seems to be working now...
` / Gary M - Propane controller This reads three tempurature sensors and reports them via MQTT and WiFi to the MFR MQTT server. It also looks at the temp reported on sensor #1 (address 0) and if the reported temp is at or below 5 degrees celsius (41 degrees fahrenheit) it opens the main propane valve on the shed heater. It keeps the valve open until the temp reaches 10 degrees celsius (50 degrees fahrenheit). At that temp the valve is closed shuting off the heater. /
// Temp sensor wires connected to D4 (GPIO2)
// Set up oneWire to communicate with devices
OneWire oneWire(ONE_WIRE_BUS);
// Pass oneWire reference to Dallas Temp object
DallasTemperature sensors(&oneWire);
// Number of temperature devices found
int numberOfDevices;
// Relay connected to D2 (GPIO4)
const int RELAY_PIN = 4;
// Temp values (in celsius) used to control relay
float onTemp = 5.0;
float hysteresis = 5.0;
// Instantiate device address
DeviceAddress tempDeviceAddress;
// WiFi connection info (SSID, Password)
const char ssid = "WiFi-24";
const char password = "dummyPassword";
const byte bssid[] = {0xE8, 0x9C, 0x25, 0x71, 0x85, 0x70};
// MQTT broker information
const char mqtt_broker = "192.168.1.98";
const char topic = "house/waterPump";
const int mqtt_port = 1883;
const char *client_id = "ESP8266-HousePump";
// Array of float temp values for the sensors
float sensorTemp[3] = {0,0,0};
// Used to generate the MQTT message packet which looks like...
// {"Topic":"house/pumpShed","Gas":"Off","Temp1":99.9,"Temp2":99.99,"Temp3":99.99}
char msgTopic[26] = "{\"Topic\":\"house/pumpShed\"";
char msgGas[13] = ",\"Gas\":\"Off\""; // Default is Gas Off aka relay off
char msgGasOff[13] = ",\"Gas\":\"Off\"";
char msgGasOn[12] = ",\"Gas\":\"On\"";
char msgSen1[10] = ",\"Temp1\":";
char msgSen2[10] = ",\"Temp2\":";
char msgSen3[10] = ",\"Temp3\":";
char msgSen4[2] = "}";
char mqttTmp1[6];
char mqttTmp2[6];
char mqttTmp3[6];
char mqttMsg[80];
// Instantiate the WiFi object
WiFiClient espClient;
// Instantiate the MQTT object
PubSubClient mqttClient(espClient);
void setup() {
// Start serial port
Serial.begin(9600);
Serial.println("** Just Rebooted **");
// Initialie the relay pin
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
// Start up the sensor library
sensors.begin();
// Waid a sec for sensors to start
delay(1000);
// Grab a count of devices on the oneWire bus
numberOfDevices = sensors.getDeviceCount();
Serial.print("Locating sensor devices...Found ");
Serial.print(numberOfDevices, DEC);
Serial.println(" devices.");
if (numberOfDevices==0) {
Serial.println("Found no temperature sensors, rebooting...");
ESP.restart();
}
// Loop through each device & print out address
for (int i = 0; i < numberOfDevices; i++) {
if (sensors.getAddress(tempDeviceAddress, i)) {
Serial.print("Found device ");
Serial.print(i, DEC);
Serial.print(" with address: ");
printAddress(tempDeviceAddress);
Serial.println();
} else {
Serial.print("Found ghost device at ");
Serial.print(i, DEC);
Serial.println(" but could not detect address. Check power and cabling");
}
}
mqttClient.setServer(mqtt_broker, mqtt_port);
// Wait a second for the radio to fully start...
delay(1000);
if (wifiConnect()) {
if (mqttConnect()) {
Serial.println("Initial connection to WiFi & MQTT Broker was successful...");
mqttClient.disconnect();
}
} else {
Serial.println("Initial connection to WiFi Failed...");
}
}
void loop() { // Read and process the temp sensors sensors.requestTemperatures(); // Wait for sensor buss to reply delay(500); Serial.println("--------------------------------------------------"); // Loop through each device and print out temp data for (int i = 0; i < numberOfDevices; i++) { // Get oneWire address if (sensors.getAddress(tempDeviceAddress, i)) { // Output the device ID Serial.print("Device: "); Serial.print(i, DEC); Serial.print("\t"); // Get the Temp data for the sensor float tempC = sensors.getTempC(tempDeviceAddress); sensorTemp[i] = tempC; Serial.print("Temp C: "); Serial.print(tempC); Serial.print("\tTemp F: "); // Convert tempC to Fahrenheit and print Serial.println(DallasTemperature::toFahrenheit(tempC)); if (i == 0 ) { // If First Sensor (aka 0) if (tempC <= onTemp) { // If tempurature is equal to or lower than on temp if (!digitalRead(RELAY_PIN)) { // If relay is off turn it on digitalWrite(RELAY_PIN, HIGH); Serial.println("Relay On"); strcpy(msgGas, msgGasOn); } } else { // else if (tempC >= (onTemp + hysteresis)) { // if tempurature is equal to or greater than off temp if (digitalRead(RELAY_PIN)) { // If relay is on turn it off digitalWrite(RELAY_PIN, LOW); Serial.println("Relay Off"); strcpy(msgGas, msgGasOff); } } } } } } // If WiFi is disconnected try to reconnect if (WiFi.status() != WL_CONNECTED) { wifiConnect(); }
// Build the MQTT message if WiFi and MQTT Connected if (WiFi.status() == WL_CONNECTED) { if (mqttConnect()) { // Put together the message payload strcpy(mqttMsg, msgTopic); strcat(mqttMsg, msgGas); strcat(mqttMsg, msgSen1); dtostrf(sensorTemp[0], 5, 2, mqttTmp1); strcat(mqttMsg, mqttTmp1); strcat(mqttMsg, msgSen2); dtostrf(sensorTemp[1], 5, 2, mqttTmp2); strcat(mqttMsg, mqttTmp2); strcat(mqttMsg, msgSen3); dtostrf(sensorTemp[2], 5, 2, mqttTmp3); strcat(mqttMsg, mqttTmp3); strcat(mqttMsg, msgSen4); // Send the message if (mqttClient.publish(topic, mqttMsg, false)) { Serial.println("MQTT Msg Published..."); } else { Serial.println("MQTT Msg Failed..."); Serial.print(mqttClient.state()); } // Disconnect from MQTT Broker mqttClient.disconnect(); } } Serial.println(""); // Force print buffer out just in case // delay(3001000); // Wait 5 minute delay(301000); // Wait 30 seconds }
// function to print a device address void printAddress(DeviceAddress deviceAddress) { for (uint8_t i = 0; i < 8; i++) { if (deviceAddress[i] < 16) Serial.print("0"); Serial.print(deviceAddress[i], HEX); } }
// Get a WiFi connection but don't freak if it fails bool wifiConnect() { WiFi.mode(WIFI_STA); WiFi.begin(ssid,password,07,bssid); int chkstat = WiFi.waitForConnectResult(5000); Serial.print("Wait for Connection chkstat="); Serial.println(chkstat); Serial.printf("BSSID: %s\n", WiFi.BSSIDstr().c_str()); if (WiFi.status() == WL_CONNECTED) { delay(500); Serial.println("Connected to Wi-Fi network"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); Serial.print("SSI Strength: "); Serial.println(WiFi.RSSI()); return true; } else { Serial.println("Wi-Fi connection failed!"); Serial.println(WiFi.status()); return false; } }
// Only call if there is a WIFI connection!
// Connected to MQTT but don't freak if it fails.
bool mqttConnect() {
if (mqttClient.connect(client_id)) {
Serial.println("MQTT broker connected");
return true;
} else {
Serial.print("MQTT Broker connection failed!");
Serial.print(mqttClient.state());
return false;
}
}
`
I guess automatic connection to remembered AP was happening parallel with setup(). use some of WiFi.setPeristent(false), WiFi.setAutoReconnect(false), WiFi.erase()
It appears that the issue was possibly due to timing. I'd suggest that some additional examples be added to the doco that show how to use WiFi.begin(ssid,password,channel,bssid) with various options and how to define the parameters more clearly. But that's just the opinion of a relative newbie...
Dang it! I added a bit of unrelated code and now the connection is failing again, exactly as before. I'm reopening this issue again, as I guess the connect with BSSID still is funky...
OK, I found some other info and this may be the issue... I'm running an ASUS RT-AX86U Pro Router and that router uses "802.11ax / WiFi 6 mode" mode as its default. The info I found suggests that WiFi 6 Mode is an issue with the ESP8266 radio, so I turned off the WiFi 6 Mode and now things seem to work reliably. So, is there an issue on the ESP8266 with WiFi 6?
Apparently there is a separate ticket open around this issue. The issues has to do with the newer board cores and the solution is to revert to core 2.5.2 and recompile without some of the newer functions (like WiFi scan). I did that and the board has been processing just fine for the last two days. And with the older core I didnt need to specific the AP MAC address as the library connects to the strongest AP just fine.
Platform
Problem Description
I've been trying to connect to a specific AP using its SSID/Password and the MAC address of the AP. I have several APs spread around my property and most of my devices attach to the strongest AP. In my particular application I want the ESP8266 to connect to a specific AP and ignore all the others. To do this I should be able to use the "WiFi.begin(ssid, password, channel, bssid, connect)" option.
But, I've tried multiple ways to define the bssid parameter properly and none of the are working. Can someone provide an example of how exactly to do this within the Arduino IDE?
And example of the definition code and the call code would really help...