Introduction: Arduino News Feed Notifier

This is an Arduino news notifier.

Function: It checks various online rss sources (both news and social media), and if it finds an update on any of these sources it signals with a LED and servo before displaying the news title on a LCD. In other words: no more need to lurk on your favorite news sources and hitting refresh during work. Aren't there simpler and cheaper ways to accomplish this, sure.

This is an updated variation of earlier designs with new functions. I'm most indebted to Fritterdonut (https://www.instructables.com/id/Wiring-up-the-LCD-... all the basic work has been laid out there. Most text of this instructable is taken from Fritter. This variation was designed to work with Mac OSX. This version includes the following corrections and new functions:

- Enabled for multiple media sources

- Only notifies and displays when sources are updated

- Includes LED and Servo analog signals

- Fixed issues with Python 3.x libraries and Pyserial functionality

- Fixed issues with Arduino code and LCD library

Step 1: Required Parts

All parts used are included in the basic Arduino starter kit.
  1. Arduino board
  2. Breadboard
  3. LED
  4. Servo (basic servo used here: SM-S2309S)
  5. (>12) Breadboard cables
  6. 16x2 Character LCD display, compatible with the LiquidCrystal library (works with larger LCD's with tweaking)
  7. Potentiometer, preferably 10K ohms.
  8. USB to USB-B cable (standard USB-to-Arduino cable)

Step 2: Wiring

The most basic setup for this to work is shown in the schematic below. If uncertain, start out with this wiring and get it to work. Then add LED and Servo after. When in demand, I'll make a schematic for the setup as shown in the picture.

The LCD should be wired up as is shown in this picture (given it's a 16x2 LCD that uses the HD44780 driver). Potentiometer controls the contrast. It should also be noted that most LCD's use pins 15 and 16 on the LCD as the +5v and GND for the backlight.Picture is from http://arduino.cc/en/Tutorial/LiquidCrystal. Make sure you test it using the "Hello World!" program described. The screen may need to have the contrast turned all the way up for it to display properly.The LED just goes in digital pin 13 and the GND pin next to it. Make sure the polarity is correct (Longer leg should be the + leg, short legs goes to ground).

Step 3: Software and Libraries

2 pieces of software and 2 Libraries/Extensions are needed for this project to work. The first library is an Arduino Library called LiquidCrystal440. It is available here: http://code.google.com/p/liquidcrystal440/. It is an updated version of the LiquidCrystal library, and helps deal with some issues when it comes to addressing memory that isn't currently visible on the screen.

Obviously to use the LiquidCrystal440 Library, you will need the first piece of software: The Arduino coding interface, which I assume all Arduino users have (if not, just check the Arduino.cc website)

The second piece of software you will need is Python. Python is an easy to learn programming language for the PC, Linux, or Mac. It is available for free here: http://www.python.org/.

The final thing you need is the extension that will let the Python computer program work with the Arduino itself, via the serial cable. The required extension is Pyserial, available here: http://pyserial.sourceforge.net/.

This setup is designed to work with Python 3.1 and later, with Pyserial 2.7.

Step 4: Arduino Code

// This code is for the Arduino RSS feed project, by Fritter

// It was updated and expanded by Sander van Haperen, August 2014. // Read the comment lines to figure out how it works

int startstring = 0; // recognition of beginning of new string int charcount = 0; // keeps track of total chars on screen

#include Servo myservo; // create servo object to control a servo // a maximum of eight servo objects can be created

#include // import the LiquidCrystal Library LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() { Serial.begin(9600); // opens serial port, sets data rate to 9600 bps lcd.begin(16,2); // Initialize the LCD size 16x2. Change if using a larger LCD lcd.setCursor(0,0); // Set cursor position to top left corner pinMode(13, OUTPUT); myservo.attach(9); // attaches the servo on pin 9 to the servo object }

void loop() { char incomingByte = 0; // for incoming serial data if (Serial.available() > 0) { // Check for incoming Serial Data int pos = 0; // variable to store the servo position myservo.write(pos); // tell servo to go to position in variable 'pos' digitalWrite(13, HIGH); incomingByte = Serial.read(); if ((incomingByte == '~') && (startstring == 1)){ // Check for the closing '~' to end the printing of serial data startstring = 0; // Set the printing to off delay(5000); // Wait 5 seconds lcd.clear(); // Wipe the screen charcount = 0; // reset the character count to 0 lcd.setCursor(0,0); // reset the cursor to 0,0 } if (startstring == 1){ // check if the string has begun if first '~' has been read if (charcount <= 30){ // check if charcount is under or equal to 30 lcd.print(incomingByte); // Print the current byte in the serial charcount = charcount++; // Increment the charcount by 1 yes I know it's awkward } } if (charcount == 31){ // if the charcount is equal to 31 aka the screen is full delay(500); lcd.clear(); // clear the screen lcd.setCursor(0,0); // set cursor to 0,0 lcd.print(incomingByte); // continue printing data charcount = 1; // set charcount back to 1 } if (incomingByte == '~'){ // Check if byte is marker ~ to start the printing startstring = 1; // start printing } } digitalWrite(13, LOW); int pos = 90; // variable to store the servo position myservo.write(pos); // tell servo to go to position in variable 'pos' delay(10); // 10ms delay for stability }

Step 5: Python Code

#import library to do http requests:

import urllib.request #import pyserial Library import serial #import time library for delays import time

#import xml parser called minidom: from xml.dom.minidom import parseString

datamem = "0" datamem2 = "0"

#Initialize the Serial connection in COM3 or whatever port your arduino uses at 9600 baud rate ser = serial.Serial("/dev/tty.usbmodem1411", 9600)

i = 1 #delay for stability while connection is achieved time.sleep(5) while i == 1: #download the rss file feel free to put your own rss url in here file = urllib.request.urlopen('http://www.nu.nl/feeds/rss/algemeen.rss') #convert to string data = file.read() #close the file file.close()

#parse the xml from the string dom = parseString(data)

#retrieve the first xml tag (data) that the parser finds with name tagName change tags to get different data xmlTag = dom.getElementsByTagName('title')[1].toxml() # the [2] indicates the 3rd title tag it finds will be parsed, counting starts at 0

if xmlTag != datamem:

#strip off the tag (data ---> data) xmlData=xmlTag.replace('

','') #write the marker ~ to serial ser.write(b"~") time.sleep(5) #split the string into individual words nums = xmlData.split(' ') #loop until all words in string have been printed for num in nums: #write 1 word ser.write(bytes(num, 'UTF-8'))

# write 1 space ser.write(bytes(' ', 'UTF-8'))

# THE DELAY IS NECESSARY. It prevents overflow of the arduino buffer. time.sleep(2) # write ~ to close the string and tell arduino information sending is finished ser.write(b"~") # wait 5 minutes before rechecking RSS and resending data to Arduino

datamem = xmlTag time.sleep(30) else: time.sleep(60)

#download the rss file feel free to put your own rss url in here file2 = urllib.request.urlopen('https://www.facebook.com/feeds/notifications.php?id=someidhere&viewer=someviewer&key=somekeyhere&format=rss20') #convert to string data2 = file2.read() #close the file file2.close()

#parse the xml from the string dom2 = parseString(data2)

#retrieve the first xml tag (data) that the parser finds with name tagName change tags to get different data xmlTag2 = dom2.getElementsByTagName('title')[1].toxml() # the [2] indicates the 3rd title tag it finds will be parsed, counting starts at 0

if xmlTag2 != datamem2:

#strip off the tag (data ---> data) xmlData2=xmlTag2.replace('

','') #write the marker ~ to serial ser.write(b"~") time.sleep(5) #split the string into individual words nums = xmlData2.split(' ') #loop until all words in string have been printed for num in nums: #write 1 word ser.write(bytes(num, 'UTF-8'))

# write 1 space ser.write(bytes(' ', 'UTF-8'))

# THE DELAY IS NECESSARY. It prevents overflow of the arduino buffer. time.sleep(2) # write ~ to close the string and tell arduino information sending is finished ser.write(b"~") # wait 5 minutes before rechecking RSS and resending data to Arduino

datamem2 = xmlTag2 time.sleep(120) else: time.sleep(60)

Step 6: Getting It to Work

Upload the Arduino Code to the Arduino itself. Put the Python code into a .py file. If all goes according to plan, if you run the .py file, you should see the text start appearing after about 10 seconds. Every time a word is outputted, the LED should flash and the servo moves as well.

If it doesn't work:

Check the port in the python file. Your Arduino may be labeled differently or be numbered differently.

Check that the RSS feed doesn't have a ~ in the data. That will throw things out of whack.

Try running the .py file from the command line as an administrator. Sometimes the script doesn't have proper permissions to access the COM ports