Adafruit Library
Wippersnapper_ESP8266.h
Go to the documentation of this file.
1 
17 #ifndef WIPPERSNAPPER_ESP8266_H
18 #define WIPPERSNAPPER_ESP8266_H
19 
20 #ifdef ARDUINO_ARCH_ESP8266
21 #include "Adafruit_MQTT.h"
22 #include "Adafruit_MQTT_Client.h"
23 #include "ESP8266WiFi.h"
24 #include "ESP8266WiFiMulti.h"
25 #include "Wippersnapper.h"
26 
27 class Wippersnapper_ESP8266;
28 extern Wippersnapper_ESP8266 WS;
29 
30 /* NOTE - As of 07/21/26, this library no longer supports "Secure MQTT"
31  * (TLS/SSL) on the ESP8266 due to new automatic certificate updates that
32  * require a new certificate every 199 days (or less) -
33  * https://forums.adafruit.com/viewtopic.php?t=224362 If you would like a secure
34  * Adafruit IO Arduino project, please switch to using the modern ESP32 (and
35  * related models) instead of the ESP8266.
36  */
37 
38 /******************************************************************************/
43 /******************************************************************************/
44 class Wippersnapper_ESP8266 : public Wippersnapper {
45 
46 public:
47  /**************************************************************************/
59  /**************************************************************************/
60  Wippersnapper_ESP8266() : Wippersnapper() {
61  _ssid = 0;
62  _pass = 0;
63  _wifi_client = new WiFiClient;
64  WiFi.persistent(false);
65  WiFi.mode(WIFI_STA);
66  }
67 
68  /**************************************************************************/
72  /**************************************************************************/
73  ~Wippersnapper_ESP8266() {
74  if (_wifi_client)
75  delete _wifi_client;
76  if (_mqtt)
77  delete _mqtt;
78  }
79 
80  /**********************************************************/
88  /**********************************************************/
89  void set_ssid_pass(const char *ssid, const char *ssidPassword) {
90  _ssid = ssid;
91 
92  // set the AP password
93  // check if ssidPassword was "" in secrets.json
94  if ((ssidPassword != NULL) && (strlen(ssidPassword) == 0)) {
95  _pass = NULL; // Set as NULL for open networks
96  } else {
97  _pass = ssidPassword;
98  }
99  }
100 
101  /**********************************************************/
106  /**********************************************************/
107  void set_ssid_pass() {
108  _ssid = WS._config.network.ssid;
109  _pass = WS._config.network.pass;
110  }
111 
112  /***********************************************************/
117  /***********************************************************/
118  bool check_valid_ssid() {
119  // Set WiFi to station mode and disconnect from an AP if it was previously
120  // connected
121  WiFi.mode(WIFI_STA);
122  WiFi.disconnect();
123  delay(100);
124 
125  // Perform a network scan
126  int n = WiFi.scanNetworks();
127  if (n == 0) {
128  WS_DEBUG_PRINTLN("ERROR: No WiFi networks found!");
129  return false;
130  }
131 
132  bool foundNetwork = false;
133 
134  WS_DEBUG_PRINTLN("WipperSnapper found these WiFi networks:");
135  for (uint8_t i = 0; i < n; i++) {
136  if (!foundNetwork && strcmp(WiFi.SSID(i).c_str(), _ssid) == 0) {
137  foundNetwork = true;
138  } else if (!foundNetwork && WS._isWiFiMulti) {
139  // multi network mode
140  for (int j = 0; j < WS_MAX_ALT_WIFI_NETWORKS; j++) {
141  if (strcmp(WS._multiNetworks[j].ssid, WiFi.SSID(i).c_str()) == 0) {
142  foundNetwork = true;
143  }
144  }
145  }
146  WS_DEBUG_PRINTVAR(WiFi.SSID(i));
147  WS_DEBUG_PRINT(" (");
148  uint8_t BSSID[WL_MAC_ADDR_LENGTH];
149  memcpy(BSSID, WiFi.BSSID(i), WL_MAC_ADDR_LENGTH);
150  for (int m = 0; m < WL_MAC_ADDR_LENGTH; m++) {
151  if (m != 0)
152  WS_DEBUG_PRINT(":");
153  WS_DEBUG_PRINTHEX(BSSID[m]);
154  }
155  WS_DEBUG_PRINT(") ");
156  WS_DEBUG_PRINTVAR(WiFi.RSSI(i));
157  WS_DEBUG_PRINT("dB (ch");
158  WS_DEBUG_PRINTVAR(WiFi.channel(i))
159  WS_DEBUG_PRINTLN(")");
160  }
161 
162  if (!foundNetwork) {
163  WS_DEBUG_PRINTLN("ERROR: Your requested WiFi network was not found!");
164  }
165  return foundNetwork;
166  }
167 
168  /********************************************************/
173  /********************************************************/
174  void getMacAddr() {
175  uint8_t mac[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
176  WiFi.macAddress(mac);
177  memcpy(WS._macAddr, mac, sizeof(mac));
178  }
179 
180  /********************************************************/
185  /********************************************************/
186  int32_t getRSSI() { return WiFi.RSSI(); }
187 
188  /*******************************************************************/
194  /*******************************************************************/
195  void setupMQTTClient(const char *clientID) {
196  if (WS._config.io_port == 8883)
197  WS._config.io_port = 1883;
198  WS._mqtt = new Adafruit_MQTT_Client(
199  _wifi_client, WS._config.aio_url, WS._config.io_port, clientID,
200  WS._config.aio_user, WS._config.aio_key);
201  }
202 
203  /********************************************************/
208  /********************************************************/
210  switch (WiFi.status()) {
211  case WL_CONNECTED:
212  return WS_NET_CONNECTED;
213  case WL_CONNECT_FAILED:
214  return WS_NET_CONNECT_FAILED;
215  case WL_IDLE_STATUS:
216  return WS_IDLE;
217  default:
218  return WS_NET_DISCONNECTED;
219  }
220  }
221 
222  /*******************************************************************/
227  /*******************************************************************/
228  const char *connectionType() { return "ESP8266"; }
229 
230 protected:
231  const char *_ssid = NULL;
232  const char *_pass = NULL;
233  WiFiClient *_wifi_client;
234  ESP8266WiFiMulti _wifiMulti;
235 
236  /**************************************************************************/
240  /**************************************************************************/
241  void _connect() {
242 
243  if (WiFi.status() == WL_CONNECTED)
244  return;
245 
246  if (strlen(_ssid) == 0) {
247  _status = WS_SSID_INVALID;
248  } else {
249  WiFi.setAutoReconnect(false);
250  // Attempt connection
251  _disconnect();
252  delay(100);
253  // ESP8266 MUST be in STA mode to avoid device acting as client/server
254  WiFi.mode(WIFI_STA);
255  _status = WS_NET_DISCONNECTED;
256  delay(100);
257 
258  if (WS._isWiFiMulti) {
259  // multi network mode
260  for (int i = 0; i < WS_MAX_ALT_WIFI_NETWORKS; i++) {
261  if (strlen(WS._multiNetworks[i].ssid) > 0 &&
262  (_wifiMulti.existsAP(WS._multiNetworks[i].ssid) == false)) {
263  // doesn't exist, add it
264  _wifiMulti.addAP(WS._multiNetworks[i].ssid,
265  WS._multiNetworks[i].pass);
266  }
267  }
268  }
269 
270  // add default network
271  if (_wifiMulti.existsAP(_ssid) == false) {
272  _wifiMulti.addAP(_ssid, _pass);
273  }
274 
275  long startRetry = millis();
276  WS_DEBUG_PRINTLN("CONNECTING");
277 
278  while (_wifiMulti.run(5000) != WL_CONNECTED &&
279  millis() - startRetry < 10000) {
280  // ESP8266 WDT requires yield() during a busy-loop so it doesn't bite
281  yield();
282  }
283 
284  if (WiFi.status() == WL_CONNECTED) {
285  _status = WS_NET_CONNECTED;
286  } else {
287  _status = WS_NET_DISCONNECTED;
288  }
289 
290  WS.feedWDT();
291  }
292  }
293 
294  /**************************************************************************/
298  /**************************************************************************/
299  void _disconnect() {
300  WiFi.disconnect();
301  delay(500);
302  }
303 };
304 
305 #endif // ARDUINO_ARCH_ESP8266
306 #endif // WIPPERSNAPPER_ESP8266_H
virtual void setupMQTTClient(const char *clientID)
Sets up the MQTT client session.
Definition: Wippersnapper.cpp:187
#define WS_DEBUG_PRINT(...)
Prints debug output.
Definition: Wippersnapper.h:63
#define WS_DEBUG_PRINTHEX(...)
Prints in hexadecimal.
Definition: Wippersnapper.h:78
#define WS_DEBUG_PRINTVAR(...)
Prints variable (any type)
Definition: Wippersnapper.h:72
secretsConfig _config
Definition: Wippersnapper.h:432
#define WL_MAC_ADDR_LENGTH
MAC address length - from RP2040 BSP.
Definition: Wippersnapper_Networking.h:20
ws_status_t
Definition: Wippersnapper.h:219
virtual bool check_valid_ssid()
Performs a scan of local WiFi networks.
Definition: Wippersnapper.cpp:232
Class that provides storage and functions for the Adafruit IO Wippersnapper interface.
Definition: Wippersnapper.h:311
virtual void _connect()
Connects to wireless network.
Definition: Wippersnapper.cpp:146
#define WS_MAX_ALT_WIFI_NETWORKS
Maximum number of alternative networks.
Definition: Wippersnapper.h:280
virtual void getMacAddr()
Sets the network interface&#39;s unique identifier, typically the MAC address.
Definition: Wippersnapper.cpp:165
virtual void set_ssid_pass()
Sets the device&#39;s wireless network credentials from the secrets.json configuration file...
Definition: Wippersnapper.cpp:222
void feedWDT()
Feeds the WDT to prevent hardware reset.
Definition: Wippersnapper.cpp:2645
bool _isWiFiMulti
Definition: Wippersnapper.h:434
networkConfig _multiNetworks[3]
Definition: Wippersnapper.h:433
#define WS_DEBUG_PRINTLN(...)
Prints line from debug output.
Definition: Wippersnapper.h:66
Wippersnapper_AIRLIFT WS
Global instance of Wippersnapper_WiFi.
Definition: Wippersnapper.cpp:38
uint8_t _macAddr[6]
Definition: Wippersnapper.h:426
Adafruit_MQTT * _mqtt
Definition: Wippersnapper.h:430
virtual ws_status_t networkStatus()
Returns the network&#39;s connection status.
Definition: Wippersnapper.cpp:197
virtual int32_t getRSSI()
Gets the network&#39;s RSSI.
Definition: Wippersnapper.cpp:175
virtual void _disconnect()
Disconnect Wippersnapper MQTT session and network.
Definition: Wippersnapper.cpp:155