ESP8266 driver using the NodeMCU interface

Dependencies:   BufferedSerial

Dependents:   esp8266_nodeMCU1 esp8266_2_thingspeak1 Solarator_0-0-2 IoTBurglar_and_Fire_AlarmSystem ... more

Fork of ESP8266Interface by ESP8266

This is an alternative implementation of the ESP8266 driver that uses the NodeMCU firmware. The NodeMCU firmware provides a slightly larger feature set than the default firmware through a Lua interpreter.

Note

This library is currently in Alpha. It is not feature complete and has some bugs, proceed with caution. Fixes and patches are welcome!

Interface changes

  • SSID and passphrase moved out of ESP8266Interface constructor and to ESP8266Interface::connect
  • ESP8266Interface constructor provides optional timeout parameter to specify how long to wait for network operations

Note

NodeMCU defaults to a baud rate of 9600 instead of 115200 used by the default firmware.

Firmware

To install the NodeMCU firmware, follow the instructions on the Firmware Update wiki page using the nodemcu_integer_0.9.6-dev_20150406.bin binary at address 0x00000 instead of boot_v1.1.bin and user1.bin.

Since the NodeMCU firmware defaults to a baud rate of 9600, the Serial Passthrough program can be used to get direct access to the Lua interpreter running on the ESP8266.

Status

Working features:

  • TCP Client
  • UDP Client Transmit (Currently only UDP Server can recieve messages)
  • Single Connection at a time
  • Station Mode (Connects to AP)
  • DNS Lookups

To be implemented:

  • TCP Server
  • UDP Server
  • UDP Client recieve
  • Multiple Connections tracked through Lua variables
  • AP Mode (Act as access point)
  • IPV6 support (Existing issue with NodeMCU)

Files at this revision

API Documentation at this revision

Comitter:
screamer
Date:
Tue Jun 03 18:41:15 2014 +0000
Parent:
7:3152fcc74390
Parent:
6:5176e0864078
Child:
11:fc3d86645d23
Commit message:
Merge

Changed in this revision

Wifly/Wifly.cpp Show annotated file Show diff for this revision Revisions of this file
Wifly/Wifly.h Show annotated file Show diff for this revision Revisions of this file
--- a/Socket/TCPSocketServer.cpp	Fri Nov 08 21:27:08 2013 +0000
+++ b/Socket/TCPSocketServer.cpp	Tue Jun 03 18:41:15 2014 +0000
@@ -32,8 +32,28 @@
     sprintf(cmd, "set i l %d\r", port);
     if (!wifi->sendCommand(cmd, "AOK"))
         return -1;
+    
+    // save
+    if (!wifi->sendCommand("save\r", "Stor"))
+        return -1;
+    
+    // reboot
+    wifi->reboot();
+    
+    // connect the network
+    if (wifi->isDHCP()) {
+        if (!wifi->sendCommand("join\r", "DHCP=ON", NULL, 10000))
+            return -1;
+    } else {
+        if (!wifi->sendCommand("join\r", "Associated", NULL, 10000))
+            return -1;
+    }
         
+    // exit
     wifi->exit();
+    
+    wait(0.2);
+    wifi->flush();
     return 0;
 }
 
--- a/Socket/UDPSocket.cpp	Fri Nov 08 21:27:08 2013 +0000
+++ b/Socket/UDPSocket.cpp	Tue Jun 03 18:41:15 2014 +0000
@@ -39,14 +39,33 @@
 {
     char cmd[17];
     
-    // set udp protocol
-    wifi->setProtocol(UDP);
-    
     // set local port
     sprintf(cmd, "set i l %d\r", port);
     if (!wifi->sendCommand(cmd, "AOK"))
         return -1;
+        
+    // save
+    if (!wifi->sendCommand("save\r", "Stor"))
+        return -1;
+    
+    // reboot
+    wifi->reboot();
+    
+    // set udp protocol
+    wifi->setProtocol(UDP);
+    
+    // connect the network
+    if (wifi->isDHCP()) {
+        if (!wifi->sendCommand("join\r", "DHCP=ON", NULL, 10000))
+            return -1;
+    } else {
+        if (!wifi->sendCommand("join\r", "Associated", NULL, 10000))
+            return -1;
+    }
+        
+    // exit
     wifi->exit();
+    wifi->flush();
     return 0;
 }
 
--- a/Wifly/Wifly.cpp	Fri Nov 08 21:27:08 2013 +0000
+++ b/Wifly/Wifly.cpp	Tue Jun 03 18:41:15 2014 +0000
@@ -22,7 +22,7 @@
 #include <algorithm>
 
 //Debug is disabled by default
-#if (1 && defined(TARGET_LPC1768))
+#if (defined(DEBUG))
 #define DBG(x, ...) std::printf("[Wifly : DBG]"x"\r\n", ##__VA_ARGS__);
 #define WARN(x, ...) std::printf("[Wifly : WARN]"x"\r\n", ##__VA_ARGS__);
 #define ERR(x, ...) std::printf("[Wifly : ERR]"x"\r\n", ##__VA_ARGS__);
@@ -32,7 +32,7 @@
 #define ERR(x, ...)
 #endif
 
-#if TARGET_LPC1768
+#if defined(DEBUG)
 #define INFO(x, ...) printf("[Wifly : INFO]"x"\r\n", ##__VA_ARGS__);
 #else
 #define INFO(x, ...)
@@ -70,12 +70,21 @@
     char cmd[20];
 
     for (int i= 0; i < MAX_TRY_JOIN; i++) {
+
+        // no auto join
+        if (!sendCommand("set w j 0\r", "AOK"))
+            continue;
+
+        //no echo
+        if (!sendCommand("set u m 1\r", "AOK"))
+            continue;
+
         // set time
-        if (!sendCommand("set c t 20\r", "AOK"))
+        if (!sendCommand("set c t 30\r", "AOK"))
             continue;
 
         // set size
-        if (!sendCommand("set c s 128\r", "AOK"))
+        if (!sendCommand("set c s 1024\r", "AOK"))
             continue;
 
         // red led on when tcp connection active
@@ -93,13 +102,9 @@
         // tcp retry
         if (!sendCommand("set i f 0x7\r", "AOK"))
             continue;
-
-        //no echo
-        if (!sendCommand("set u m 1\r", "AOK"))
-            continue;
-
-        // no auto join
-        if (!sendCommand("set w j 0\r", "AOK"))
+            
+        // set dns server
+        if (!sendCommand("set d n rn.microchip.com\r", "AOK"))
             continue;
 
         //dhcp
@@ -158,6 +163,9 @@
                 continue;
         }
 
+        if (!sendCommand("save\r", "Stor"))
+            continue;
+
         exit();
 
         state.associated = true;
@@ -184,11 +192,9 @@
             break;
         case UDP:
             // set ip flags: udp auto pairing enabled
-            if (!sendCommand("set i f 0x40\r", "AOK"))
-                return false;
             if (!sendCommand("set i h 0.0.0.0\r", "AOK"))
                 return false;
-            if (!sendCommand("set i r 0\r", "AOK"))
+            if (!sendCommand("set i f 0x40\r", "AOK"))
                 return false;
             break;
     }
@@ -214,27 +220,23 @@
     char rcv[20];
     char cmd[20];
 
-    // get ip from host and set host
-    if (gethostbyname(host, rcv)) {
-        sprintf(cmd, "set i h %s\r", rcv);
-        if (!sendCommand(cmd, "AOK"))
-            return false;
-    } else {
-        return false;
+    // try to open
+    sprintf(cmd, "open %s %d\r", host, port);
+    if (sendCommand(cmd, "OPEN", NULL, 10000)) {
+        state.tcp = true;
+        state.cmd_mode = false;
+        return true;
     }
 
-    // set port
-    sprintf(cmd, "set i r %d\r", port);
-    if (!sendCommand(cmd, "AOK"))
-        return false;
-
-    // open
-    if (sendCommand("open\r", NULL, rcv)) {
+    // if failed, retry and parse the response
+    if (sendCommand(cmd, NULL, rcv, 5000)) {
         if (strstr(rcv, "OPEN") == NULL) {
             if (strstr(rcv, "Connected") != NULL) {
+                wait(0.25);
                 if (!sendCommand("close\r", "CLOS"))
                     return false;
-                if (!sendCommand("open\r", "OPEN"))
+                wait(0.25);
+                if (!sendCommand(cmd, "OPEN", NULL, 10000))
                     return false;
             } else {
                 return false;
@@ -243,7 +245,7 @@
     } else {
         return false;
     }
-    
+
     state.tcp = true;
     state.cmd_mode = false;
 
@@ -322,6 +324,7 @@
         
     if (send("$$$", 3, "CMD") == -1 && send("\r",1,">") != true) {
         ERR("cannot enter in cmd mode\r\n");
+        exit();
         return false;
     }
     state.cmd_mode = true;
@@ -333,11 +336,11 @@
     // if already disconnected, return
     if (!state.associated)
         return true;
-        
+
     if (!sendCommand("leave\r", "DeAuth"))
         return false;
     exit();
-    
+
     state.associated = false;
     return true;
 
@@ -357,17 +360,29 @@
     wait(0.2);
 }
 
+bool Wifly::reboot()
+{
+    // if already in cmd mode, return
+    if (!sendCommand("reboot\r"))
+        return false;
+    
+    wait(0.3);
+
+    state.cmd_mode = false;
+    return true;
+}
+
 bool Wifly::close()
 {
     // if not connected, return
     if (!state.tcp)
         return true;
-        
+
     wait(0.25);
     if (!sendCommand("close\r", "CLOS"))
         return false;
     exit();
-    
+
     state.tcp = false;
     return true;
 }
--- a/Wifly/Wifly.h	Fri Nov 08 21:27:08 2013 +0000
+++ b/Wifly/Wifly.h	Tue Jun 03 18:41:15 2014 +0000
@@ -44,11 +44,14 @@
     TCP = (1 << 1)
 };
 
+/**
+ * The Wifly class
+ */
 class Wifly
 {
 
 public:
-    /*
+    /**
     * Constructor
     *
     * @param tx mbed pin to use for tx line of Serial interface
@@ -61,77 +64,82 @@
     */
     Wifly(  PinName tx, PinName rx, PinName reset, PinName tcp_status, const char * ssid, const char * phrase, Security sec);
 
-    /*
+    /**
     * Connect the wifi module to the ssid contained in the constructor.
     *
     * @return true if connected, false otherwise
     */
     bool join();
 
-    /*
+    /**
     * Disconnect the wifly module from the access point
     *
-    * @ returns true if successful
+    * @return true if successful
     */
     bool disconnect();
 
-    /*
+    /**
     * Open a tcp connection with the specified host on the specified port
     *
     * @param host host (can be either an ip address or a name. If a name is provided, a dns request will be established)
     * @param port port
-    * @ returns true if successful
+    * @return true if successful
     */
     bool connect(const char * host, int port);
 
 
-    /*
+    /**
     * Set the protocol (UDP or TCP)
     *
     * @param p protocol
-    * @ returns true if successful
+    * @return true if successful
     */
     bool setProtocol(Protocol p);
 
-    /*
+    /**
     * Reset the wifi module
     */
     void reset();
+    
+    /**
+    * Reboot the wifi module
+    */
+    bool reboot();
 
-    /*
+    /**
     * Check if characters are available
     *
     * @return number of available characters
     */
     int readable();
 
-    /*
+    /**
     * Check if characters are available
     *
     * @return number of available characters
     */
     int writeable();
 
-    /*
+    /**
     * Check if a tcp link is active
     *
-    * @returns true if successful
+    * @return true if successful
     */
     bool is_connected();
 
-    /*
+    /**
     * Read a character
     *
     * @return the character read
     */
     char getc();
 
-    /*
+    /**
     * Flush the buffer
     */
     void flush();
 
-    /*
+    /**
     * Write a character
     *
     * @param the character which will be written
@@ -139,28 +147,28 @@
     int putc(char c);
 
 
-    /*
+    /**
     * To enter in command mode (we can configure the module)
     *
     * @return true if successful, false otherwise
     */
     bool cmdMode();
 
-    /*
+    /**
     * To exit the command mode
     *
     * @return true if successful, false otherwise
     */
     bool exit();
 
-    /*
+    /**
     * Close a tcp connection
     *
-    * @ returns true if successful
+    * @return true if successful
     */
     bool close();
 
-    /*
+    /**
     * Send a string to the wifi module by serial port. This function desactivates the user interrupt handler when a character is received to analyze the response from the wifi module.
     * Useful to send a command to the module and wait a response.
     *
@@ -174,16 +182,25 @@
     */
     int send(const char * str, int len, const char * ACK = NULL, char * res = NULL, int timeout = DEFAULT_WAIT_RESP_TIMEOUT);
 
-    /*
+    /**
     * Send a command to the wify module. Check if the module is in command mode. If not enter in command mode
     *
     * @param str string to be sent
     * @param ACK string which must be acknowledge by the wifi module. If ACK == NULL, no string has to be acknoledged. (default: "NO")
     * @param res this field will contain the response from the wifi module, result of a command sent. This field is available only if ACK = "NO" AND res != NULL (default: NULL)
     *
-    * @returns true if successful
+    * @return true if successful
     */
     bool sendCommand(const char * cmd, const char * ack = NULL, char * res = NULL, int timeout = DEFAULT_WAIT_RESP_TIMEOUT);
+    
+    /**
+    * Return true if the module is using dhcp
+    *
+    * @return true if the module is using dhcp
+    */
+    bool isDHCP() {
+        return state.dhcp;
+    }
 
     bool gethostbyname(const char * host, char * ip);
 
--- a/WiflyInterface.h	Fri Nov 08 21:27:08 2013 +0000
+++ b/WiflyInterface.h	Tue Jun 03 18:41:15 2014 +0000
@@ -22,8 +22,8 @@
 
 #include "Wifly.h"
 
- /** Interface using Wifly to connect to an IP-based network
- *
+ /**
+ * Interface using Wifly to connect to an IP-based network
  */
 class WiflyInterface: public Wifly {
 public:
@@ -70,7 +70,7 @@
   
   /** Get IP address
   *
-  * @ returns ip address
+  * \return ip address
   */
   char* getIPAddress();