本帖最后由 roc2 于 2019-6-19 11:54 編輯
1、概述
MESH組網技術在IOT領域具有非常大的作用,應用非常廣泛,主流的無線技術從最開始的Zigbee,到藍牙,到這里的WIFI都實現了MESH組網技術。在這里使用零知開源平臺演示WIFI WESH組網的使用。 2、軟件和硬件硬件使用零知-ESP8266;
實物圖1.png (185.28 KB, 下載次數: 85)
下載附件
2019-6-19 11:53 上傳
軟件使用零知開發工具,自帶示例:
示例.jpg (163.95 KB, 下載次數: 73)
下載附件
2019-6-19 11:47 上傳
3、方法步驟(1)先在零知開發工具中打開HelloMesh示例,或者復制下面的代碼到零知開發工具中: - /**********************************************************
- * 文件: x.ino by 零知實驗室
- * -^^- 零知開源,讓電子制作變得更簡單! -^^-
- * 時間: 2019/05/28 12:22
- * 說明:
- ************************************************************/
- #include <ESP8266WiFi.h>
- #include <ESP8266WiFiMesh.h>
- #include <TypeConversionFunctions.h>
- #include <assert.h>
-
- const char exampleMeshName[] PROGMEM = "MeshNode_";
- const char exampleWiFiPassword[] PROGMEM = "123456789";//ChangeThisWiFiPassword_TODO
-
- 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, FPSTR(exampleWiFiPassword), FPSTR(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) {
- // We do not store strings in flash (via F()) in this function.
- // The reason is that the other node will be waiting for our response,
- // so keeping the strings in RAM will give a (small) improvement in response time.
- // Of course, it is advised to adjust this approach based on RAM requirements.
-
- /* 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 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(F("Request sent: "));
- Serial.println(meshInstance.getMessage());
- Serial.print(F("Response received: "));
- Serial.println(response);
-
- // Our last request got a response, so time to create a new request.
- meshInstance.setMessage(String(F("Hello world request #")) + String(++requestNumber) + String(F(" from "))
- + meshInstance.getMeshName() + meshInstance.getNodeID() + String(F(".")));
-
- // (void)meshInstance; // This is useful to remove a "unused parameter" compiler warning. Does nothing else.
- return statusCode;
- }
-
- /**
- 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 networkIndex = 0; networkIndex < numberOfNetworks; ++networkIndex) {
- String currentSSID = WiFi.SSID(networkIndex);
- int meshNameIndex = currentSSID.indexOf(meshInstance.getMeshName());
-
- /* Connect to any _suitable_ APs which contain meshInstance.getMeshName() */
- if (meshNameIndex >= 0) {
- uint64_t targetNodeID = stringToUint64(currentSSID.substring(meshNameIndex + meshInstance.getMeshName().length()));
-
- if (targetNodeID < stringToUint64(meshInstance.getNodeID())) {
- ESP8266WiFiMesh::connectionQueue.push_back(NetworkInfo(networkIndex));
- }
- }
- }
- }
-
- 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.
-
- // The WiFi.disconnect() ensures that the WiFi is working correctly. If this is not done before receiving WiFi connections,
- // those WiFi connections will take a long time to make or sometimes will not work at all.
- WiFi.disconnect();
-
- Serial.println();
- Serial.println();
-
- Serial.println(F("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(F("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 = String(F("Hello world request #")) + String(requestNumber) + String(F(" from ")) + meshNode.getMeshName() + meshNode.getNodeID() + String(F("."));
- meshNode.attemptTransmission(request, false);
- timeOfLastScan = millis();
-
- // One way to check how attemptTransmission worked out
- if (ESP8266WiFiMesh::latestTransmissionSuccessful()) {
- Serial.println(F("Transmission successful."));
- }
-
- // Another way to check how attemptTransmission worked out
- if (ESP8266WiFiMesh::latestTransmissionOutcomes.empty()) {
- Serial.println(F("No mesh AP found."));
- } else {
- for (TransmissionResult &transmissionResult : ESP8266WiFiMesh::latestTransmissionOutcomes) {
- if (transmissionResult.transmissionStatus == TS_TRANSMISSION_FAILED) {
- Serial.println(String(F("Transmission failed to mesh AP ")) + transmissionResult.SSID);
- } else if (transmissionResult.transmissionStatus == TS_CONNECTION_FAILED) {
- Serial.println(String(F("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(String(F("Invalid transmission status for ")) + transmissionResult.SSID + String(F("!")));
- assert(F("Invalid transmission status returned from responseHandler!") && false);
- }
- }
- }
- Serial.println();
- } else {
- /* Accept any incoming connections */
- meshNode.acceptRequest();
- }
- }
復制代碼 (2)驗證并上傳上述代碼到零知-ESP8266開發板;(3)測試:分別把上述代碼上傳到兩個零知-ESP8266開發板,然后分別連接兩個板子的串口調試窗口,然后就可以看到兩個節點數據傳輸信息了:
結果.jpg (235.95 KB, 下載次數: 83)
下載附件
2019-6-19 11:50 上傳
注意:密碼修改時候字符要大于8個字符,不然會一直提示No mesh AP found。
更多詳細資料可到零知實驗室官網免費獲取。
|