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