RSS Reader using AVR mega8

I spent part of an afternoon developing a hardware RSS reader (most of my time was spent on the python side of things).

It’s pretty simple and uses an AVR microcontroller connected to a computer via a serial cable.

x1

Hardware

I am using the Dragon Rider 500 as a development board. This provides all of the hardware you need (assuming you have all of the add-on kits). That being said you certainly can do this with your own hardware setup:

  • ATmega8 microcontroller (or any that has a USART and enough pins for all connections)
  • A way to program the microcontroller (I use the AVR Dragon)
  • MAX232 chip for the serial communications
  • DB9 connector
  • HD44780 LCD screen
  • Crystal (I used an 8MHz crystal)
  • Assorted capacitors and resistors

dragon_rss_schematic1

On the Dragon Rider we will need to use some creativity to Route the connections. Normally Port D could be connected directly to the LCD header. This is not the case here because the USART needed for the serial connection uses PD0 and PD1. Furthermore, Port B cannot be used because PB6 and PB7 are in use for the external crystal.

lcd_jumper

In this pictured you can see my solution to this problem. I pluged in a ribbon cable into the headers for the LCD, Port B, and Port D. I then use jumper wires to make the proper routes. Don’t forget to hook up voltage and ground to the LCD header.

Software

The software for this project comes in two parts, the firmware for the microcontroller and the python script for scraping the RSS feeds and sending them over the serial connection.

AVR Firmware

I’m using Peter Fleury’s LCD library again (http://jump.to/fleury). It’s powerful, concise, versatile, and easy to alter for your hardware setup. If you look at the header file attached (lcd.h) you will see that I’m running in 4-bit mode with Port D as the data bits, and Port B as the control bits.

The concept of this firmware is pretty simple:

  • Once powered up the microcontroller displays “RSS Reader” and then waits for serial data.
  • Each byte of serial data received causes a buffer of 16 chars to shift left and add the byte to the buffer, then display the buffer.
  • Three special commands are accepted by the microcontroller: 0x00, 0x01, and 0x02. These are clear screen, move to line 0, and move to line 1 respectively.

Python Scrypt

I wrote a pyton script to scrape the RSS data and send it over the serial connection. This requires the python module “pyserial” which you will have to install on your system to get this to work.

The RSS feed can be configured at the top of the pyton file. Notice that you need to enter a name for the feed as well as the feed url. There are three examples there, I’m certain you can follow those for the proper syntax.

Making it all work

  1. Assemble the hardware
  2. Program the microcontroller (m8-Serial_Comm.hex can be used if you don’t want to compile this yourself). Fuse settings for ATmega8 using an 8 MHz crystal: lfuse= 0xEF hfuse=0xD9
  3. Power up the Dragon Rider and make sure the serial cable is plugged in (LCD should read: “RSS Reader”)
  4. Execute the python program (python serial_rss.py)
  5. Enjoy

[digg=http://digg.com/hardware/DIY_RSS_ticker_using_AVR_LCD_and_Python#]

Downloading the Source Files
I can’t host .zip files on wordpress.com. Because of this you will need to visit instructables.com to download the package for this project (sorry for the inconvenience).

Dragon_RSS.zip

Update:
I have since discovered that my python scraper was done the hard way. Here is a new version of the python script using the “feedparser” module.

#Rev3 2/27/09

#RSS feed Urls: Enter only the url, titles will be pulled down from feed.
rss_urls = (
        'http://hackaday.com/feed/rss',
	'http://rss.slashdot.org/Slashdot/slashdot',
	'http://feeds.digg.com/digg/popular.rss',
	'http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml'
	)
charDelay = 0.2 #Seconds to delay before pringing next character.

max_feed_items = 0 #Maximum number of articles to scroll from each feed (0=unlimited).

import feedparser
import serial
import time
import unicodedata

#setup RS232 communitcations protocol
ser = serial.Serial(0, 9600, stopbits=2)

def unicode2ascii(myString):
    #Convert unicode to ascii, replacing characters that don't exist in ascii with '?'
    return unicodedata.normalize('NFKD', myString).encode('ascii','replace')

def serial_scroll(myString):
    for char in range(len(myString)):
        #Write the next character in the string
        ser.write(myString[char])
        #Pause for scrolling effect
        time.sleep(charDelay)

def write_feed_title(myTitle):
        ser.write(chr(0x00)) #clear lcd
        ser.write(chr(0x01)) #tell lcd to write to line 0
        #Write title so that it is left-aligned (on 16 character display)
        s = myTitle + (' ' * (16-len(myTitle)))
        ser.write(s[:16])

def display_article_titles(feed):
    #tell lcd to write to line 1
    ser.write(chr(0x02))
    for item in range(len(feed.entries)):
        s = unicode2ascii(feed.entries[item].title)
        serial_scroll(str(s))
        #Check for how many story titles to display
        if item >= (max_feed_items-1) and max_feed_items != 0:
            #Scroll spaces to clear screen
            serial_scroll(' ' * 16)
            return
        serial_scroll(' --- ')

while 1:
    for feed in range(len(rss_urls)):
        curFeed = feedparser.parse(rss_urls[feed])
        write_feed_title(unicode2ascii(curFeed.feed.title))
        display_article_titles(curFeed)
essential