Our project was a real-time weather update system that accepted an airport code from the user via a keyboard, looked up the code on an internet database, and displayed the resulting weather information on a television screen.
We used the PS/2 protocol, between a standard keyboard and an Atmel Mega32 chip, to decode the airport code typed by the user. The keyboard only worked on a PS/2 protocol, explaining our decision to interface with it by reading data off of pin 3 of port D on the keyboard MCU. After receiving each character the user entered, the program keyboard.c sent the byte over the serial peripheral interface (SPI) to a second MCU running tv.c on a custom-built board. We used SPI because it made the most sense in this dual processor situation, where both chips were in close proximity with each other. The keyboard chip also sent complete airport codes over the UART to the personal computer running a program in Visual Basic (VB) to perform the internet query. Visual Basic .NET 2005 Beta provided functionality for serial communication, so it seemed like a sensible choice for the PC program. After the VB program obtained the weather data, it sent the information back over the UART to the keyboard MCU, which then used the SPI to convey the values to the custom board. The TV MCU then output the data in a readable fashion onto the tv screen.
High Level Design
Our rationale for project was that it is often tedious to open up a browser on a PC to look up the current weather on sites like weather.com. We thought it would be useful to have a stand-alone device where all one would have to do would be enter an airport code and immediately receive the most updated weather information. The project was also a proof of concept for many topics in ECE 476, such as UART, video, and SPI. Therefore, we focused on breadth rather than depth in the project, integrating various technologies into a system that performed a specific function.
The project required no background math past that which one would consider basic in a course like ECE 476 (e.g. simple arithmetic).
We had to use two MCUs because all of the keyboard.c processing could not occur with video being blasted to the tv at the same time from the same chip. Using one MCU cause severe flicker on the screen so we broke our program up into keyboard.c and tv.c, eith tv.c loaded onto the custom boards Atmel Mega32 chip. We used the Serial Peripheral Interface to communicate between the two MCUs, rather than say another UART connection, because this was easiest to implement and it lent itself best to this situation in which the two chips were in close proximity to each other. On the PC side, we had to have a server called ApacheFriends running in order to run the PHP script which would perform the internet query. We had the PHP script write back to a text file because the VB program could easily open and read the results using existing VB file management commands.
The major hardware tradeoff of our design was using two MCUs for the keyboard and video portions of our project. Using one MCU would have been a more elegant solution, although much more difficult to implement (if not impossible) with the Mega32. We had to contend with timing limitations from using only one MCU and were forced to solder together an MCU protoboard to use along our SDK500. The SPI interface used to communicate between the two MCUs, on the other hand, proved to be the most effective and fastest means of serial communication.
One of the major software tradeoffs of our design was in using airport ICAO codes to identify locations for weather information, instead of a zip code or city name. Originally, we wanted the user to be able to input a zip code or city name on the user interface, and have the PC lookup weather data for that location from the Internet. However, we found that the METAR reports we mentioned above are specified for an airport location, which is identified by its ICAO (International Civil Aviation Organization) code. The PHP script we used to retrieve and parse weather information also required an ICAO code as input. Ideally, we would have created a database to map zip codes or city names to the nearest airport (and its respective ICAO code,) to allow for a more intuitive user interface. While these databases are available online, we felt that this would have been beyond the scope of this project’s main objectives.
WeatherDog made use of four standards, PS/2, RS232, ANSI, and IEEE 802.3. First of all, the keyboard for the device had a PS/2 connection, so we needed to be able to work with the PS/2 standard in interpreting keyboard outputs. This allowed us to interface to the keyboard so that the keyboard MCU could receive data from it. The reason we used the PS/2 standard for the keyboard was it was the way the standard keyboard we used was sending the MCU data, so we were not be able to realize direct conversion to other data forms, e.g. RS232. Furthermore, we only had to decode scan code Set 2, which made our keyboard code much simpler since it only had to work with the most common type of keyboard. Secondly, we used the RS-232 standard for the serial communication between the chips UART and the PC at 9600 baud. Thirdly, we write the code for the chip in ANSI C, an obvious standard necessary for the project. Fourthly, we used the SPI standard to communicate between the two MCUs. Lastly, although we did not deal with this directly, the ethernet connection required to obtain the data over the Internet demanded the employment of the 802.3 standard for carrier sensing multiple access (CSMA) protocols.
Patents, copyrights, and trademarks
Because our design for looking up weather information from the internet on a PC relied on some freely-distributed programs and other available code, we needed to be well aware of issues in using someone else’s intellectual property. The beta version of Visual Basic 2005 Express (running on the .NET 2005 platform) is distributed by Microsoft Corporation. Beta versions of any software package are usually distributed freely before a final release in order to get new users to report bugs in the software and become familiar with the new interface. Since we did not make any modifications to the software or distribute it ourselves, we did not violate any copyrights. Similarly, we followed the same guidelines in using the software package for the Apache Web server made available from Apache Friends.
The weather services PHP script we used was distributed by “The Pear Group” and was written by the voluntary contributions of a number of individuals. The license agreement form included with this code specified that “[r]edistribution and use in source and binary forms, with or without modification, is permitted” under a number of guidelines, including that “[r]edistributions of source code must retain the above copyright notice.” Since we did not actually modify this code (and instead wrote our own PHP script to interface with the one we obtained,) we did not need to contend with any copyright violations.
Interfacing with the keyboard
The first tricky portion of our program was decoding the keyboard input from the user. We basically had to map the keyboard scan code Set 2 codes sent from the keyboard onto ASCII characters to be sent over the UART and SPI. The following figure illustrates the codes the keyboard sends, and they were mapped to standard ASCII characters, uppercase for letters:
In terms of the PS/2 protocol, when the user presses a key, the internal clock of the keyboard (which normally stays idle) begins to pulse at 20-30kHz; the data line then transmits the following 11 bits, one on each clock period: a start bit (logic 0), eight data bits (LSB first), a parity bit (odd parity), and a stop bit (logic 1). The following diagram, also reproduced as Figure 1 in Appendix 3, shows the generic keyboard transmission:
We wrote an ISR for the MCU, triggered by the falling edge of the keyboard’s clock on the INT0 pin. On each call to the ISR, it reads the keyboard data line at that clock period. Once we receive all data bits, we decode the input into its equivalent ASCII character. Upon receiving the <enter> symbol from the keyboard, we transmit the input string through the UART to the PC.
Interface Between the Two MCUs
With the keyboard clock running at 12.2kHz, a single key press, which requires reading 11 bits for a make code and 22 bits for a break code, takes about 2.7ms to decode, with 33 calls to an ISR which executes on each falling edge of the keyboard clock and reads the data bit on the keyboard input. On any single key press, calls to this ISR could interfere with the sensitive timing of the video code used to output to the TV screen. The video code blasts one line to the screen every 63.625us, and refreshes each frame every 1/60 of a second, with only about 4ms between frames for calculating the new frame.Because of these timing issues, the scheme we used to decode a PS/2 keyboard input could not be implemented on the same MCU as the video code. We were forced to think of possible alternatives to allow two MCUs to communicate with one another without interfering with the sensitive timing of the video code. One possible alternative, implemented by a previous group in the past, was simply to connect ports on both MCUs directly. The disadvantage of this scheme was the lack of any protocol that could be used to send a significant number of bytes (such as in a string) serially between the two MCUs. Alternatively, another group had simply used the UART serial communication ports to transfer data between two MCUs. While this would have been the simplest solution to our problem, our serial port on the keyboard MCU was already dedicated for the connection to the PC, used to look up weather information from an Internet database. Finally, the best solution was using the Serial Peripheral Interface (SPI) provided on the Mega32 processor.
Unlike the UART, the SPI is normally used for serial communication over very short distances, such as between two adjacent MCUs, as was our case. Because it is a synchronous form of communication, both the receiver and transmitter must use the same clock. This is guaranteed by a master/slave interface; while both a master and slave MCU can send and receive data to and from one another, the master is responsible for providing the clock signal. The scheme summarizing the master/slave configuration (obtained for the Mega32 datasheet) is shown below, also Figure 5 in Appendix 3:
To transmit data, the master pulls down the slave select (~SS) pin on the slave to enable communication. The master then shifts out eight bits of data, one bit per clock pulse, out of its master-out-slave-in (MOSI) pin and shifts it into the MOSI pin of the slave. The slave, likewise, simultaneously shifts out eight bits of data out of its master-in-slave-out (MISO) pin and into the MISO pin of the master. The pin directions used in our scheme are shown below:
Because the directions of each of these four pins on the master and slave MCUs complement one another, they were simply all connected directly.The SPI control register, SPCR, enables or disables SPI and its corresponding interrupt mask bit, as well as sets parameters such as master/slave designation and clock rate. In our configuration, we used the keyboard MCU as the master and the video MCU as the slave. This made a lot of sense because the keyboard MCU was also responsible for interfacing with the PC over the UART serial port to receive weather data and transmit to the video MCU.
To output a byte, the master runs the following lines of code:
PORTB.4 = 0; //pulls down ~SS
SPDR = buffer[i];//outputs value of buffer[i] to slave
When transmission is complete, a SPI_STC interrupt is called and the ~SS pin is pulled back up with PORTB.4 = 1.
On the slave side, we disabled the SPI interrupt because of the sensitive timing nature of the video code. Instead, we simply check the interrupt flag (7th bit of the SPI status register, SPSR) during the allotted 4ms between frames every time. Thus, the following line of code receives a byte from the master:
if ((SPSR & 0x80)>>7) input = SPDR;
Note that we did not need to send any bytes from the slave to the master.
Interface Between the PC and the Internet
In order to interface the MCU with a PC to retrieve weather information from the Internet, we needed to write a program on the PC that would support serial communication. In addition, we had to choose a suitable programming language on which to write this program. Since we did not want to spend too much time on this aspect of the project (and instead focus on the hardware interface,) we chose to use a beta version of Visual Basic 2005 Express, made freely available by Microsoft at http://lab.msdn.microsoft.com/express/vbasic/default.aspx. Visual Basic is a very user-friendly programming language, often simplifying very difficult tasks to drag-and-drop controls and a few lines of code. Also, unlike Visual Basic .NET 2003, the beta version of Visual Basic we used includes a basic “Serial Port” control. Our code for serial communication on the PC side was very simple. We could send any string of data to the MCU over the UART serial port after dragging a Serial Port control to our Visual Basic “Form” and using the following line of code:
Likewise, to receive data over the serial port, our Visual Basic program calls an “Event” that is triggered by data being placed on the serial port buffer. In this event, we simply use the following line of code to retrieve the data:
receive_string = SerialPort1.ReadLine()
Being able to output weather information from the Internet was a lot trickier than we had originally thought. We found a weather services PHP script freely-distributed for use at http://pear.php.net/package/Services_Weather/, which could retrieve and parse current weather information from freely-available METAR reports provided by the National Oceanic and Atmospheric Administrations National Weather Service (http://weather.noaa.gov/weather/metar.shtml) for various airport locations around the world. METAR reports are rather cryptic documents containing weather conditions about a location including temperature, humidity, wind speed and direction, visibility, pressure, precipitation, and many others. The following is an example of a METAR report for the Chicago OHare Airport:
Decoding such a document so that we could retrieve simple weather conditions was beyond the scope of what we could do for this project, so we relied on the PHP script we had obtained to do just that. Neither one of us had any experience using PHP, which is a cross-platform, HTML- embedded scripting language that runs on a server and is normally used to create dynamic web pages. Since our goal was not to create a dynamic webpage, we had to find a way to run the PHP script and relay the retrieved weather information to a Visual Basic program we had written for serial communication with the MCU. To run a PHP script locally from our computer, we discovered that we needed to install a local web server. We used an installation package provided freely at http://www.hotscripts.com/Detailed/26145.html to install an Apache web server that could run PHP scripts locally. Because there is not an existing interface between Visual Basic and PHP, we decided that the easiest way to call a PHP script from our Visual Basic program was simply to execute the script from a command prompt (which could be easily done in Visual Basic) with parameters such as airport location also input at the prompt. To obtain the results of the PHP script (that is, the weather information,) we modified the script to write all pertinent values to a text file that could be easily read and parsed by our Visual Basic program. While this was clearly not the most elegant solution, it worked well enough to allow us to focus on the microprocessor and hardware portions of our project.
Interface to the TV
This interface was basically a matter of outputting the appropriate strings when necessary, and clearing old strings when new data arrived. It built upon the video game lab which we did earlier in the semester. New to the final project was consideration for how much we could output on each condition of LineCount == 231 (please see Appendix 2: Video Code). We divided the process of outputting to the screen into distinct stages, making sure to only output a small bit of video each time.
We used a 6-pin mini DIN connector to produce the wires on the end of the PS/2 keyboard so that we could connect them to the appropriate pins on the boards. See Appendix 2 for the output pins of the keyboard.
We connected Clock to pin 2 of Port D on the keyboard STK500 board, and Data to pin 3 of Port D. We used Port Ds Vcc and GND for the corresponding keyboard wires.
The pin directions used in our scheme are shown below:
For more detail: WeatherDog