找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 7445|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

【零知ESP8266】教程:MESH 組網(wǎng)示例

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
本帖最后由 roc2 于 2019-6-19 11:54 編輯

1、概述
MESH組網(wǎng)技術(shù)在IOT領(lǐng)域具有非常大的作用,應(yīng)用非常廣泛,主流的無(wú)線技術(shù)從最開(kāi)始的Zigbee,到藍(lán)牙,到這里的WIFI都實(shí)現(xiàn)了MESH組網(wǎng)技術(shù)。在這里使用零知開(kāi)源平臺(tái)演示W(wǎng)IFI WESH組網(wǎng)的使用。
2、軟件和硬件
硬件使用零知-ESP8266;

軟件使用零知開(kāi)發(fā)工具,自帶示例:

3、方法步驟
(1)先在零知開(kāi)發(fā)工具中打開(kāi)HelloMesh示例,或者復(fù)制下面的代碼到零知開(kāi)發(fā)工具中:
  1. /**********************************************************
  2. *    文件: x.ino      by 零知實(shí)驗(yàn)室
  3. *    -^^- 零知開(kāi)源,讓電子制作變得更簡(jiǎn)單! -^^-
  4. *    時(shí)間: 2019/05/28 12:22
  5. *    說(shuō)明:
  6. ************************************************************/
  7. #include <ESP8266WiFi.h>
  8. #include <ESP8266WiFiMesh.h>
  9. #include <TypeConversionFunctions.h>
  10. #include <assert.h>

  11. const char exampleMeshName[] PROGMEM = "MeshNode_";
  12. const char exampleWiFiPassword[] PROGMEM = "123456789";//ChangeThisWiFiPassword_TODO

  13. unsigned int requestNumber = 0;
  14. unsigned int responseNumber = 0;

  15. String manageRequest(const String &request, ESP8266WiFiMesh &meshInstance);
  16. transmission_status_t manageResponse(const String &response, ESP8266WiFiMesh &meshInstance);
  17. void networkFilter(int numberOfNetworks, ESP8266WiFiMesh &meshInstance);

  18. /* Create the mesh node object */
  19. ESP8266WiFiMesh meshNode = ESP8266WiFiMesh(manageRequest, manageResponse, networkFilter, FPSTR(exampleWiFiPassword), FPSTR(exampleMeshName), "", true);

  20. /**
  21.    Callback for when other nodes send you a request

  22.    @param request The request string received from another node in the mesh
  23.    @param meshInstance The ESP8266WiFiMesh instance that called the function.
  24.    @returns The string to send back to the other node
  25. */
  26. String manageRequest(const String &request, ESP8266WiFiMesh &meshInstance) {
  27.   // We do not store strings in flash (via F()) in this function.
  28.   // The reason is that the other node will be waiting for our response,
  29.   // so keeping the strings in RAM will give a (small) improvement in response time.
  30.   // Of course, it is advised to adjust this approach based on RAM requirements.

  31.   /* Print out received message */
  32.   Serial.print("Request received: ");
  33.   Serial.println(request);

  34.   /* return a string to send back */
  35.   return ("Hello world response #" + String(responseNumber++) + " from " + meshInstance.getMeshName() + meshInstance.getNodeID() + ".");
  36. }

  37. /**
  38.    Callback for when you get a response from other nodes

  39.    @param response The response string received from another node in the mesh
  40.    @param meshInstance The ESP8266WiFiMesh instance that called the function.
  41.    @returns The status code resulting from the response, as an int
  42. */
  43. transmission_status_t manageResponse(const String &response, ESP8266WiFiMesh &meshInstance) {
  44.   transmission_status_t statusCode = TS_TRANSMISSION_COMPLETE;

  45.   /* Print out received message */
  46.   Serial.print(F("Request sent: "));
  47.   Serial.println(meshInstance.getMessage());
  48.   Serial.print(F("Response received: "));
  49.   Serial.println(response);

  50.   // Our last request got a response, so time to create a new request.
  51.   meshInstance.setMessage(String(F("Hello world request #")) + String(++requestNumber) + String(F(" from "))
  52.                           + meshInstance.getMeshName() + meshInstance.getNodeID() + String(F(".")));

  53.   // (void)meshInstance; // This is useful to remove a "unused parameter" compiler warning. Does nothing else.
  54.   return statusCode;
  55. }

  56. /**
  57.    Callback used to decide which networks to connect to once a WiFi scan has been completed.

  58.    @param numberOfNetworks The number of networks found in the WiFi scan.
  59.    @param meshInstance The ESP8266WiFiMesh instance that called the function.
  60. */
  61. void networkFilter(int numberOfNetworks, ESP8266WiFiMesh &meshInstance) {
  62.   for (int networkIndex = 0; networkIndex < numberOfNetworks; ++networkIndex) {
  63.     String currentSSID = WiFi.SSID(networkIndex);
  64.     int meshNameIndex = currentSSID.indexOf(meshInstance.getMeshName());

  65.     /* Connect to any _suitable_ APs which contain meshInstance.getMeshName() */
  66.     if (meshNameIndex >= 0) {
  67.       uint64_t targetNodeID = stringToUint64(currentSSID.substring(meshNameIndex + meshInstance.getMeshName().length()));

  68.       if (targetNodeID < stringToUint64(meshInstance.getNodeID())) {
  69.         ESP8266WiFiMesh::connectionQueue.push_back(NetworkInfo(networkIndex));
  70.       }
  71.     }
  72.   }
  73. }

  74. void setup() {
  75.   // Prevents the flash memory from being worn out, see: https://github.com/esp8266/Arduino/issues/1054 .
  76.   // 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.
  77.   WiFi.persistent(false);

  78.   Serial.begin(115200);
  79.   delay(50); // Wait for Serial.

  80.   //yield(); // Use this if you don't want to wait for Serial.

  81.   // The WiFi.disconnect() ensures that the WiFi is working correctly. If this is not done before receiving WiFi connections,
  82.   // those WiFi connections will take a long time to make or sometimes will not work at all.
  83.   WiFi.disconnect();

  84.   Serial.println();
  85.   Serial.println();

  86.   Serial.println(F("Note that this library can use static IP:s for the nodes to speed up connection times.\n"
  87.                    "Use the setStaticIP method as shown in this example to enable this.\n"
  88.                    "Ensure that nodes connecting to the same AP have distinct static IP:s.\n"
  89.                    "Also, remember to change the default mesh network password!\n\n"));

  90.   Serial.println(F("Setting up mesh node..."));

  91.   /* Initialise the mesh node */
  92.   meshNode.begin();
  93.   meshNode.activateAP(); // Each AP requires a separate server port.
  94. //  meshNode.setStaticIP(IPAddress(192, 168, 4, 22)); // Activate static IP mode to speed up connection times.
  95. }

  96. int32_t timeOfLastScan = -10000;
  97. void loop() {
  98.   if (millis() - timeOfLastScan > 3000 // Give other nodes some time to connect between data transfers.
  99.       || (WiFi.status() != WL_CONNECTED && millis() - timeOfLastScan > 2000)) { // Scan for networks with two second intervals when not already connected.
  100.     String request = String(F("Hello world request #")) + String(requestNumber) + String(F(" from ")) + meshNode.getMeshName() + meshNode.getNodeID() + String(F("."));
  101.     meshNode.attemptTransmission(request, false);
  102.     timeOfLastScan = millis();

  103.     // One way to check how attemptTransmission worked out
  104.     if (ESP8266WiFiMesh::latestTransmissionSuccessful()) {
  105.       Serial.println(F("Transmission successful."));
  106.     }

  107.     // Another way to check how attemptTransmission worked out
  108.     if (ESP8266WiFiMesh::latestTransmissionOutcomes.empty()) {
  109.       Serial.println(F("No mesh AP found."));
  110.     } else {
  111.       for (TransmissionResult &transmissionResult : ESP8266WiFiMesh::latestTransmissionOutcomes) {
  112.         if (transmissionResult.transmissionStatus == TS_TRANSMISSION_FAILED) {
  113.           Serial.println(String(F("Transmission failed to mesh AP ")) + transmissionResult.SSID);
  114.         } else if (transmissionResult.transmissionStatus == TS_CONNECTION_FAILED) {
  115.           Serial.println(String(F("Connection failed to mesh AP ")) + transmissionResult.SSID);
  116.         } else if (transmissionResult.transmissionStatus == TS_TRANSMISSION_COMPLETE) {
  117.           // No need to do anything, transmission was successful.
  118.         } else {
  119.           Serial.println(String(F("Invalid transmission status for ")) + transmissionResult.SSID + String(F("!")));
  120.           assert(F("Invalid transmission status returned from responseHandler!") && false);
  121.         }
  122.       }
  123.     }
  124.     Serial.println();
  125.   } else {
  126.     /* Accept any incoming connections */
  127.     meshNode.acceptRequest();
  128.   }
  129. }
復(fù)制代碼
(2)驗(yàn)證并上傳上述代碼到零知-ESP8266開(kāi)發(fā)板;
(3)測(cè)試:分別把上述代碼上傳到兩個(gè)零知-ESP8266開(kāi)發(fā)板,然后分別連接兩個(gè)板子的串口調(diào)試窗口,然后就可以看到兩個(gè)節(jié)點(diǎn)數(shù)據(jù)傳輸信息了:

注意:密碼修改時(shí)候字符要大于8個(gè)字符,不然會(huì)一直提示No mesh AP found。

更多詳細(xì)資料可到零知實(shí)驗(yàn)室官網(wǎng)免費(fèi)獲取。





分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表