Introduction: Easy ESP8266 WiFi Debugging With Python

About: Founder of Powerhouse Electronics. For more info goto:

The new sub $5 dollar ESP8266 WiFi module makes inexpensive IoT way more possible and easy for mere mortals like me. In fact, I just did a search on and I found the same module for $3.25 (free shipping, but of course) in quantities of one. How I can have one of these modules shipped from the other side of the earth right to my door for $3.25 is still a mystery to me. Anyway...

In a nutshell, the ESP8266 module is a super inexpensive (note, I did not say cheap because they seem really good) WiFi module for embedded apps. It appears the module has an ARM micro that is re-programmable and there are a lot of folks gaga over that.

For me, I just want a little IoT board that can chirp out some data onto my WiFi network now and again. You know, like when the mailman drops off the mail. The ESP8266 right out of the box has a set of TTL Rx / Tx pins that communicate at a default 115k serial baud rate. Note, early modules came set with a default of 57.6k baud rate. So, the default module communicates at 115k using an old modem style super simple AT command protocol. Basically, commands (all start with "AT" hence the name) are sent to the module using something like "AT+RST" (commands the module to reset) and the module responds - usually responding to each command with a "OK".

But the devil is in the details.

Before there is any hope of embedding a ESP8266 module in a mailbox detector IoT device the AT commands between the ESP8266 and the controlling micro really must be understood fully. Therefore, to make it easier to test and debug controlling the ESP8266 module this Instructable will show how to hook up a new ESP8266 to a PC and test / control it using some simple Python code.

Step 1: Hardware Setup

There are two problems that make hooking up the ESP8266 directly to PC difficult. First, the module uses 3.3Vdc TTL Rx and Tx lines to communicate. Second, the module's datasheet indicates the module will need up to 300mA of 3.3Vdc supply voltage.

The easy solution to the first problem is to simply use a FTDI 3.3V USB serial cable. I've had a couple of these USB-to-Serial cables for years. Looks like Adafruit has these in stock for around $20 bucks. There are some other types around but the FTDI is the gold standard. Only problem with the FTDI converter is that the Vcc output from the cable is 5Vdc and not the needed 3.3Vdc. Seems strange given the TTL signals on the FTDI cable are at 3.3Vdc - guess they got cheap and dropped putting a step down regulator in the converter.

So, the second problem is to down convert the FTDI 5Vdc output to 3.3Vdc @ 300mA. My solution was to use a little regulator I had in my parts bin. Specifically, I used a Mic5239 which can be found at Mouser. Since I had ten of these in my parts bin I decided to sacrifice one for the greater good. I solder the regulator down to a little hunk of PCB and hot glued the whole mess to a DIP socket. In the first picture in this Instructable the regulator is visible on the right-hand edge of the breadboard. It's ugly but seems to work well. Would have been much easier if I had originaly order the regulator in a larger SOIC package instead of the tiny MSOP-8 package. Rule to self - no more super tiny parts.

As a plus, in the 8 pin package of the Mic5239 regulator there is an enable pin. The enable pin must be pulled high for the 3.3Vdc output to come on. So, as a trick, I tied the regulator enable pin to the FTDI RTS output pin. Therefore, using Python, power to the ESP8266 can be turned on and off! Turns out, even though I did NOT turn on hardware flow control in the Python code the Python serial driver (called PySerial) still allows control over the RTS output pin.

Step 2: Software

There are three bits of Python code for this Instructable.

1) "" -> This Python code provides a TCP server that the ESP8266 can connect to. Simply edit the code so that the IP number in the source code matches the IP number of the machine your running this on. The server simply allows a client to make a TCP connection, accepts some data, and sends back some junk data. That's it. The server just starts up and then waits in an endless loop for clients to connect.

2) "" -> This Python code provides a way to test "" is working correctly. So, with the server code running on one machine, run "" on another computer on your network. Run the client as " Some data to send goes here." The client app sends whatever is given on the command line. In this case, the client would send "Some data goes here." to the server. Both the server and the client will show some output that indicates a successful transfer.

3) Finally, "" can now be used to test for a TCP connection to the Python server. If all goes well, the server and "" will show some output that indicates a successful transfer. Once again, before running "" edit the code so that the IP numbers match. Run as " MySSID MyPasscode" - the SSID and passcode must match your WiFi settings.

Using the Python Test_ESP8266 code I learned a couple things about the module. After getting everything working and verified with the server I simply tried using a bad passcode, as a test to see what would happen. Everything appeared normal until the actual command to form the TCP connection. The command that failed was "AT+CIPSTART='TCP','',9999". However, I would have expected the command "AT+CWJAP?" to fail first. The "AT+CWJAP?" command returns the SSID and RSSI of the AP the ESP8266 is connected to. With a bad passcode it should not have been able to connect.

Goofing with the code I think I've discovered a trick. After connecting to the AP, ask for the ESP8266 IP number. Even with a good passcode it may return "ERROR". No worries, just dwell a couple seconds and ask again. With a good SSID and passcode the ESP8266 will eventually return the IP number. After a good IP number is returned the TCP connection command always seems to work.

Another trick, if a bad passcode is used the ESP8266 module gets stuck! Regardless of the command sent the module returns "buzy now ...". Even the "AT+RST" (reset) command is ignored. The work around is to use the regulator to cycle power to the module. Using the RTS pin on the FTDI USB-to-Serial converter - which connects to the regulator enable pin - the regulator 3.3Vdc output can be switched off. An off time of 10 seconds seems to work well.

Well, that's is. Hope this helps,


BTW: For the latest and greatest updates please visit my web site: