Buzz words and catch phrases are always being generated, mostly in technology areas or politics. Even Dilbert got in on the trend with “Buzzword Bingo” back in the ‘90’s. One of the currently hot phrases is “Internet of Things (IoT)” so I thought it might be fun to see how I could use a PIC and a cheap Wi-Fi module to make my own IoT devices. This particular Episode will show how to interface to an ESP8266 module and use the default AT command interface to report information from the PIC. That will allow me to take something like the temperature sensor input described in in an earlier post and report the value on demand over my wireless network. With the wide variety of PIC interface capabilities available that’s just one of many possibilities.
ESP8266 Wi-Fi Module
There are many different versions of the ESP8266 Wi-Fi module available. The ones I bought from Tayda Electronics look similar to the pictures shown above. There is a mount for an external antenna but I just use the onboard one (it’s the small rectangle next to the antenna connection). This particular module is commonly known as the ESP-07 and comes with the AT Command Set firmware. Most any other version that also has the AT Command Set firmware will probably work as well for this project. There are also modules with different firmware installed that are more commonly used by Arduino folks. In any case, there are a number of firmware downloads available on the web as well as instructions for reprogramming the ESP module. We won’t get into that in this post.
The AT Command Set firmware itself has changed since the first ESP modules were made so the commands we will be using are applicable to firmware version 0.25.0.0 from June 2015. I found the version information using the AT+GMR command. A copy of the AT Commands document is provided below.
The schematic shows our old friend the 16F688 PIC, along with the USB to TTL adapter we used in Episode 17, and the ESP8266 module. There is also an LM1117 voltage regulator that is used to take the 5 volts (from the USB or from a separate 5 volt power source) down to the 3.3 volts that the ESP8266 needs. To simplify the wiring, we also run the PIC on 3.3 volts. I also included a 3-pin header so that I can jumper the command input to either the USB adapter (for commands from the terminal program) or to the PIC. The output of the ESP8266 goes to both the PIC and the USB port so that I can monitor the information on the terminal program even when the PIC is in control. You can also see that there is a resistor voltage divider on the USB module transmit output. That is required in order to reduce the TTL logic level to what is acceptable for the Wi-Fi module. We don’t need a divider on the TXD from the PIC because the PIC is running from the 3.3 volt supply.
As you can see in the picture, I wired mine up on a small breadboard. I included a 5-pin header so that I can plug the USB to TTL adapter into it for setup and test purposes and then remove it when it’s not needed. I also wired a standard power socket in parallel with the 5 volts supplied by the USB module so that I can use a wall wart when I’m not using the USB adapter. Make sure that you don’t have both plugged in at the same time. The USB adapter does have its own 3.3 volt output but it doesn’t supply sufficient current to drive the ESP8266 module.
One thing to note when wiring up the ESP8266 module is that the hole spacing doesn’t match the standard 0.1 inch spacing on prototyping boards. I cut short lengths of solid wire and soldered them into the module holes. I was then able to bend the wires sufficiently to get them soldered to the prototyping board. One other downside is that the pin markings are on the bottom of the ESP8266 module so make sure you know the layout before soldering it to the board. You could mount the board upside down so you could see the pin markings but that might diminish the range of the antenna.
One other thing to note on the schematic is that I show the “EN” pin on the ESP8266 connected to 3.3 volts. That is the enable pin but on some modules it is labeled “CH_PD” instead of “EN”.
Initial ESP8266 Setup
My modules have a default baud rate of 115.2 kbaud but some of the modules default to 9600 baud. The initial burst of information from the module is at 57.6 kbaud so it will look like garbage on the terminal program but it’s still an indication that the ESP8266 is communicating. As I mentioned in a previous post, I use the Tera Term terminal program. The basic setup is the same as was shown in that post but the termination characters for each AT command require both a CR (carriage return) and an LF (line feed). That setup screen shot is shown above. When you have the terminal program set up, then type AT (all commands should be uppercase). You should see the letters you are typing and get a response of “OK”. If not, then try setting the serial port to 9600 baud and try again. If that doesn’t work then recheck your wiring.
There is a terminal screen shot above that shows the sequence of commands used to initialize the Wi-Fi module before we hook it up to the PIC. The first several commands allow us to set some default values in the ESP8266 so that we don’t need to send them from the PIC. In general, we will set the baud rate to 9600 (if it isn’t already there), set the operating mode to “station” (i.e.: client mode, as opposed to access point mode), set a static IP address on our LAN, and then connect to an available Wi-Fi network (automatically reconnects on each power on).
Here are the AT command steps to use following the first connection to the terminal software:
AT+UART_DEF=9600,8,1,0,0 (9600 baud, 8 bits, 1 stop bit, no parity, no handshake)
AT+CWMODE_DEF=1 (sets to station/client mode)
AT+CWMODE_CUR? (verify that the current mode = 1)
AT+CWLAP (list the available wireless APs in your area)
AT+CIPSTA_DEF=”192.168.1.88” (set static IP local LAN – your number may be different)
AT+CWJAP_DEF= “ssid”,”password” (join a wireless AP from those listed by CWLAP)
AT+CIPSTA_CUR? (verify that the current IP is what you previously set)
Web Connection Testing
After getting the default settings in place you can test the connection to your network. In order to do that you need to enter a few more AT commands and then bring up your browser and enter the IP address that you set for the ESP8266. There are screen shots above that show these commands and results. Here are the AT commands to enable webpage communications:
AT+CIPMUX=1 (enable multiple connections)
AT+CIPSERVER=1,40000 (enable the server and set the desired port number)
After those commands, bring up your browser and on the URL line type in whatever you selected for your static IP and port number. Mine is shown below.
The browser should show that it is waiting for a connection and the terminal program should show that a GET request was made. The “0,CONNECT” response means that the ESP8266 has opened connection 0 for the webpage. If you open another webpage and type in the same static IP and port number the ESP8266 will respond with “1,CONNECT”. I was able to establish connections 0-4 by opening multiple web pages. Generally you only need connection 0 and that is what this project uses.
Now that the web page is open and the ESP8266 has accepted the connection, we can send some test data. A screen shot of the commands and the webpage response is shown above. Here are the AT commands for sending data:
AT+CIPSEND=0,5 (connection 0, 5 characters to be sent – response is the “>” symbol)
12345 (test data in ASCII characters – note that it will not echo on the terminal)
AT+CIPCLOSE=0 (close connection 0)
The data will not appear on the webpage until the connection is closed by the ESP8266. To make another request to the ESP8266 all you need to do is to refresh the webpage. You can then send more data using the CIPSEND command.
The software link is listed below. While it is targeted for the 16F688, it is easily ported to other versions of the PIC. Just make sure that you choose one that has the asynchronous serial port capability. You will also need to change the line that identifies the PIC version (LIST=) and the INCLUDE file but those are intuitive changes. The __CONFIG line may also need tweaking just because one or two of the labels used are spelled differently in some of the INCLUDE files.
The software basically mimics the commands we sent manually from the terminal program. At the appropriate points it waits for the expected responses from the ESP8266 before issuing further commands. The commands sent and the responses expected may need to change if the AT Command set gets updated in newer versions of the ESP8266. When sending out the command strings and the dummy message the PIC uses indirect addressing of RAM locations in banks 0 and 1. The code to initialize those memory locations is located at the end of the listing. Unfortunately, these older PICs are limited in their indirect addressing capabilities so we can’t just embed the strings in Flash memory like we did for the LCD Graphics Display in Episode 13. That project used a newer 16F1847 PIC and it would be easy enough to port this program to that newer PIC if you are so inclined.
In order to use a common routine to send the strings we could have either passed a string length to the routine or simply add an “end-of-string” character to each string. The second option is what I chose and to simplify it further I used the numeric value 0. That allows the code to load the next value and then check to see if the loading caused the Zero Flag to be set in the Status register. The string lengths defined include space for a carriage return and a line feed for each AT command and for the end-of-string identifier for all outputs. Note that the data sent after sending the CIPSEND command does not need a carriage return or line feed.
It is worthwhile to note that the ESP8266 sends back a lot of data that we really don’t care about. Because of that, having the serial receive code as an interrupt handler would not be a good way to go. The problem, however, is that just polling for responses will cause the receiver buffer to overflow. That is why the “Overflow” handler in the code is very important. It allows the PIC to simply clear up the overflow at its leisure and then wait for the expected responses. In previous listings where I hadn’t expected overflows I used the method described in the data sheet of disabling/enabling the serial port. That didn’t work properly in this program and I suspect it had something to do with the fact that the transmitter may not have been finished before the overflow was handled. Because of that I changed to the second method of clearing the overflow flag in which just the serial receiver is disabled/enabled.
The screen shot of the PIC messages to the terminal program and to the webpage is shown above. Note that the “Hello World” message sent is on two lines. That’s because the message has an HTML command included (<br>) which does a new line. That’s important to note because most any HTML command can be included in whatever you send to the webpage. While the message in this example is static, you could make it dynamic to suit your needs. Simply make a call to your own message creating routine in the “Send_Data” routine. As mentioned in the opening section you could read a temperature sensor, convert the value to ASCII, and then output the results whenever the ESP8266 receives a webpage connect request. For applications like that a refresh of the webpage will cause the PIC to send new data so you don’t need to close and then reopen the webpage. That’s it for this post. Check out my other electronics projects.