ESP8266をWifiモデムとして使う

ライブラリを使ったSocket通信(APへの接続)

ESP8266をWifiモデムとして使う為のライブラリはこ ちらでいくつか紹介されています。
さすがに人気のあるモジュールなので、ライブラリも沢山ありますが、
「Seems to be the most stable and reliable ESP library at the moment」
(現時点で最も安定し、信頼できるESPライブラリであると思われる)と紹介されている
WeeESP8266を 使いました。
「ITEADLIB_Arduino_WeeESP8266-master.zip」をダウンロードして展開したら、フォルダーごと Librariesフォルダーに移動します。

UNOもNANOもハードウェアシリアルを持っていますが、デバッグを考えると、ソフトウェアシリアルで接続したほうが楽チンです。
こ ちらでソフトウェアシリアルでの使用方法が紹介されていますが、
このライブラリをソフトウエアシリアルで使うためには「esp8266.h」を一部変更する必要があります。
デフォルトでは以下の赤枠の部分がコメントアウトされているので、コメントを外します。



青枠の部分でデフォルトのボーレートを設定していますが、これはスケッチ内で自由に変更できるので
このままにしておきます。

ArduinoとESP-01の接続は以下の通りです。
ここで気になるのはESP-01のRXdとUNOのTXdを直結していることです。
ESP-01は3.3V駆動、UNOは5V駆動なので、UNO→ESP-01のTX信号(5V)がもろにESP-01に入ります。
「esp8266 gpio 5v 3.3v」をキーワードに色々調べましたが、どうもESPシリーズのGPIOは5Vも大丈夫なようです。
心配な方はこ ちらを参照してください。
ESP-01のリセットピンのボタンは、リセット時の動作を確認するために付けています。




リセットボタンを押してから、以下のスケッチを実行します。
単に現在の状況を確認しているだけです。
/*
 * ESP8266 Connection Test
 * 
 * ESP8266----------ATmega
 * ESP8266_TX    -> RX(D2)
 * ESP8266_RX    -> TX(D3)
 */
#include <SoftwareSerial.h>

#define rxPin 2
#define txPin 3

SoftwareSerial myESP8266(rxPin, txPin); /* RX:D2, TX:D3 */

void ESP8266_Write(char * cmd) {
  Serial.print("Write=[");
  Serial.print(cmd);
  Serial.println("]");
  myESP8266.println(cmd);
}

int ESP8266_Read(char * buf, int szbuf, int timeout) {
  int len=0;
  int pos=0;
  char line[128];
   
  long int time = millis();

  while( (time+timeout) > millis()) {
    while(myESP8266.available())  {
      char c = myESP8266.read(); // read the next character.
      buf[len]=c;
      len++;
      if (len == szbuf) return len;
      buf[len]=0;

      if (c == 0x0d) {
         
      } else if (c == 0x0a) {
        Serial.print("Read=[");
        Serial.print(line);
        Serial.println("]");
        if (strcmp(line,"OK") == 0) return len;
        pos=0;
        line[pos]=0;
      } else {
        line[pos++]=c;
        line[pos]=0;
      }
    } 
  }
  return len;
}

void setup(void)
{
    char buf[256];
    int len;
   
    Serial.begin(9600);
    myESP8266.begin(4800);
    ESP8266_Write("AT");
    len=ESP8266_Read(buf,sizeof(buf),2000);
    ESP8266_Write("AT+CWJAP?");
    len=ESP8266_Read(buf,sizeof(buf),2000);
    ESP8266_Write("AT+CIPSTA?");
    len=ESP8266_Read(buf,sizeof(buf),2000);
}


void loop(void) {
}

上のスケッチを実行すると以下のように表示されます。
何もしていないのにAPに接続されていてIPアドレスも表示されます。
前回説明したように、ESP-01は最後に接続したAPの情報を記憶していて、リセット時に自動的に前回と同じAPに接続を行います。


そこで、以下のスケッチで起動直後は一旦APとの接続を開放してみます。
APとの接続開放はleaveAP()を使います。
/*
 * ESP8266 Connect Example with WeeESP8266 Library
 *
 * ESP8266----------ATmega
 * ESP8266_TX    -> RX(D3)
 * ESP8266_RX    -> TX(D2)
 */

#include "ESP8266.h"
#include <SoftwareSerial.h>

#define rxPin 2
#define txPin 3
#define baudRate 4800

SoftwareSerial myESP8266(rxPin, txPin); /* RX:D2, TX:D3 */
ESP8266 wifi(myESP8266,baudRate); // https://github.com/itead/ITEADLIB_Arduino_WeeESP8266

void ESP8266_Write(char * cmd) {
  Serial.print("Write=[");
  Serial.print(cmd);
  Serial.println("]");
  myESP8266.println(cmd);
}

int ESP8266_Read(char * buf, int szbuf, int timeout) {
  int len=0;
  int pos=0;
  char line[128];
    
  long int time = millis();

  while( (time+timeout) > millis()) {
    while(myESP8266.available())  {
      char c = myESP8266.read(); // read the next character.
      buf[len]=c;
      len++;
      if (len == szbuf) return len;
      buf[len]=0;

      if (c == 0x0d) {
          
      } else if (c == 0x0a) {
        Serial.print("Read=[");
        Serial.print(line);
        Serial.println("]");
        if (strcmp(line,"OK") == 0) return len;
        pos=0;
        line[pos]=0;
      } else {
        line[pos++]=c;
        line[pos]=0;
      }
    }  
  }
  return len;
}

void setup(void)
{
    char buf[256];
    int len;

    Serial.begin(9600);
    ESP8266_Write("AT");
    len=ESP8266_Read(buf,sizeof(buf),2000);
    ESP8266_Write("AT+CWJAP?");
    len=ESP8266_Read(buf,sizeof(buf),2000);
    ESP8266_Write("AT+CIPSTA?");
    len=ESP8266_Read(buf,sizeof(buf),2000);

    Serial.println("wifi.leaveAP()");
    wifi.leaveAP();

//    ESP8266_Write("AT");
//    len=ESP8266_Read(buf,sizeof(buf),2000);
    ESP8266_Write("AT+CWJAP?");
    len=ESP8266_Read(buf,sizeof(buf),2000);
    ESP8266_Write("AT+CIPSTA?");
    len=ESP8266_Read(buf,sizeof(buf),2000);
}

void loop(void)
{
}

以下の様にAPとの接続は無くなります。


改めてAPとの接続を確立します。
/*
 * ESP8266 Connect Example with WeeESP8266 Library
 *
 * ESP8266----------ATmega
 * ESP8266_TX    -> RX(D2)
 * ESP8266_RX    -> TX(D3)
 */

#include "ESP8266.h"
#include <SoftwareSerial.h>

#define rxPin 2
#define txPin 3
#define baudRate 4800

SoftwareSerial myESP8266(rxPin, txPin); /* RX:D2, TX:D3 */
ESP8266 wifi(myESP8266,baudRate); // https://github.com/itead/ITEADLIB_Arduino_WeeESP8266

#define SSID        "aterm-e625c0-g"
#define PASSWORD    "05ecd1dcd39c6"

void ESP8266_Write(char * cmd) {
  Serial.print("Write=[");
  Serial.print(cmd);
  Serial.println("]");
  myESP8266.println(cmd);
}

int ESP8266_Read(char * buf, int szbuf, int timeout) {
  int len=0;
  int pos=0;
  char line[128];
   
  long int time = millis();

  while( (time+timeout) > millis()) {
    while(myESP8266.available())  {
      char c = myESP8266.read(); // read the next character.
      buf[len]=c;
      len++;
      if (len == szbuf) return len;
      buf[len]=0;

      if (c == 0x0d) {
         
      } else if (c == 0x0a) {
        Serial.print("Read=[");
        Serial.print(line);
        Serial.println("]");
        if (strcmp(line,"OK") == 0) return len;
        pos=0;
        line[pos]=0;
      } else {
        line[pos++]=c;
        line[pos]=0;
      }
    } 
  }
  return len;
}

void setup(void)
{
    char buf[256];
    int len;

    Serial.begin(9600);
    ESP8266_Write("AT");
    len=ESP8266_Read(buf,sizeof(buf),2000);
    ESP8266_Write("AT+CWJAP?");
    len=ESP8266_Read(buf,sizeof(buf),2000);
    ESP8266_Write("AT+CIPSTA?");
    len=ESP8266_Read(buf,sizeof(buf),2000);

    Serial.println("wifi.leaveAP()");
    wifi.leaveAP();

    ESP8266_Write("AT+CWJAP?");
    len=ESP8266_Read(buf,sizeof(buf),2000);
    ESP8266_Write("AT+CIPSTA?");
    len=ESP8266_Read(buf,sizeof(buf),2000);

    if (wifi.setOprToStation()) {
      Serial.print("to station ok\r\n");
    } else {
      Serial.print("to station err\r\n");
    }

    if (wifi.joinAP(SSID, PASSWORD)) {
      Serial.print("Join AP success\r\n");
      Serial.print("IP: ");      
      Serial.println(wifi.getLocalIP().c_str());
    } else {
      Serial.print("Join AP failure\r\n");
    }

    len=ESP8266_Read(buf,sizeof(buf),2000);
    ESP8266_Write("AT+CWJAP?");
    len=ESP8266_Read(buf,sizeof(buf),2000);
    ESP8266_Write("AT+CIPSTA?");
    len=ESP8266_Read(buf,sizeof(buf),2000);

    wifi.leaveAP();
    Serial.print("setup end\r\n");
}

void loop(void)
{
}

一旦APとの接続を開放してから改めてAPとの接続を確立します。
少し面倒ですがこれが一番確実な接続方法です。
なお、APとの接続中にUNOの電源を入れ直してもAPとの接続は切れません。


次回はRaspberryとのSocket通信を紹介します。