Week 12Home


This week we learned how to create interfaces and program applications.


The Goal:

This week, our goal was to make an interface to a microcontroller board we made. For this week, I decided to continue work on my board from week 10, which I would need for my final project. My week 10 board was able to access the internet, and read a page, but it was not able to parse or respond to data from that webpage. For this week, I planned to give my board the ability to parse and use the input from the webpage interface.


Automatic message division timer

My board from Week 10 didn't have any way of parsing messages from the ESP8266, so it had no way of knowing what constituted an entire message in order to display the message as a whole instead of breaking messages pseudorandomly depending on when a certain line of code ran. In order to make message parsing more reliable, I took advantage of the close byte spacing of the ESP8266 messages. I added code so that after every byte received, the 8-bit timer is started. If another byte starts coming in before the timer expires, the timer is reset to zero and restarted after the byte has come in. If the timer overflows (reaches 256), this triggers an interrupt routine that causes the message buffer to be processed and sent to the LCD.

The theory behind this is that the separation between bytes coming from the ESP8266 in a continuous transmission is about the single-bit spacing for 115200 baud communication, which is 8.7 microseconds. The 8-bit timer, which is run on the 20 MHz MCU clock with no prescaling, should count up to 256 in 12.8 microseconds. Therefore, if the timer overflows before another byte has started coming in, it is safe to assume that the ESP8266 has finished sending a unit of text and that this text can be displayed as a complete message. The message buffer can then be cleared and made ready for the next message so that every message starts at the start of the buffer instead of being randomly placed and divided as before.

This materially improved my ability to make a connection correctly. Earlier, since the messages were often unintelligible, I had to guess when to press the button to send the next command. Often, I would end up pressing the button too early, causing an error and forcing me to reset and start again. Now I was able to wait until I saw the correct message displayed to send the next command.


Automatic message parsing and response

Next, I wanted to give the ATTiny44 the ability to send the sequence of commands automatically rather than relying on the user to press the button at the correct intervals. I first tried simply waiting a short time (e.g. 10 seconds) between commands in a for loop. This sometimes worked, but was unreliable and slow since most commands run very quickly, but the actual connection to WiFi can be very slow and varies from instance to instance. I therefore decided to give my board message-parsing and response abilities so that it could detect when the ESP8266 sent the ready message.

I added code so that every time a message is received (see message division section above), the message is checked for certain strings (OK, >, (ERR)OR, ). Upon receiving one of these codes, the ATTiny sends the next command to the ESP8266. Because there is no response after the 5th command, I had the ATTiny send the 5th and 6th commands consecutively with no break.

This still required the user to press the button to start this sequence after the ESP8266 had initialized. I removed this requirement by adding code to listen for the "(GOT) IP" message, which signals that the ESP8266 is done initializing. The ATTiny then initiates the command sequence.

String processing for web interface

Now my board was able to automatically connect to the internet and request my test webpage, but it wasn't able to do anything intelligent with the contents of that page. The challenge was to give the board the ability to separate the page contents from the preceding metadata and then to extract the desired message string from those page contents in order to display a message on the LCD. I considered my options and decided to use a special character (#) in my webpage to signal the start of the desired data (message string). I then added code so that my board would look for and extract the location of this special character in the reply of the ESP8266 after the final page request had been sent. Because my desired 15 character + '#' string could be arbitrarily placed, and therefore circularly shifted in my 16-character buffer, I then had to perform a circular shift to place the start of the message string at the start of the buffer. In order to save memory space, I found and implemented an algorithm for an in-place circular shift consisting of the reversal of the two halfs of the buffer, their recombination, and then the reversal of the entire buffer. This would place the start of a 15-character string at the start of the buffer, allowing the string to be correctly processed and displayed on the LCD.

Automatic updating

A system that gets information from the web can't be static and shouldn't require user action to refresh information that may change, so I used the ATTiny's second timer to implement an auto-update system. I set this 16 bit timer with a /1024 prescaler so that it overflows once every 3.35 seconds. Upon overflow, the interrupt handler triggers a new page request to the webserver, processing and displaying the new message on the LCD.

System integration

Finally, although this is not really interface-related, I ended by adding in the temperature measurement and display code from Week 9 so that the chip also reads and displays the temperature every time it refreshes.


The Result:

The result of all this is a system that uses an ESP8266, a 16x2 LCD, and an ATTiny44a and makes use of a diverse set of ATTiny hardware capabilities including:

And in the end, it is a nifty desktop gadget (see Final Project for packaging, I hope...). The video below shows the board automatically receiving and displaying an update pushed to the server.



Files