N.E. Ohio Weather Alerts:
10 Latest QSO's Are:
Aviation Operating Modes SDR Slow Scan TV My Logbook Awards My Station Weather My Projects Miscellaneous
N8MDP Contact Me
Tweets by n8mdp
Raspberry PI LED Badge
Weather Warning Application
A couple of years ago at the Dayton Hamvention, I purchased a number of LED Badges with the intention to hack them for usage with Raspberry Pi's. One of the use cases was to use the RPi to drive the LED Badge to display weather alerts and warnings. You probably noticed at the top of my website that I display weather advisories, watches, and warning as a marquee. But what if I am not looking at my website? How would I know whether there were alerts for where I live. Thus the idea to use the RPI and the LED Badge to to create a weather alert scrolling message board and place the system in my sunroom where it would update 24/7.
The pieces of the project were simple. A Raspberry Pi, and it can be an original Pi like I used, and an LED Badge like the one I show below;
These LED badge displays typically have a USB socket for charging and programming, and appear to a PC or Pi as a virtual serial port.
The badges come with Windows drivers and software to download messages to the device. The intention with the software is that you type in your message, download the message to the badge, then unplug and run the display from its internal battery. Messages are stored internally in flash memory so the device can be powered off and it will retain the message.
For my purposes, I need the Raspberry Pi to monitor weather alerts from the local National Weather Service and search for my county in lists of possible weather alerts. Once my county has been identified, the Pi will upload the message to the display and scroll the alert until a new alert message is identified.
So the first job was to get the device running on my Windows PC. The device installed as a serial device (the common Prolific PL2303 driver) and the supplied software successfully sent messages to it:
One of the problems with these LED Badges is that you don't know how the data is encoded when you send a message from the software to thge badge over USB.
So with the software working, we need to take a look at what it was sending to the device. To do this, I needed to obtain a serial monitor program. Based on other references online, I downloaded HHD Software Device Monitoriing Studio. This is a great tool for snooping on devices that use serial control such as USB devices.
I'm not going to go through the details of how to run the monitoring software but the important result is that you get a data view of the data transfered. To get the first results, I used the LED Badge software to send the message: Severe Thunderstorm Warning. The monitoring software captured the following:
It's very clear where the message is in the packet transfer. But there are other pieces of data, at least for my badge to be aware of. My badge allows multiple messages to be uploaded at one time. If you look carefully, there are blank areas where no characters were sent yet a block of '00' hex values are sent. This is important when writing the Python script that I developed for this application.
I should mention that a LED badge you have may not behave and transfer packets of data the same as mine. At least my analysis may help you to get yours working as well. Let's breakdown the data packet to explain what was sent.
The first set of 8 bytes (00 02 31 06 00 35 31 42 in Hex) appears to be an 8-byte header that is sent everytime a single message is sent. I duplicated this with other message tests. So every packet that is sent by the Pi must start with these first 8 bytes.
The next byte of interest is 1B Hex. Based on other message tests, this is a character count for the first message sent. Knowing this, we will be able to write a formula in Python to calculate the message length and include it in the data packet. For my message test: Severe Thunderstorm Warning, this is a 27 character message. 1B hex is 27 integer.
The next 27 bytyes sent is the message, from hex 53 to hex 68.
The first message block is a total of 60 bytes. Given that my test message was 27 characters, the remaining characters must be 00 hex and it is 60 - 27 = 33 characters to transmit.
The next byte to be concerned with appears to be a checksum byte. In the case for the Severe Thunderstorm Warning message, 89 Hex.
Testing different messages resulted in very different byte values that were sent. I tried for days to recreate how this byte was calculated, but was not successful. In order to send the correct checksum value, I had to confirm the value of all the alert messages I wanted the Python program to display. In my program, this was a total of 39 alert messages. I'll talk more about the alert messages and where they will be coming from later.
You will see in the Python program the different checksum values.
The next 4 bytes is another header, 02 31 06 40. This is a header for the second message that 'could' be uploaded into the badge memory. Whether you send a second message or not, the header must still be sent.
The next group of 64 bytes must be 00 hex since no message characters are sent. After the 64 bytes are sent, another checksum and 4 byte header is sent (77 02 31 06 80). Since I am not sending another message, I can always send the byte 77 as the checksum. I verified this in other test runs.
The next group of 64 bytes must be 00 hex since no message characters are sent. After the 64 bytes are sent, another checksum and 4 byte header is sent (B7 02 31 06 C0). Since I am not sending another message, I can always send the byte B7 as the checksum. I verified this in other test runs.
FInally, another group of 64 bytes must be 00 hex since no message characters are sent. After the 64 bytes are sent, another checksum and 3 byte header is sent (F7 02 33 01). Since I am not sending another message, I can always send the byte F7 as the checksum. I verified this in other test runs.
Understanding the packet structure, I needed to determine the messages I would send. The National Weather Service has a listing of standardized watches, warnings, advisories, and statement that they issue thorugh their RSS service. You can find this listing at https://www.weather.gov/help-map. The listing also provides priority levels that was helpful in my Python code should I recieved multiple warnings and watches for my county. This way, I display the highest prioirity message.
Here examples of messages and their priority level:
'Tornado Warning, 2
As a I said previously, for the 39 messages I planned to use, I had to test each and every one of them to get the checksum value to send when that message needs to be displayed. This is where the serial monitoring sofware came in real handy. Here are some examples from my Python program:
# Checksum based on NWS listing. This section assigns the Checksum value
Now the fun begins. The Python Code. I will break down the code so you can understand each section and what I did.
***** Python Code for running the Weather Alert badge on the RPi.
The first section is to import that necessary libraries. One of the most important libraries is the 'feedparser'. This is needed to parse the RSS feed from the NWS.
The next section of code defines and assigns the priority level of the messages based on the NWS listing.
The next section of code assigns the checksum values to each of the individual messages.
The next definition is the primary section that writes the packets of data to the LED badge through the USB port. You should recognize many of the bytes we obtained in the analysis from the serial monitor data dump.
#Open the USB serial port
# Block Group 1: Send the first 8 bytes
# Determine the length of the alert message string. Convert to hexadecimal
wxStringLength = len(alertMessage)
# Block 2 is the hex equivalent of number of characters to send. Write the 1 byte.
# Block 3: Need to loop through the number of characters in the string. Write them.
#Block 4: Send empty characters. Depends on the length of the wx_string.
for x in range(blankChars):
#Block 5: Send the message checksum.
# For some reason, I had to use the "latin_1" encoding for hte byte to send correctly.
#Block 6: Send the next 4 header bytes
#Block 8: Send the next checksum and 4 header bytes
#Block 10: Send the next checksum and 4 header bytes
#Block 11: Send the next block of 64 empty characters
#Block 12: Send the final 4 bytes
#Close the serial port
The next section is a display timer. Every 2 minutes, the display will update should a new prioirty message be recieved.
Now comes the main loop. This loop goes out and gets the latest NWS RSS feed for Ohio, parses the feed looking for the county I am in, adjusting the priority level if higher priority messages come in, and then send the message to the definition which writes the message to the USB port. I tried to comment the code as much as possible.
print ('Starting loop')
# Get the RSS feed from NWS for Ohio
# Obtain number of entries in the feed. This is a normal RSS action
# Reset the Priority Number variable to 900. This number will reflect No Watches/Warnings
#Run the loop timer for two minutes before next update.
That's it! I've been running this code successfully for many months. I set the Raspberry Pi to start the code automatically. So if we lose power or I shut down the Pi, all that needs to be done is to restore power and the Python script starts right up.
You can download the full Python script HERE.
I plan to expand the application by adding bright green, yellow, and red LEDs to indicate no warnings, watches, or warnings.
I hope you found this project interesting. Again, I must reiterate that not every LED badge or message board works the same. Many of the LED boards use the Prolific PL2303 driver, which is very common. Most of these boards are made in China and may use some kind proprietary coding for sending messages to the board. I have a larger LED board that programs completely different than the mini LED Badge I used here. So like me, you may have to do a little bit of hacking and reverse engineering to get your LED board to work.
I hope you enjoyed reading this project.
CQ CQ CQ
If you have a question or a comment. please do not hesitate to ask here.