mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-21 10:26:06 +03:00
* Make mesh network actually usable. Make mesh network use static IP during initial connection to speed up connection time. Add separate handlers for requests and responses. Add network password. Provide more detailed code example. Add optional verbose mode. Improve comments. Add readme file. * Fix compiler warnings. Fix code style of HelloMesh.ino to avoid upsetting Travis. * Remove stray spaces. * Make mesh network WiFi password settable via the ESP8266WiFiMesh constructor. Make use of static IP optional by moving static IP initialization code to setStaticIP method. Increase scanning interval from one to two seconds in the HelloMesh.ino example to increase chances of successful connections. Update comments. Update README.rst. * Increase specificity in the conditions of the waitForClientTransmission method (renamed from waitForClient) to avoid issues related to #4626 , #4728 and #4754 in the future. * Improve most parts of the library to achieve better performance and greatly increase flexibility. Changes: * Make WiFi-connection related variables static to allow for the use of multiple ESP8266WiFiMesh instances on a single node (useful e.g. when communicating with several different mesh networks). * Make it possible to choose AP port, which is helpful when using multiple ESP8266WiFiMesh AP:s on a single node. * Add user-customizable network filter. * Make activation of own AP optional for each mesh node. * Add ways to change mesh network name and node id for existing ESP8266WiFiMesh instances. * Add verboseModePrint method to clean up the code. * Add reactivation of static IP after successful data transfers to speed up re-connection attempts. * Add empty_IP constant which can be used to check if static IP is disabled for a ESP8266WiFiMesh instance. * Remove the WiFiClient _client class variable in ESP8266WiFiMesh since there is no need to save _client in the class instance. * Add transmission status as a return value from attemptTransmission. * Pass calling ESP8266WiFiMesh instance pointer to callback functions to allow for greater range of actions in callbacks. * Make transmission message a class variable to allow it to be stored in the class and accessed from callbacks. * Add getters for mesh name and node id to ESP8266WiFiMesh. * Add getter and setter for networkFilter to ESP8266WiFiMesh. * Increase range of available node_id:s by changing the type to String and adding functions to convert between String and uint64_t using a customizable radix between 2 and 36. * Make it possible to connect to several nodes during each attemptTransmission call. * Add static connection_queue and latest_transmission_outcomes vectors to the ESP8266WiFiMesh class, a NetworkInfo class and a TransmissionResult class to aid in bookkeeping when connecting to several AP:s during one attemptTransmission call. * Make wifi_channel and BSSID optional when connecting to an AP (though excluding them will slow down the connection process). * Add optional scan and static ip optimizations available in Arduino core for ESP8266 version 2.4.2. * Add functions to check lwIP version in order to enable WiFi optimizations only available with lwIP2. * Add concluding_disconnect, initial_disconnect and no_scan options to the attemptTransmission method. * Update documentation. * Improve README.rst formatting. * Further improve README.rst. * Even further improve README.rst. * Make source code comments Doxygen compatible. Improve README file and change its file format to .md. * Add temporary compatibility layer to ensure backwards compatibility with the old mesh network library API until the next major core release (2.5.0). * Polish documentation slightly. * Add scan_all_wifi_channels option to attemptTransmission method. * - Add getter and setter for the WiFi channel of a ESP8266WiFiMesh instance. - Separate methods for changing mesh name and node id from AP control methods. - Add methods getAPController and isAPController to better handle situations when multiple ESP8266WiFiMesh instances take turns to be in control of the AP. - Create separate UtilityMethods.cpp file for utility methods. - Improve code efficiency and robustness, e.g. by passing arguments by reference instead of by value for non-POD types and employing typedefs. - Update README.md. * Make the code more stylish. * Update README.md with the new ESP8266WiFiMesh constructor documentation. * Make attemptScan method in CompatibilityLayer use reference as argument. * Make it possible to use const String as argument to attemptScan. * - Make code use camelCase instead of snake_case. - Improve documentation. * Rename Uint64ToString to uint64ToString and StringToUint64 to stringToUint64, since they are methods.
132 lines
5.6 KiB
C++
132 lines
5.6 KiB
C++
#include <ESP8266WiFi.h>
|
|
#include <ESP8266WiFiMesh.h>
|
|
|
|
String exampleMeshName("MeshNode_");
|
|
|
|
unsigned int requestNumber = 0;
|
|
unsigned int responseNumber = 0;
|
|
|
|
String manageRequest(const String &request, ESP8266WiFiMesh &meshInstance);
|
|
transmission_status_t manageResponse(const String &response, ESP8266WiFiMesh &meshInstance);
|
|
void networkFilter(int numberOfNetworks, ESP8266WiFiMesh &meshInstance);
|
|
|
|
/* Create the mesh node object */
|
|
ESP8266WiFiMesh meshNode = ESP8266WiFiMesh(manageRequest, manageResponse, networkFilter, "ChangeThisWiFiPassword_TODO", exampleMeshName, "", true);
|
|
|
|
/**
|
|
Callback for when other nodes send you a request
|
|
|
|
@param request The request string received from another node in the mesh
|
|
@param meshInstance The ESP8266WiFiMesh instance that called the function.
|
|
@returns The string to send back to the other node
|
|
*/
|
|
String manageRequest(const String &request, ESP8266WiFiMesh &meshInstance) {
|
|
/* Print out received message */
|
|
Serial.print("Request received: ");
|
|
Serial.println(request);
|
|
|
|
/* return a string to send back */
|
|
return ("Hello world response #" + String(responseNumber++) + " from " + meshInstance.getMeshName() + meshInstance.getNodeID() + ".");
|
|
}
|
|
|
|
/**
|
|
Callback used to decide which networks to connect to once a WiFi scan has been completed.
|
|
|
|
@param numberOfNetworks The number of networks found in the WiFi scan.
|
|
@param meshInstance The ESP8266WiFiMesh instance that called the function.
|
|
*/
|
|
void networkFilter(int numberOfNetworks, ESP8266WiFiMesh &meshInstance) {
|
|
for (int i = 0; i < numberOfNetworks; ++i) {
|
|
String currentSSID = WiFi.SSID(i);
|
|
int meshNameIndex = currentSSID.indexOf(meshInstance.getMeshName());
|
|
|
|
/* Connect to any _suitable_ APs which contain meshInstance.getMeshName() */
|
|
if (meshNameIndex >= 0) {
|
|
uint64_t targetNodeID = ESP8266WiFiMesh::stringToUint64(currentSSID.substring(meshNameIndex + meshInstance.getMeshName().length()));
|
|
|
|
if (targetNodeID < ESP8266WiFiMesh::stringToUint64(meshInstance.getNodeID())) {
|
|
ESP8266WiFiMesh::connectionQueue.push_back(NetworkInfo(i));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
Callback for when you get a response from other nodes
|
|
|
|
@param response The response string received from another node in the mesh
|
|
@param meshInstance The ESP8266WiFiMesh instance that called the function.
|
|
@returns The status code resulting from the response, as an int
|
|
*/
|
|
transmission_status_t manageResponse(const String &response, ESP8266WiFiMesh &meshInstance) {
|
|
transmission_status_t statusCode = TS_TRANSMISSION_COMPLETE;
|
|
|
|
/* Print out received message */
|
|
Serial.print("Request sent: ");
|
|
Serial.println(meshInstance.getMessage());
|
|
Serial.print("Response received: ");
|
|
Serial.println(response);
|
|
|
|
// Our last request got a response, so time to create a new request.
|
|
meshInstance.setMessage("Hello world request #" + String(++requestNumber) + " from " + meshInstance.getMeshName() + meshInstance.getNodeID() + ".");
|
|
|
|
// (void)meshInstance; // This is useful to remove a "unused parameter" compiler warning. Does nothing else.
|
|
return statusCode;
|
|
}
|
|
|
|
void setup() {
|
|
// Prevents the flash memory from being worn out, see: https://github.com/esp8266/Arduino/issues/1054 .
|
|
// This will however delay node WiFi start-up by about 700 ms. The delay is 900 ms if we otherwise would have stored the WiFi network we want to connect to.
|
|
WiFi.persistent(false);
|
|
|
|
Serial.begin(115200);
|
|
delay(50); // Wait for Serial.
|
|
|
|
//yield(); // Use this if you don't want to wait for Serial.
|
|
|
|
Serial.println();
|
|
Serial.println();
|
|
|
|
Serial.println("Note that this library can use static IP:s for the nodes to speed up connection times.\n"
|
|
"Use the setStaticIP method as shown in this example to enable this.\n"
|
|
"Ensure that nodes connecting to the same AP have distinct static IP:s.\n"
|
|
"Also, remember to change the default mesh network password!\n\n");
|
|
|
|
Serial.println("Setting up mesh node...");
|
|
|
|
/* Initialise the mesh node */
|
|
meshNode.begin();
|
|
meshNode.activateAP(); // Each AP requires a separate server port.
|
|
meshNode.setStaticIP(IPAddress(192, 168, 4, 22)); // Activate static IP mode to speed up connection times.
|
|
}
|
|
|
|
int32_t timeOfLastScan = -10000;
|
|
void loop() {
|
|
if (millis() - timeOfLastScan > 3000 // Give other nodes some time to connect between data transfers.
|
|
|| (WiFi.status() != WL_CONNECTED && millis() - timeOfLastScan > 2000)) { // Scan for networks with two second intervals when not already connected.
|
|
String request = "Hello world request #" + String(requestNumber) + " from " + meshNode.getMeshName() + meshNode.getNodeID() + ".";
|
|
meshNode.attemptTransmission(request, false);
|
|
timeOfLastScan = millis();
|
|
|
|
if (ESP8266WiFiMesh::latestTransmissionOutcomes.empty()) {
|
|
Serial.println("No mesh AP found.");
|
|
} else {
|
|
for (TransmissionResult &transmissionResult : ESP8266WiFiMesh::latestTransmissionOutcomes) {
|
|
if (transmissionResult.transmissionStatus == TS_TRANSMISSION_FAILED) {
|
|
Serial.println("Transmission failed to mesh AP " + transmissionResult.SSID);
|
|
} else if (transmissionResult.transmissionStatus == TS_CONNECTION_FAILED) {
|
|
Serial.println("Connection failed to mesh AP " + transmissionResult.SSID);
|
|
} else if (transmissionResult.transmissionStatus == TS_TRANSMISSION_COMPLETE) {
|
|
// No need to do anything, transmission was successful.
|
|
} else {
|
|
Serial.println("Invalid transmission status for " + transmissionResult.SSID + "!");
|
|
}
|
|
}
|
|
}
|
|
Serial.println();
|
|
} else {
|
|
/* Accept any incoming connections */
|
|
meshNode.acceptRequest();
|
|
}
|
|
}
|