With the press of a button this device will connect to your Wi-Fi, search a couple API sites, and print out the data of interest out on receipt paper. If the printer runs out of paper, the user will be alerted, and can not print until the paper has been replaced. The device makes use of a PIC18F microcontroller, ESP8266 Wi-Fi module, and CSN-A2 thermal receipt printer. Due to time constraints, and the complexity of this project, there is much room for improvement in future versions. This doesn't go into too much detail, but explains the general design process and challenges. Hopefully it can still be of some value to people. Check out the code at Github if you want to see how the code fits together.

Revision 1:

General Improvements:

For development process see project logs.


Original


API Configuration:

Weather data was retrieved from OpenWeatherMap, and word data was retrieved by Wordnik. These are both free services that are quick to set up and easy to use. The data format returned by these are JSON.

Example of call from OpenWeatherMap:

http://api.openweathermap.org/data/2.5/find?q=<city>&units=metric&appid=<API-Key>

Example of call from Wordnik:

http://api.wordnik.com/v4/words.json/wordOfTheDay?api_key=<API-Key>


HTTP Communication

To be able to communicate with the servers to request data, some basic understanding of HTTP is needed. To ask the server for the data at our URL of interest, we need to make a GET request. The full GET request format can be found in the Github code, but there are 3 steps to make the API call. First, begin the connection with the server and wait for response. Next, tell the server how many bytes of data you will send it and wait the for the response. Finally make the GET request, and wait for the server to send the data.


Parsing Data

The trickiest part of the project was parsing the JSON data. Below is an example of how to find temperature and wind speed from the OpenWeatherMap data:

There is a lot of useless data here, and this is an example of a very short API response. A forecast of several days would be thousands of characters. Because of this, it isn't reasonable to save the data first, and then parse through it. The amount of data stored becomes problematic for most microcontrollers. Rather than spend money and time on external data storage, I used a byte-by-byte parsing method. JSON parsing libraries exist, but can only be used if the whole body is saved

The amount of data in a JSON response is dynamic, but the objects (**usually**) come in the same order. So to find the temperature value of 7.9, I can read each byte, and once I had read 4 "{" characters, I will be expecting "temp": next. I can then skip bytes until a ":" appears, and then record data until a comma appears.


Wi-Fi Module and Thermal Printer

Both of these devices used serial RS232 communication, and had their own unique command set. The ESP8266 command set can be found here. The CSN-A2 printer used the ESC-POS (Epson Standard Code - Point of Sale) command set which can be found here.


PIC Microcontroller

In our classes, we studied Microchips PIC18F series of microcontrollers, so it made sense to use a microcontroller from this family for my project. I used Microchip’s search function to narrow down the search based on my needs. I need a microcontroller with a 3.3 Volt operating voltage as communication with my chosen Wi-Fi module needs to be done with 3.3 Volts. Two onboard USART modules are needed for this project, one for the printer and one for the Wi-Fi module. The microcontroller that best fits the needs of this project is the PIC18LF25K22. It fits the specifications listed above, and has mid-range program memory and RAM. I ran the micro at 16MHz.

USART Comm Speed

To communicate with the ESP8266 (variable baud rate), I initially ran it at 115200 baud rate, but due to the need to compare data received in between transmission, I dropped it down to 19200. The default speed to communicate with the receipt printer was also 19200 baud.


Hardware

The entire design was put together and designed in the classroom, including the PCB. My inexperience in PCB design really showed with this project. Forgive my rushed graphic composite below.

My first error was putting the silkscreen on the wrong sides of the board. Luckily I didn't bake it before realizing, so it wasn't too bad to scratch it off. The biggest mistake was routing power to my micro improperly, as I had mixed up Vdd and Vss on my software design. This resulted in the death of my micro, and reinforces the need to buy components in multiples. I was able to do a couple jumps and scratch a couple tracks to fix this.

My LCD was failing to be configured, and I realized that I had routed the data pins for the LCD backwards. I added a small subroutine to reverse the bits before sending them out on the port. Finally, I managed to order surface mount decoupling caps in metric rather than imperial, so they were microscopic. In my rush I had to made do soldering small thru-hole caps to the pads. Despite all the issues I got there in the end.


Recommendations

There are several ways this design could be improved, but the main ways would be to perform better in low signal strength areas, and being more efficient when parsing through very large amounts in incoming data.

The Wi-Fi module used in this project was a version with an on-PCB antenna, which performs poorly in low Wi-Fi signal areas. An easy way to improve this would be to use a module version with the option for an external antenna. Another improvement to the software would be better handling of lost signals mid-transmission. In its current state this would cause the program to freeze, but with some more advanced handling techniques, that could be avoided.

The other recommendation I would make is that if it were necessary to parse through very large amounts of data, it would be an option to do the data requisition by another server, parsing it there with more reliable techniques, and then sending only the data of interest to the Wi-Fi module. Though it would be more expensive and require more knowledge of HTTP, doing the heavy parsing server-side would free up processing for the microcontroller to do other things, and would make maintenance on the project much easier. If for example an API service shut down, I could find a new one and make the necessary changes server-side without having to reprogram the device. If one of the API services I used in this design were to close down, the device would be rendered useless, and would require updating and reprogramming.


Future Development

A great part of this project is my ability to continue working on it and making changes to it. Aside from working on the improvements discussed above, I'd like the next version of this device to print off the weather forecast of the day, every morning at the same time. I will also look into other API services to display more than just the weather and word of the day.


Thanks for reading! If you have any questions or suggestions, feel free to leave a message!