Monday, December 26, 2016

Getting the ESP-13 Arduino WiFi shield to work - part 1, sending data from Arduino over Wifi

I thought it would be fun to make some little WiFi enabled gadgets in my house, so I bought a cheap ($19.99) WiFi solution on Amazon.com : the "Gowoops ESP8266 Web Server Serial Port WiFi Shield Expansion Board ESP-13 and UNO R3 ATmega328P Development Board For Arduino with USB cable"

But it turned out that I, like many people, couldn't simply "turn it on and expect it to work".

So I spent a few hours clicking around various sites, including this one that was probably the closest to being helpful - but since it expected me to have a Windows machine, and some software that I could not use, I was still stuck.

So - for Mac users among you, here is what it took for me to get data that the Arduino generates to be sent over WiFi to a receiving program (in my case I used Python - because it's built in to the Mac, I am familiar with it, and networking is trivial. But it's really just there to prove that data is making it from the shield to the computer, over the wireless link).

Step 1: configure the shield as a serial port server

Plug the shield into your Arduino, and power them up (I just used the USB cable for this).
Press the “key” button on the ESP-13 (see picture)

for at least one second to make sure it goes back to default mode. It takes a few seconds to “come to life” in the default state.

Make sure the two DIP switches are OFF at this stage - this keeps the Arduino from talking to the shield – necessary for programming the Arduino. Note, in the above diagram the DIP switches are ON.

On your computer or phone, turn on WiFi and select DoitWiFi_Config from the list of possible access points. Make sure you have DHCP enabled, so your computer will be given an IP address by the ESP-13.  Once you are connected, open a browser, and go to 192.168.4.1 (this is the default address of the shield)

In the resulting configuration page, change the AP name to DoitWiFi_Ser2Net
Leave encryption OPEN (for now)

Press Submit (green) button at the bottom of the page (you may need to scroll to find it - the below is a composite of screenshots from my phone).



Step 2: write a short Arduino program to send data over the serial link.
Here is a sample program that prints a sequence of numbers – one per second:

int ii;
void setup()
{
  Serial.begin(9600);
  ii=0;
}
void loop()
{
  delay(1000);
  Serial.print("packet # ");
  Serial.print(ii++,DEC);
  Serial.println(" - hello ESP8266 WiFi"); //output the serial data
}

Enter this code into the Arduino development environment as a new sketch, and check that it works. Because I used the Arduino that came with the WiFi shield (they came as a package on Amazon) I used the board "Arduino/Genuino Uno" under "Tools/Board", and the USB port that showed up (since I connected my Mac with USB).


Step 3: upload the program to the Arduino.
This is done in the usual way, but remember – THE DIP SWITCHES MUST BE OFF because otherwise the upload will fail.
You can test that the program works by opening the serial monitor; you should see a series of messages (one per second) like this:



Step 4: make a program that can “receive” data.
The following Python program works on e.g. a Mac. Enter the text into a file called tcptest.py

import socket
import sys
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('192.168.4.1', 9000)
print >>sys.stderr, 'connecting to %s port %s'% server_address
sock.connect(server_address)
print >>sys.stderr, 'Connection made!'

try:
 while 1:
  data = sock.recv(16)
  print >>sys.stderr, '%s' % data,

finally:
  print >>sys.stderr, 'closing socket'
  sock.close()


Note that the server address (192.168.4.1) and port (9000) are the default parameters that were set in step 1 (you didn’t actually have to do anything to get these values, they are the default). This is just about the shortest program I can think of to capture TCP/IP packets and display them - if you know Python it should be easy to think of ways to make it do more, but that's not the point of this post...

Step 5: connect your computer’s WiFi to the shield
Find the DoitWiFi_Ser2Net wireless access point, and connect your computer to it. For this to work, you need to have DHCP enabled – this will ensure that your computer gets given a wireless address by the device that it will be able to talk to. Many in-house wireless systems have IP addresses starting with 192.168.1. – you will know you have succeeded when your IP address is something like 192.168.4.2

Step 6: connect the Arduino serial port to the WiFi shield
You now have to set the two DIP switches to “ON” so the Arduino will send serial data to the ESP-13 - at this point you must not try to upload programs to the Arduino; if you are still using the USB cable for power that's OK.

Step 7: start the Python program to capture the output from the shield
At the command line in the Terminal, run the above Python program by typing

python tcptest.py

You will see an output like this (stop it by typing Ctrl-C):


python tcptest.py 
connecting to 192.168.4.1 port 9000
Connection made!
packet # 467 - hello ESP8266 WiFi
packet # 468 - hello ESP8266 WiFi
packet # 469 - hello ESP8266 WiFi
packet # 470 - hello ESP8266 WiFi
packet # 471 - hello ESP8266 WiFi
packet # 472 - hello ESP8266 WiFi
packet # 473 - hello ESP8266 WiFi
packet # 474 - hello ESP8266 WiFi
packet # 475 - hello ESP8266 WiFi
packet # 476 - hello ESP8266 WiFi
packet # 477 - hello ESP8266 WiFi

As you can see, you are getting packets every second with the current value of the counter in the Arduino program - in other words, you have your first WiFi link running!

I hope to figure out how to send data in the other direction... so I can instruct the Arduino to "do things" - and then, figure out how to make the shield "play nice" on my home network so I don't have to fiddle with network settings on my computer to be able to talk to it. All of that will be the subject of a follow-up blog, if I figure it out.

14 comments:

  1. that is for a mac user.
    i am a windows user, how can i do that?

    ReplyDelete
    Replies
    1. Hello Hasan,
      Do you know how to run a Python program on your Windows machine? Otherwise, the vendor has a windows-only application you can use to show you are getting a connection... you can find instructions at https://fineshang.gitbooks.io/esp8266-based-serial-wifi-shield-for-arduino-user/content/chapter4.html

      Delete
  2. The wifi board EPS 13 troubled me for a few days. Thanks for your great tutorial. It does work! Appreciate!

    ReplyDelete
  3. Thanks: Saved me days of frustration. These manufacturers cheat us by not following through with instructions. I guess thats why Ada/Spark charge what they do.

    ReplyDelete
  4. Thanks a lot for your detailed instructions. I have succeeded in communicating with my Arduino remotely by connecting to the AP network created by the shield.

    Is there a way to use the Wifi shield to connect to home wireless network, similar to the way one connects a laptop/phone? This way Arduino will get a local IP address from my wireless router (DHCP) and I can connect to it using "nc localIP 9000" without connecting to its own network.

    Thanks again for your notes.

    ReplyDelete
    Replies
    1. I have managed to successfully connect the Arduino wifi shield to home wireless network. Here are my configuration settings (location: 192.168.4.1):

      Station: Enable (Refresh)
      AP list: Choose your home network
      AP password: your_password
      DHCP Enable: Yes
      Rest of STA parameters should be non-active now

      Network Configuration:
      Socket Type: Server
      Transport Type: TCP
      Remote IP/Local Port choices will deactivate when you choose "server"

      Delete
  5. To send the other way is simple.
    On the sending machine change tcptest.py to :
    import socket
    import sys
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_address = ('192.168.1.219', 9000)
    print >>sys.stderr, 'connecting to %s port %s'% server_address
    sock.connect(server_address)
    print >>sys.stderr, 'Connection made!'
    message="Trust no-one"
    try:
    sock.send(message)

    finally:
    print >>sys.stderr, 'closing socket'
    sock.close()

    then on the arduino :
    String rx="";
    void setup() {
    Serial.begin(9600);
    }

    void loop() {
    int lf = 10;
    if (Serial.available() > 0) {
    rx = Serial.readStringUntil("\n");
    Serial.print("I received: ");
    Serial.println(rx);
    }
    }

    Simple as that.

    ReplyDelete
    Replies
    1. ACH ! indenting's gone slightly awry, you get the idea though

      Delete
  6. I am very new to Arduino so please forgive me if this is way off base. Basically, if I am understanding this correctly, Serial.print() is used to both send data over wifi AND print it to the serial monitor. As a result, if any incoming data is printed to the serial monitor it is immediately sent back to the wifi, resulting in an echo like effect.

    I am trying to use this shield to send HTTP GET and POST requests to an API. Unfortunately, it seem that if I try to print the response from the server it is resent, resulting in an infinite loop of 400 errors. Once I have it functioning properly there will be no need to print to the serial monitor, but until then, I need this functionality for debugging. Does anyone know a solution to this problem, preferably one that doesn't require any "hacking" or additional hardware?

    ReplyDelete
  7. This comment has been removed by the author.

    ReplyDelete
  8. This comment has been removed by the author.

    ReplyDelete
  9. When I connect the ESP-13 to an Arduino UNO, only the red LED lights up not the blue one. And I see a wifi SSID AI-THINKER_xxxx and not DoitWiFi_Config. Connecting to AI-THINKER does not show up anything at 192.168.4.1. I've tried a RST and KEY press but no luck. Any ideas why the blue LED is not coming on?

    ReplyDelete
    Replies
    1. I have got the same problem did you find anyway to solve it??

      Delete