1. 程式人生 > >Arduino使用ESP8266通訊的實踐

Arduino使用ESP8266通訊的實踐

  • 列表內容

一、 背景
nRF24L01的成本較低,但內部需通過SPI通訊,略顯複雜,同時RF過於專用,接入其他系統時需要轉換,不方便。
ESP8266是樂鑫公司推出的廉價、但幾乎全能的WIFI晶片,被各種智慧硬體廣泛使用,根據其datasheet,不但支援SPI,也可通過I2C、UART等方式進行通訊,尤其是UART,直接支援AT指令,大大簡化開發難度,相當便利。本文即採用AT模式。

ESP8266開發板,TB約12塊左右,右側為ESP8266,左側為25Q80BVSIG,1M快閃記憶體。
這裡寫圖片描述

二、接線
1、ESP8266開發板引腳圖
這裡寫圖片描述

  • TX:串列埠寫
  • GND:接地
  • CH_PD:高電平為可用,低電平為關機
  • GPIO2:可懸空
  • RST:重置,可懸空
  • GPIO0:上拉為工作模式,下拉為下載模式,可懸空
  • VCC:3.3V(切不可接5V,燒片)
  • RX:串列埠讀

2、接線示意

ESP8266 ArduinoMega ArduinoUuno
TX 19(RX1) 0(RX0)
GND GND GND
CH_PD 5(自由指定) 5(自由指定)
GPIO2 - -
RST - -
GPIO0 - -
VCC 3.3V 3.3V
RX 18(TX1) 1(TX1)

ESP8266的串列埠預設波特率為115200,mega也可直接接RX0/TX0,
為除錯方便起見,本文中RX0/TX0留做除錯視窗,用RX1/TX1和晶片互動。
如果是UNO,如果要看除錯資訊,只能增加一個軟串列埠。

三、程式碼&執行
雖然可以直接通過串列埠直接讀寫AT指令,但指令較多,處理繁瑣,
找到有如下的庫對AT指令做了封裝,使用十分便利,推薦。
Git地址為:
https://github.com/ekstrand/ESP8266wifi.git

1) ESP8266庫安裝
下載上面的ESP8266的庫後,將其複製到Arduino安裝目錄下的libraries目錄下,啟動ArduinoIDE後,從例子中選擇ESP8266_tcp_cli。
該庫預設支援3個客戶端連線和1個監聽連線,如要增大須修改其標頭檔案中的如下兩個巨集:

define SERVER '4' 
define MAX_CONNECTIONS 3

2) 程式碼修改
該庫設計很靈活,設定了3個串列埠,入串列埠,出串列埠和除錯串列埠。
其中入串列埠和出串列埠用於AT命令傳送和接收,和ESP8266的串列埠相連,除錯串列埠可顯示具體互動情況(AT指令資訊等)原例子中採用的是UNO,因其只有一個硬串列埠,所以改為Mega適用,以檢視除錯資訊。

3) 執行
載入執行後,如WIFI設定正常,則可接入WIFI並取得IP,如下:
這裡寫圖片描述

可看到除錯串列埠輸出的AT指令,已經連線到WIFI,並取得192.168.80.188的IP.
另外,2121埠被也監聽成功。
可用telnet 模擬客戶端,連線建立成功後,輸入資料0~D,hello world。
輸入的資料可從COM監視器中看到對應的AT指令。如下圖:

這裡寫圖片描述

四、例子程式碼解析

從原有例子中刪除了軟串列埠相關的處理,如下

#include <ESP8266wifi.h>

#define esp8266_reset_pin 5
#define SERVER_PORT "2121"
#define SSID "XXXX"
#define PASSWORD "yourpass"

// 初始化,串列埠1和ESP8266互動,串列埠0做除錯輸出, pin5做reset
ESP8266wifi wifi(Serial1, Serial1, esp8266_reset_pin, Serial);

void processCommand(WifiMessage msg);
uint8_t wifi_started = false;

// 自定義的應用層命令,可根據自身應用修改
const char RST[] PROGMEM = "RST";
const char IDN[] PROGMEM = "*IDN?";

void setup() {

  // 除錯串列埠啟動,波特率可隨意指定
  Serial.begin(115200);

  // ESP8266預設波特率為115200(可用AT指令修改)
  Serial1.begin(115200);
  while (!Serial) // 等待串列埠初始化成功
    ;
  Serial1.println("Starting wifi"); // 命令
  Serial.println("Starting wifi");  // 除錯log輸出

  wifi.setTransportToTCP();       // TCP模式(預設設定)
  wifi.endSendWithNewline(false); // 傳送資料自動以\r\n結尾(預設設定)

  wifi_started = wifi.begin();    // WIFI啟動
  if (wifi_started) { // 如果WIFI初始化成功
    wifi.connectToAP(SSID, PASSWORD); // 指定使用者名稱密碼連線WIFI
    wifi.startLocalServer(SERVER_PORT); // 本機(Arduino)監聽2121埠(做服務端)

  } else {
    // ESP8266 isn't working..
    Serial.println("ESP8266 isn't working..");
  }
}

void loop() {

  static WifiConnection *connections;

  // check connections if the ESP8266 is there
  if (wifi_started)
    wifi.checkConnections(&connections); // 檢查/獲取當前所有連線的狀況

  // check for messages if there is a connection
  for (int i = 0; i < MAX_CONNECTIONS; i++) { // 預設最大為3
    if (connections[i].connected) {
      // See if there is a message
      WifiMessage msg = wifi.getIncomingMessage();

      if (msg.hasData) { // 如果有資料
        processCommand(msg);
      }
    }
  }
}

void processCommand(WifiMessage msg) { // 資料處理函式
  char espBuf[MSG_BUFFER_MAX];
  int set;
  char str[16];

  Serial.print(msg.message);

  // 以下為應用層面的處理
  sscanf(msg.message, "%15s %d", str, &set);
  Serial.print(str);
  Serial.println(set);

  if ( !strcmp_P(str, IDN) ) {
    wifi.send(msg.channel, "ESP8266wifi Example");
  }
  // Reset system by temp enable watchdog
  else if ( !strcmp_P(str, RST) ) {
    wifi.send(msg.channel, "SYSTEM RESET...");
    // soft reset by reseting PC
    asm volatile ("  jmp 0");
  }
  // Unknown command
  else {
    wifi.send(msg.channel, "ERR");
  }
}

六、更多文章
ESP8266可以和Arduino配合使用,充當起為Arduino進行Wifi連線、網路處理的任務。
但其實esp8266本身對比arduino,功能、效能方面均是有過之而無不及,實有殺雞用牛刀大材小用之感。
更多ESP8266的文章,請見如下:
https://blog.csdn.net/ydogg/article/category/6930257