Introduction: Using ESP-01 and Arduino UNO

In our previous tutorial, we learned how to set up the ESP8266 ESP-01 and establish communication with other devices.

In this tutorial we are going to show how to use the ESP-01 module to give the Arduino UNO access to a Wi-Fi network and interact with inputs and outputs.

Step 1: Materials

The materials that you will need for this tutorial are:

Add the LED and button to the wiring setup from the previous tutorial as shown in the images above.

Note that TX and RX from the ESP-01 are now connected to pins 7 and 6 correspondingly.

Step 2: Coding

Now that we have the setup complete, we are going to control the LED via Wi-Fi to turn it ON or OFF.

We are also going to check to make sure that when the button is pressed that a message is received about its change of state.

The following code shows how to do this:

#include 
//#include 
#define TIMEOUT 5000 // mS
#define LED 5
SoftwareSerial mySerial(7, 6); // RX, TX
const int button = 11;
int button_state = 0;
 
void setup()
{
 pinMode(LED,OUTPUT);
 pinMode(button,INPUT); 
 Serial.begin(9600);
 mySerial.begin(9600);
 SendCommand("AT+RST", "Ready");
 delay(5000);
 SendCommand("AT+CWMODE=1","OK");
 SendCommand("AT+CIFSR", "OK");
 SendCommand("AT+CIPMUX=1","OK");
 SendCommand("AT+CIPSERVER=1,80","OK");
}
 
void loop(){
 button_state = digitalRead(button);
 
 if(button_state == HIGH){
    mySerial.println("AT+CIPSEND=0,23");
    mySerial.println("

Button was pressed!

");     delay(1000);     SendCommand("AT+CIPCLOSE=0","OK");   }     String IncomingString="";  boolean StringReady = false;    while (mySerial.available()){    IncomingString=mySerial.readString();    StringReady= true;   }     if (StringReady){     Serial.println("Received String: " + IncomingString);      if (IncomingString.indexOf("LED=ON") != -1) {     digitalWrite(LED,HIGH);    }     if (IncomingString.indexOf("LED=OFF") != -1) {     digitalWrite(LED,LOW);    }   }  }   boolean SendCommand(String cmd, String ack){   mySerial.println(cmd); // Send "AT+" command to module   if (!echoFind(ack)) // timed out waiting for ack string     return true; // ack blank or ack found }   boolean echoFind(String keyword){  byte current_char = 0;  byte keyword_length = keyword.length();  long deadline = millis() + TIMEOUT;  while(millis() < deadline){   if (mySerial.available()){     char ch = mySerial.read();     Serial.write(ch);     if (ch == keyword[current_char])       if (++current_char == keyword_length){        Serial.println();        return true;     }    }   }  return false; // Timed out }
 

Step 3: Code Explanation

#include <SoftwareSerial.h>
#define TIMEOUT 5000 // mS
#define LED 5
SoftwareSerial mySerial(7, 6); // RX, TX
const int button = 11;
int button_state = 0;

In this part of the code, we include the SoftwareSerial library to allow pins 6 and 7 to receive serial communication from the ESP-01.

We also assign the name “LED” to pin 5 and “button” to pin 11, and make the initial value of the button zero.

Step 4: Code Explanation - Continued

void setup()
{
 pinMode(LED,OUTPUT);
 pinMode(button,INPUT); 
 Serial.begin(9600);
 mySerial.begin(9600);
 SendCommand("AT+RST", "Ready");
 delay(5000);
 SendCommand("AT+CWMODE=1","OK");
 SendCommand("AT+CIFSR", "OK");
 SendCommand("AT+CIPMUX=1","OK");
 SendCommand("AT+CIPSERVER=1,80","OK");
}

In the setup, we make the LED an output and the button an input.

We then begin serial communication and define the baud rate for both channels of communication.

Next, we call the function “SendCommand” several times to configure the ESP-01.

With this function you avoid having to open the serial monitor and sending commands manually like we did in the previous tutorial.

First we reset the module and wait for a couple of milliseconds to let it finish.

Then we make it operate in STA mode and ask for the IP address.

Finally, we enable multiple connections and start the server at port 80.

Step 5: Code Explanation - Continued

void loop(){
 button_state = digitalRead(button);
 
 if(button_state == HIGH){
    mySerial.println("AT+CIPSEND=0,23");
    mySerial.println("<h1>Button was pressed!</h1>");
    delay(1000);
    SendCommand("AT+CIPCLOSE=0","OK");
  }
  
 String IncomingString="";
 boolean StringReady = false;
 
 while (mySerial.available()){
   IncomingString=mySerial.readString();
   StringReady= true;
  }
 
  if (StringReady){
    Serial.println("Received String: " + IncomingString);
  
  if (IncomingString.indexOf("LED=ON") != -1) {
    digitalWrite(LED,HIGH);
   }
 
  if (IncomingString.indexOf("LED=OFF") != -1) {
    digitalWrite(LED,LOW);
   }
  }
 }

In the loop, we read the state of the button and assign it to the variable “button_state.”

Then we check if the button is pressed.

If the case is true, we type the command “AT+CIPSEND=0,23” to send 23 bit of data through channel 0 to our device connected to the ESP-01. Then we type the message that we want to send. In this case the message is “Button was pressed!” Note that we can use html formatting to edit the text and make it a header.

Next, we create a string variable that will hold the data coming from the ESP module. Once all data has been read we check if the received data contains either a string equal to “LED=ON” or “LED=OFF” along the lines.

If the first case is true, the LED is turned on. If the second case is true, the LED is turned off.

Step 6: Code Explanation - Continued

boolean SendCommand(String cmd, String ack){
  mySerial.println(cmd); // Send "AT+" command to module
  if (!echoFind(ack)) // timed out waiting for ack string
    return true; // ack blank or ack found

The “SendCommand” function takes two arguments: the AT command that we want to send to the ESP-01 and the acknowledge string.

The first argument is used to send a command to the ESP-01 through the serial channel.

The second argument is used to verify that the command was successfully accepted by the ESP module.

Step 7: Code Explanation - Continued

boolean echoFind(String keyword){
 byte current_char = 0;
 byte keyword_length = keyword.length();
 long deadline = millis() + TIMEOUT;
 while(millis() < deadline){
  if (mySerial.available()){
    char ch = mySerial.read();
    Serial.write(ch);
    if (ch == keyword[current_char])
      if (++current_char == keyword_length){
       Serial.println();
       return true;
    }
   }
  }
 return false; // Timed out
}

The last function is used to compare the acknowledge string to the response given by the ESP-01 once a command has been sent.

First we initialize the variable “current_char” to zero. This variable will serve as an index to compare each character between the acknowledge string and the ESP response. Then we store the length of the acknowledge string in the variable “keyword_length” and create a deadline that equals to the time since the Arduino board began running plus 5000ms.

Next we create a while loop that runs until the deadline is met. Inside the while loop we check if there is data to be read in the serial channel connected to the ESP. If the case is true, then we compare the acknowledge string to the data being read from the serial channel.

If both are equal, then the function returns a true to tell the program that the ESP-01 has responded accordingly to the command sent. If the deadline is met, then the function returns a false, meaning that something went wrong and the ESP was not able to respond to the command sent.

Step 8: Results

Once we upload the code, we can open the serial monitor. We will get the information shown in the image above.

This means that the configuration of the ESP was successful, and it is ready to be used as a server.

Step 9: Results - Continued

Now we can open a web browser and type either of the following lines shown above in the screen shot images of the browser windows.

The first line is used to turn the LED on, and the second line is used to turn the LED off. The images above show the lines written into the browser as well as the corresponding action that occurs on the breadboard.

Step 10: Results - Continued

If we press the button, we get the following message in our web browser’s window.

Step 11: Results - Continued

If we use the Android App “Mobile Telnet” we can get the same results.

First we need to open the App and connect to the ESP module as it was done in the previous tutorial.

Once we are connected we can type a message to turn the LED on, as shown in the image above.

Step 12: Results - Continued

Similarly, we can send the following message to turn the LED off.

Shown above in the screenshot image.

Step 13: Results - Continued

If we press the button we get the same message as before on our phone.

Now you can manipulate inputs and outputs via Wi-Fi using the Arduino UNO and the ESP-01 module in the ESP8266 series.

If you have any questions about this tutorial, do not hesitate to post a comment, shoot us an email, or post it in our forum.

Check out Jaycon Systems online store for the parts you need to start creating!

If you haven't already - read through the other great tutorials we have on our website as well as our Instructables profile!

Let us know what you think, and thanks for reading!

Comments

author
WilliamBarati (author)2017-04-11

Thank you for sharing this

author
jay777. (author)2017-03-21

Found a few issues with the code on this one. I reflashed my esp-01 using the ESP8266Flasher with v0.9.2.2 AT Firmware. This got me down to 9600 baud. If not you will need to set " mySerial.begin(9600); " to " mySerial.begin(115200); " 115200 is the default baud rate for the module. For the button was pressed part of it you have to refresh the web page then push the button. To turn the led off and on, you do just like in the how to. IP/LED=ON or IP/LED=OFF.

Here is the corrected code that I just tested as working.

#include <SoftwareSerial.h>

#define TIMEOUT 5000 // mS

#define LED 5

SoftwareSerial mySerial(6, 7); // RX, TX

const int button = 11;

int button_state = 0;

void setup()

{

pinMode(LED,OUTPUT);

pinMode(button,INPUT);

Serial.begin(9600);

mySerial.begin(9600);

SendCommand("AT+RST", "Ready");

delay(5000);

SendCommand("AT+CWMODE=3","OK");

SendCommand("AT+CIFSR", "OK");

SendCommand("AT+CIPMUX=1","OK");

SendCommand("AT+CIPSERVER=1,80","OK");

}

void loop(){

button_state = digitalRead(button);

if(button_state == HIGH){

SendCommand("AT+CIPSEND=0,23","OK");

delay(250);

mySerial.println("<h1>Button was pressed!</h1>");

delay(250);

SendCommand("AT+CIPCLOSE=0","OK");

}

String IncomingString="";

boolean StringReady = false;

while (mySerial.available()){

IncomingString=mySerial.readString();

StringReady= true;

}

if (StringReady){

Serial.println("Received String: " + IncomingString);

if (IncomingString.indexOf("LED=ON") != -1) {

digitalWrite(LED,HIGH);

}

if (IncomingString.indexOf("LED=OFF") != -1) {

digitalWrite(LED,LOW);

}

}

}

boolean SendCommand(String cmd, String ack){

mySerial.println(cmd); // Send "AT+" command to module

if (!echoFind(ack)) // timed out waiting for ack string

return true; // ack blank or ack found

}

boolean echoFind(String keyword){

byte current_char = 0;

byte keyword_length = keyword.length();

long deadline = millis() + TIMEOUT;

while(millis() < deadline){

if (mySerial.available()){

char ch = mySerial.read();

Serial.write(ch);

if (ch == keyword[current_char])

if (++current_char == keyword_length){

Serial.println();

return true;

}

}

}

return false; // Timed out

}

author
ranag2000 (author)2016-07-28

hello, how ESP-01 connects to the AP without AT+CWJAP=ssid,password ?

I can connect to the router when using FTDI but having problems when I try to connect from Arduino UNO.

one more question, I guess the default baud rate for ESP-01 is 115200.

is there no problem opening serial at 9600?

thank you.

author
882743 (author)ranag20002017-02-27

i chnge it to 115200 ,was it possible with 9600 ?

author
JeffWX1 (author)ranag20002016-11-25

did you figure it out?

author
JeffWX1 (author)2016-11-25

was it an oversight? I dont see how the it's supposed to connect the my wifi. I tried several ways to SendCommand("AT-CWJAP") but i keep getting errors no matter how i format it. Does anyone know the correct format to send the command?

author
882743 (author)JeffWX12017-02-27

try SendCommand("AT-CWJAP?")

author
cszhaoqm (author)2016-03-03

Nice, but i prefer to use ESP only if just control the led. And i like to use Arduino IDE to program ESP.

author
JayconSystems (author)cszhaoqm2016-03-08

Here is the link to the tutorial that uses Arduino IDE to program ESP and to control an LED: https://www.instructables.com/id/ESP8266-As-a-Microcontroller/

author
JayconSystems (author)cszhaoqm2016-03-04

We have another tutorial that does just that! It's on our website right now, but I'll make it an Instructable soon and send you a reply with the link to it once it's been uploaded! Thanks for reading!

About This Instructable

37,781views

86favorites

License:

Bio: We bring hardware products to life, specializing in engineering, prototyping, and mass manufacturing. We've worked with over 20 Kickstarter projects.
More by JayconSystems:How to Measure a Corner's Radius Using a 3D Printed ToolSending Commands Via the LCD BackpackProgramming a Single 7 Segment Display
Add instructable to: