My new wi-fi sensor node... Now with webserver implementation...

Update on March,2015:
Finally my wbserver is working like a charm.... I found the simple problem being with the firmware. I uploaded V0.9.2.2 Firmware and changed the baud rate to 9600 and Voila!!! the same webserver sketch above works flawlessly... Only change the serial baudrate to 9600 and it WORKS!!! At last.... :)

I used to send some sensor data from my Plantoid (Mechaphytum Animus) to the web (ThingSpeak namely) to be viewed on any browser using MyRobotLab... This time I decided to do the same with a wi-fi connection directly from the Arduino on Mechaphytum Animus. To accomplish the job I found this tiny wi-fi unit on a Chinese online seller at $5... The unit is based on ESP8266 chip and can establish wi-fi connection between units, to a PC and can create web socket via serial... It was hard to find reliable data on the net about the unit.. It came without any description or datasheet... Finding some info about its AT code descriptions and some code bits over the net from some previous users, I managed to write an Arduino code to update sensor data to my channel at ThingSpeak... 

Wi-fi unit wiki page:

http://www.electrodragon.com/w/Wi07c

My Arduino sketch to update DS18B temperature sensor data to ThingSpeak:


#file : home/borsaci06/DS18BTemperatureToThingSpeak.c edit raw
#include
#include 
#include 
#define ONE_WIRE_BUS 8
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

#define SSID "YOUR SSID  HERE"
#define PASS "YOUR PASSWORD HERE"
#define IP "184.106.153.149" // thingspeak.com
String GET = "GET /update?key=YOURTHINGSPEAKAPIKEY&field2=";


void setup()
{
  Serial.begin(115200);
  sensors.begin();
  Serial.println("AT");
  delay(5000);
  if(Serial.find("OK")){
    connectWiFi();
  }
}

void loop(){
  sensors.requestTemperatures();
  float tempC = sensors.getTempCByIndex(0);
  //tempC = DallasTemperature::toFahrenheit(tempC);
  char buffer[10];
  String tempF = dtostrf(tempC, 4, 1, buffer);
  updateTemp(tempF);
  //Serial.println(tempF);
  delay(60000);
}

void updateTemp(String tempF){
  String cmd = "AT+CIPSTART=\"TCP\",\"";
  cmd += IP;
  cmd += "\",80";
  Serial.println(cmd);
  delay(2000);
  if(Serial.find("Error")){
    return;
  }
  cmd = GET;
  cmd += tempF;
  cmd += "\r\n";
  Serial.print("AT+CIPSEND=");
  Serial.println(cmd.length());
  //delay(1000);
  if(Serial.find(">")){
    Serial.print(cmd);
  }else{
    Serial.println("AT+CIPCLOSE");
  }
}


boolean connectWiFi(){
  Serial.println("AT+CWMODE=3");
  delay(2000);
  String cmd="AT+CWJAP=\"";
  cmd+=SSID;
  cmd+="\",\"";
  cmd+=PASS;
  cmd+="\"";
  Serial.println(cmd);
  delay(5000);
  if(Serial.find("OK")){
    return true;
  }else{
    return false;
  }
}

After managing to send data to web, I tried to implement a webserver which can post data to my network, from where I can monitor that incoming wifi stream with my browser... Found a wonderful sketch on the net which is written by Ray Wang to test wifi sensor node by ESP8266 unit.... works like a charm... I can monitor all my analog ports with this sketch... easy to be modified to one's needs for other ports... The sketch enables the wifi unit, connects to your wifi network via WPA2-PSK, gets an IP adress from the router and you can monitor your sensor node in your beowser using the unit's IP at port 8080...

/* ====== ESP8266 Demo ======
 *   Print out analog values
 * ==========================
 *
 * Change SSID and PASS to match your WiFi settings.
 * The IP address is displayed to soft serial upon successful connection.
 *
 * Ray Wang @ Rayshobby LLC
 * http://rayshobby.net/?p=9734
 */

// comment this part out if not using LCD debug
#include 
SoftwareSerial dbg(7, 8); // using pin 7, 8 for software serial

enum {WIFI_ERROR_NONE=0, WIFI_ERROR_AT, WIFI_ERROR_RST, WIFI_ERROR_SSIDPWD, WIFI_ERROR_SERVER, WIFI_ERROR_UNKNOWN};

#define BUFFER_SIZE 128

#define SSID  "YOURSSID"   // change this to match your WiFi SSID
#define PASS  "YOURPASS"  // change this to match your WiFi password
#define PORT  "8080"      // using port 8080 by default

char buffer[BUFFER_SIZE];

void setup() {

  Serial.begin(115200);
  Serial.setTimeout(5000);

  dbg.begin(9600);
  dbg.println("begin.");

  byte err = setupWiFi();
  if (err) {
    // error, print error code
    dbg.print("setup error:");
    dbg.println((int)err);
  } else {
    // success, print IP
    dbg.print("ip addr:");
    char *ip = getIP();
    if (ip) {
      dbg.println(ip);
    }
    else {
      dbg.println("none");
    }
    maxTimeout();
  }
}

bool maxTimeout() {
  // send AT command
  Serial.println("AT+CIPSTO=0");
  if(Serial.find("OK")) {
    return true;
  } else {
    return false;
  }
}

char* getIP() {
  // send AT command
  Serial.println("AT+CIFSR");

  // the response from the module is:
  // AT+CIFSR\n\n
  // 192.168.x.x\n
  // so read util \n three times
  Serial.readBytesUntil('\n', buffer, BUFFER_SIZE);
  Serial.readBytesUntil('\n', buffer, BUFFER_SIZE);
  Serial.readBytesUntil('\n', buffer, BUFFER_SIZE);
  buffer[strlen(buffer)-1]=0;
  return buffer;
}

void loop() {
  int ch_id, packet_len;
  char *pb;
  Serial.readBytesUntil('\n', buffer, BUFFER_SIZE);
  if(strncmp(buffer, "+IPD,", 5)==0) {
    // request: +IPD,ch,len:data
    sscanf(buffer+5, "%d,%d", &ch_id, &packet_len);
    if (packet_len > 0) {
      // read serial until packet_len character received
      // start from :
      pb = buffer+5;
      while(*pb!=':') pb++;
      pb++;
      if (strncmp(pb, "GET /", 5) == 0) {
        serve_homepage(ch_id);
      }
    }
  }
}

void serve_homepage(int ch_id) {
  String header = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: close\r\nRefresh: 5\r\n";

  String content="";
  // output the value of each analog input pin
  for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
    int sensorReading = analogRead(analogChannel);
    content += "analog input ";
    content += analogChannel;
    content += " is ";
    content += sensorReading;
    content += "
\n"; } header += "Content-Length:"; header += (int)(content.length()); header += "\r\n\r\n"; Serial.print("AT+CIPSEND="); Serial.print(ch_id); Serial.print(","); Serial.println(header.length()+content.length()); if (Serial.find(">")) { Serial.print(header); Serial.print(content); delay(20); } /*Serial.print("AT+CIPCLOSE="); Serial.println(ch_id);*/ } byte setupWiFi() { Serial.println("AT"); if(!Serial.find("OK")) { return WIFI_ERROR_AT; } delay(500); // reset WiFi module Serial.println("AT+RST"); if(!Serial.find("ready")) { return WIFI_ERROR_RST; } delay(500); // set mode 3 Serial.print("AT+CWJAP=\""); Serial.print(SSID); Serial.print("\",\""); Serial.print(PASS); Serial.println("\""); delay(2000); if(!Serial.find("OK")) { return WIFI_ERROR_SSIDPWD; } delay(500); // start server Serial.println("AT+CIPMUX=1"); if(!Serial.find("OK")){ return WIFI_ERROR_SERVER; } delay(500); Serial.print("AT+CIPSERVER=1,"); // turn on TCP service Serial.println(PORT); if(!Serial.find("OK")){ return WIFI_ERROR_SERVER; } delay(500); return WIFI_ERROR_NONE; }
     
 
Update on Jan,2015:
The unit works as expected and sends all analog inputs sensor data to my browser via its IP... But I am having troubles about consistency... After some time it stops sending data. browser does not receive data but I can see the module still working if I ping it from the command prompt of PC. It begins transmission if I hard reset the Arduino... I realised that the unit is not consistent about sending-receiving commands. It sometimes adds /r/n twice, sometimes doesn't... so I modified the above code and replaced all serial.println commands with extra "Serial.print("\r\n"); " commands which did not help either... there is a forum about the unit on internet ( http://www.esp8266.com/index.php ) where I read something about faulty firmware. They say that the module goes into a busy mode while transmission for an unpredictable time which causes it not to receive appropriate  command from the Arduino sketch.. I am thinking of adding a watchdog timer to the sketch to monitor the module responses and reset the program.. Any ideas?... All kinds of help will be appreciated... this tiny module is awesome...
 
Update on March,2015:
Finally my wbserver is working like a charm.... I found the simple problem being with the firmware. I uploaded V0.9.2.2 Firmware and changed the baud rate to 9600 and Voila!!! the same webserver sketch above works flawlessly... Only change the serial baudrate to 9600 and it WORKS!!! At last.... :)
 
 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Alessandruino's picture

Very cool borsaci:) isn t it

Very cool borsaci:) isn t it dangerous to solder wires on a lupo battery?:)

borsaci06's picture

Li-Ion battery...

Thanks  Alessandro,

These batteries are not LiPo, they are Li-Ion cellphone batteries... I am using them in my low voltage projects for years... If charged properly these are safer than LiPos... I charge them with Arduino Fio Li-Ion charge port which has a lithium charge controller just like in the cellphones... They are cheap, small and reliable source of power when low voltage sensors needed to be read by Arduino... Arduino vcc port is not sufficient to drive a RF module or wifi module...

 

GroG's picture

Hi borsaci, Can you do a

Hi borsaci,

Can you do a screen-cast of it "working" and it "not working" ?

I use free Screen-O-Matic to do screen casts..  its easy and works well.

 

borsaci06's picture

esp8266

Greg,

I sent to your gmail screenshots of the unit working and not working and also the cmd line ping while not working... I tested the setup with a new script (which has watchdog timer activated).. I will also send a screenshot about this new script which you can see an error while initializing... cannot process AT+CIPSTO=30 command (I already tested with different delays with this command).. with this script the unit acquires a proper IP but cannot even send data to my browser... It continuously tries to get data and nothing displayed... doesnot timeout too...

GroG's picture

Ya .. I don't think adjusting

Ya .. I don't think adjusting the server timeout will help..   it should only require a couple milliseconds to get the needed data

The last picture you sent (Serial debugger) - is the most interesting for me ..

I don't see the Serial.println for the items being printed out .. so I assume its in onewire library ?

I one ERROR - but assume it has something to do with the initial reset..

At the bottome I see an HTTP header printed out..

You might want to start putting in Serial.print lines in the library .. we need to find out where the program is getting hung up in...

GroG's picture

Great News Borsaci !! Good to

Great News Borsaci !!

Good to have a stable system.  Now what are your plans ?  More sensor channels ? 
Was the "posting" data to Thingy speak fakey too?  And now thats fixed with the firmware upgrade?
I think the webserver would be a great control system, but I would find it a little limiting in that it does not have a file system - which makes  what it can serve to a client a little limiting.

I've seen a common design to provide a rich UI and do json calls to a web server for polling data.

looking forward to playing with these when I get home, thanks for forging ahead and figuring out the firmware problem !

borsaci06's picture

ESP8266 WebServer...

Thx Greg,

Well now I started to design a sensor node board with this tiny module and a tiny Arduino Mini with 3,3V onboard supply and all pin breakouts for both Arduino and ESP8266... this will be an all-in-one webserver board under $10... A sd card add on may be good too...

Posting to ThingSpeak is worky from the beginning... But the upgraded firmware makes it more stable too... It posts data from time to time... you also know that ThingSpeak servers do not like fequent posting... I also managed to control a led remotely over internet (MRL Home Automation Project is on the way)...

I would be glad to assist your working on this tiny module in any way you want... I collected huge data and software about ESP8266 over internet.... pls don't hesitate to ask... cheers...

Dincer