ESP8266をWifiモデムとして使う

ATコマンドによるAPへの接続

ESP8266をWifiモデムとして使う為のライブラリはいくつかありますが、所詮シリアル通信でATコマンドを投げているだけなので、
ライブラリを使わずに通信してみることにしました。

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




まずはAPとの接続方法を紹介します。
DHCP経由でダイナミックなIPアドレスを取得します。
AT-Firmwareはリセットを発行すると、直前に接続していたAPに自動的に接続する機能があるので
それを利用してリセットを発行したら[WIFI GOT IP]の応答を待ちます。
/*
 * Wifi Connect with AT Command(Dynamic IP Mode)
 *  
 * ESP8266----------ATmega
 * TX     ----------RX(D4)
 * RX     ----------TX(D5)
 *
 */

#include <SoftwareSerial.h>

#define rxPin    4    // D4
#define txPin    5    // D5
#define _DEBUG_  0

SoftwareSerial mySerial(rxPin, txPin); // RX, TX

//unsigned long lastmillis;

void putChar(char c) {
  char tmp[10];
  if ( c == 0x0a) {
    Serial.println();
  } else if (c == 0x0d) {
    
  } else if ( c < 0x20) {
    uint8_t cc = c;
    sprintf(tmp,"[0x%.2X]",cc);
    Serial.print(tmp);
  } else {
    Serial.print(c);
  }
}

//Wait for specific input string until timeout runs out
bool waitForString(char* input, int length, unsigned int timeout) {
  unsigned long end_time = millis() + timeout;
  char current_byte = 0;
  int index = 0;

   while (end_time >= millis()) {
    
      if(mySerial.available()) {
        
        //Read one byte from serial port
        current_byte = mySerial.read();
//        Serial.print(current_byte);
        putChar(current_byte);
        if (current_byte != -1) {
          //Search one character at a time
          if (current_byte == input[index]) {
            index++;
            
            //Found the string
            if (index == length) {              
              return true;
            }
          //Restart position of character to look for
          } else {
            index = 0;
          }
        }
      }
  }  
  //Timed out
  return false;
}

//Send AT Command
void sendCommand(char* buff) {
  if (_DEBUG_) {
    Serial.println("");
    Serial.print(buff);
    Serial.println("-->");
  }
  mySerial.println(buff);
  mySerial.flush();
}

//Print error
void errorDisplay(char* buff) {
  Serial.print("Error:");
  Serial.println(buff);
  while(1) {}
}


void clearBuffer() {
  while (mySerial.available())
    mySerial.read();
//  Serial.println();
}



void setup(void)
{
  char cmd[64];

  Serial.begin(9600);

  //Make sure ESP8266 is set to 4800
  mySerial.begin(4800);
  delay(100);

  //Restarts the Module
  sendCommand("AT+RST");
  if (!waitForString("WIFI GOT IP", 11, 10000)) {
    errorDisplay("ATE+RST Fail");
  }
  clearBuffer();

  //Local echo off
  sendCommand("ATE0");
  if (!waitForString("OK", 2, 1000)) {
    errorDisplay("ATE0 Fail");
  }
  clearBuffer();

  //Get local IP address
  sendCommand("AT+CIPSTA?");
  if (!waitForString("OK", 2, 1000)) {
    errorDisplay("AT+CIPSTA? Fail");
  }
  clearBuffer();
}

 void loop(void) {
}

上のスケッチを実行するとDHCPから払い出されたIPアドレスでAPに接続します。




次に固定アドレスでのAPとの接続方法を紹介します。
IPアドレスを固定する場合は「AT+CIPSTA_CUR」でアドレスを指定します。

注意点として、一度でも「AT+CIPSTA_CUR」で固定のアドレスを指定すると、
リセットしない限りESP-01はこのアドレスを使い続けます。
リセットするか電源を入れ直すことで、DHCPから払い出されたアドレスを使うようになります。
/*
 * Wifi Connect with AT Command(Fix IP Adress Mode)
 * 
 * ESP8266----------ATmega
 * TX     ----------RX(D4)
 * RX     ----------TX(D5)
 *
 */

#include <SoftwareSerial.h>


#define rxPin    4    // D4
#define txPin    5    // D5
#define _DEBUG_  0

#define MY_IP       "192.168.10.50"

SoftwareSerial mySerial(rxPin, txPin); // RX, TX

//unsigned long lastmillis;

void putChar(char c) {
  char tmp[10];
  if ( c == 0x0a) {
    Serial.println();
  } else if (c == 0x0d) {
   
  } else if ( c < 0x20) {
    uint8_t cc = c;
    sprintf(tmp,"[0x%.2X]",cc);
    Serial.print(tmp);
  } else {
    Serial.print(c);
  }
}

//Wait for specific input string until timeout runs out
bool waitForString(char* input, int length, unsigned int timeout) {
  unsigned long end_time = millis() + timeout;
  char current_byte = 0;
  int index = 0;

   while (end_time >= millis()) {
   
      if(mySerial.available()) {
       
        //Read one byte from serial port
        current_byte = mySerial.read();
//        Serial.print(current_byte);
        putChar(current_byte);
        if (current_byte != -1) {
          //Search one character at a time
          if (current_byte == input[index]) {
            index++;
           
            //Found the string
            if (index == length) {             
              return true;
            }
          //Restart position of character to look for
          } else {
            index = 0;
          }
        }
      }
  } 
  //Timed out
  return false;
}

//Send AT Command
void sendCommand(char* buff) {
  if (_DEBUG_) {
    Serial.println("");
    Serial.print(buff);
    Serial.println("-->");
  }
  mySerial.println(buff);
  mySerial.flush();
}

//Print error
void errorDisplay(char* buff) {
  Serial.print("Error:");
  Serial.println(buff);
  while(1) {}
}


void clearBuffer() {
  while (mySerial.available())
    mySerial.read();
//  Serial.println();
}



void setup(void)
{
  char cmd[64];

  Serial.begin(9600);

  //Make sure ESP8266 is set to 4800
  mySerial.begin(4800);
  delay(100);

  //Restarts the Module
  sendCommand("AT+RST");
  if (!waitForString("WIFI GOT IP", 11, 10000)) {
    errorDisplay("ATE+RST Fail");
  }
  clearBuffer();

  //Local echo off
  sendCommand("ATE0");
  if (!waitForString("OK", 2, 1000)) {
    errorDisplay("ATE0 Fail");
  }
  clearBuffer();

  //Set IP address of Station
  sprintf(cmd, "AT+CIPSTA_CUR=\"%s\"", MY_IP);
  sendCommand(cmd);
  if (!waitForString("OK", 2, 1000)) {
    errorDisplay("AT+CIPSTA_CUR fail");
  }
  clearBuffer();

  //Get local IP address
  sendCommand("AT+CIPSTA?");
  if (!waitForString("OK", 2, 1000)) {
    errorDisplay("AT+CIPSTA? Fail");
  }
  clearBuffer();
}

 void loop(void) {
}

上のスケッチを実行すると固定IPでAPに接続します。


次回はATコマンドを使ったSocket通信を紹介します。