ESP8266 Serial WiFi Module


DSC_1987
This is my first attempt to receive data with an Arduino and the ESP8266 WiFi-Module. This program is based on the example by Seedstudio, and displays weather data on a small TFT display.

The Modul

esp8266_pinout_h
I bought this module at Electrodragon. This Version has two LEDs, one for Power and another one which is connected to the TX-Pin. It runs at 3.3 Volt and the serial port is set to a data rate of 115200 baud. The CH_PD-Pin has to be high. After a reset, the module sends the following data:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
AT+RST
OK
 ets Jan  8 2013,rst cause:4, boot mode:(3,6)
wdt reset
load 0x40100000, len 24236, room 16
tail 12
chksum 0xb7
ho 0 tail 12 room 4
load 0x3ffe8000, len 3008, room 12
tail 4
chksum 0x2c
load 0x3ffe8bc0, len 4816, room 4
tail 12
chksum 0x46
csum 0x46
ready

Wiring

The wiring is quite simple. The wifi-module needs just two wires for power and two for the serial interface. As a display i used a 1.8″ (45.72 mm) TFT-display that is connected via SPI.


weather-display

ArduinoESP8266 ModuleDisplay Module
3.3VVCC & CH_PD
5VVCC
GNDGNDGND & BKL
0 (RX)TX
1 (TX)RX
8RESET
9RS
10LCD CS
11MOSI
13SLCK

The Program

I changed the source code from Seedstudio a little bit, because at 115200 baud the 64 Byte uart-buffer from the Arduino fills up very fast. But overall the program is really simple.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include <SoftwareSerial.h>
#include <JsonParser.h>
#define cs   10  // Pins for the display
#define dc   9
#define rst  8
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>
Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);
using namespace ArduinoJson::Parser;
#define SSID "<ssid>" // insert your SSID
#define PASS "<password>" // insert your password
#define LOCATIONID "2925533" // location id
#define DST_IP "188.226.224.148" //api.openweathermap.org
SoftwareSerial dbgSerial(2, 3); // RX, TX for debugging
JsonParser<32> parser;
void setup()
{
  Serial.begin(115200);
  Serial.setTimeout(5000);
  dbgSerial.begin(9600); // for debuging
  dbgSerial.println("Init");
  tft.initR(INITR_BLACKTAB);
  tft.setRotation(1);
  tft.fillScreen(ST7735_BLACK);
  tft.setCursor(2, 2);
  tft.setTextColor(ST7735_WHITE);
  Serial.println("AT+RST"); // restet and test if module is redy
  delay(1000);
  if(Serial.find("ready")) {
    dbgSerial.println("WiFi - Module is ready");
    tft.println("WiFi - Module is ready");
  }else{
    dbgSerial.println("Module dosn't respond.");
    tft.println("Module dosn't respond.");
    tft.println("Please reset.");
    while(1);
  }
  delay(1000);
  // try to connect to wifi
  boolean connected=false;
  for(int i=0;i<5;i++){
    if(connectWiFi()){
      connected = true;
      tft.println("Connected to WiFi...");
      break;
    }
  }
  if (!connected){
    tft.println("Coudn't connect to WiFi.");
    while(1);
  }
  delay(5000);
  Serial.println("AT+CIPMUX=0"); // set to single connection mode
}
void loop()
{
  String cmd = "AT+CIPSTART=\"TCP\",\"";
  cmd += DST_IP;
  cmd += "\",80";
  Serial.println(cmd);
  dbgSerial.println(cmd);
  if(Serial.find("Error")) return;
  cmd = "GET /data/2.5/weather?id=";
  cmd += LOCATIONID;
  cmd += " HTTP/1.0\r\nHost: api.openweathermap.org\r\n\r\n";
  Serial.print("AT+CIPSEND=");
  Serial.println(cmd.length());
  if(Serial.find(">")){
    dbgSerial.print(">");
  }else{
    Serial.println("AT+CIPCLOSE");
    dbgSerial.println("connection timeout");
    tft.fillScreen(ST7735_BLACK);
    tft.setCursor(2, 2);
    tft.setTextColor(ST7735_WHITE);
    tft.println("connection timeout");
    delay(1000);
    return;
  }
  Serial.print(cmd);
  unsigned int i = 0; //timeout counter
  int n = 1; // char counter
  char json[100]="{";
  while (!Serial.find("\"main\":{")){} // find the part we are interested in.
  while (i<60000) {
    if(Serial.available()) {
      char c = Serial.read();
      json[n]=c;
      if(c=='}') break;
      n++;
      i=0;
    }
    i++;
  }
  dbgSerial.println(json);
  JsonObject root = parser.parse(json);
  double temp = root["temp"];
  double pressure = root["pressure"];
  double humidity = root["humidity"];
  temp -= 273.15; // from kelvin to degree celsius
  tft.fillScreen(ST7735_BLACK);
  tft.setCursor(2, 25);
  tft.setTextColor(ST7735_BLUE);
  tft.setTextSize(2);
  tft.print("Temp: ");
  tft.print((int)temp);
  tft.print(".");
  tft.print((int)((temp-(int)temp)*10));
  tft.println(" C");
  tft.setCursor(2, 55);
  tft.setTextColor(ST7735_GREEN);
  tft.setTextSize(2);
  tft.print("Press: ");
  tft.print((int)pressure);
  tft.setCursor(2, 85);
  tft.setTextColor(ST7735_YELLOW);
  tft.setTextSize(2);
  tft.print("Humidity: ");
  tft.print((int)humidity);
  tft.println("%");
  dbgSerial.println(temp);
  dbgSerial.println(pressure);
  dbgSerial.println(humidity);
  dbgSerial.println("====");
  delay(600000);
}
boolean connectWiFi()
{
  Serial.println("AT+CWMODE=1");
  String cmd="AT+CWJAP=\"";
  cmd+=SSID;
  cmd+="\",\"";
  cmd+=PASS;
  cmd+="\"";
  dbgSerial.println(cmd);
  Serial.println(cmd);
  delay(2000);
  if(Serial.find("OK")){
    dbgSerial.println("OK, Connected to WiFi.");
    return true;
  }else{
    dbgSerial.println("Can not connect to the WiFi.");
    return false;
  }
}

Conclusion

The program is quite simple and could be extended with more features like a weather forecast. If you have any comments about the source code leave it down below. I hope i don’t have to many spelling mistakes in my first English post :)
Update: There was a bug in the code, which was found by Jody Roth. This is now fixed.