Introduction: 20 X 4 LCD News Rss Feed With Adruino/python

This is an updated version of this instructable : https://www.instructables.com/id/Wiring-up-the-LCD-... All the credits goes to the original author. A few key updated features for the new project and code:

  1. 20 x 4 LCD with I2C.
  2. Python 3 instead of 2
  3. Working news links
  4. Key input option added. Please note the python program need to be open in order to use the key input.

Thanks and enjoy.

Step 1: The Adruino Code: (this Needed to Be Started Before Python)

<p>// This code is for the Arduino RSS feed project, by Fritter<br>// Read the comment lines to figure out how it works
//I reedited the code for the 20 x 4 LCD I2C display by trial and error. it eventually worked. 
//A lot of patience for frustrations. Incremental changes to understant the behavior and logic or the code versus completely different approaches.
//need to use newsfeed.py, start adruino first.</p><p>// include the library code:. wire, LiquidCrystal. LiquidCrystal_I2C</p><p>#include <Wire.h>
</p><p>#include <LiquidCrystal.h></p><p>#include  <LiquidCrystal_I2C.h></p><p>
int startstring = 0;     // recognition of beginning of new string
int charcount = 0;     // keeps track of total chars on screen
       
LiquidCrystal_I2C lcd2(0x27,20,4);
// LiquidCrystal_I2C lcd(i2c_addr, en, rw, rs, d4, d5, d6, d7, BACKLIGHT_PIN, POSITIVE);
int CodeIn;// used on all serial reads
<br></p><p>void setup(){</p><p>lcd2.begin();
lcd2.clear();
lcd2.backlight();
lcd2.setCursor(0,0);
lcd2.print("TOP TEN NEWS");
delay(1000);
lcd2.clear();</p><p> Serial.begin(9600); 
}</p><p>void loop() {
        char incomingByte = 0;   // for incoming serial data
       
         if (Serial.available() > 0) {        // Check for incoming Serial Data
                 
                 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(4000);                                                                     // Wait 4 seconds for reader to read
                   lcd2.clear();                                                                         // Wipe the screen
                   charcount = 0;                                                                   // reset the character count to 0
                   lcd2.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 <= 129){ 
                     if (charcount == 20){
                     lcd2.setCursor(0,1);
                   }
                     if (charcount == 40){
                     lcd2.setCursor(0,2);
                   }
                     if (charcount == 60){
                     lcd2.setCursor(0,3);
                     }
                     if (charcount == 80){                                                       
                     delay(2500);
                     lcd2.clear();                                                                        // clear the screen
                     lcd2.setCursor(0,0);
                      charcount = 1;  
                     }
                     lcd2.print(incomingByte);                                                // Print the current byte in the serial
                     charcount = charcount++;                                             // Increment the charcount by 1 yes I know it's awkward
                     }
                 }
                                                                             // set cursor to 0,0
                                    // continue printing data
                                                                                   // set charcount back to 1
                                    
                 if (incomingByte == '~'){                                                    // Check if byte is marker ~ to start the printing
                  
                   startstring = 1;                                                                  // start printing
                 }
         }
                 
                 delay(10);                                                                            // 10ms delay for stability
             }</p>

Step 2: Python 3 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
#Initialize the Serial connection in COM3 or whatever port your arduino uses at 9600 baud rate
ser = serial.Serial("\\.\COM7", 9600)
i = 1
#delay for stability while connection is achieved
time.sleep(5)
while i == 1:
     newsSource = input("what News Source would you like to use? 1= Reuters; 2= BBC; 3 = Fox")
     #download the rss file feel free to put your own rss url in here
     if newsSource == '1':
          http = 'http://feeds.reuters.com/reuters/topNews'
          print ('1aaa')         
     elif newsSource == '2':
          http = 'http://feeds.bbci.co.uk/news/world/asia/rss.xml'
          print ('2bbb')
     elif newsSource == '3':
          http = 'http://feeds.foxnews.com/foxnews/latest'
          print ('3ccc')
     elif newsSource == '':
          time.sleep(30)
          http = 'http://feeds.foxnews.com/foxnews/latest'
     file = urllib.request.urlopen(http)
     #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')[2].toxml()
# the [2] indicates the 3rd title tag it finds will be parsed, counting starts at 0
#strip off the tag (data  --->   data)
xmlData=xmlTag.replace('
</p><p>','').replace('<!--[CDATA[','').replace(']]-->','')</p>
     ser.write(b'~')
#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(num.encode('UTF-8'))
# write 1 space
          ser.write(b' ')
# THE DELAY IS NECESSARY. It prevents overflow of the arduino buffer.
          time.sleep(1)
          xmlTag = dom.getElementsByTagName('title')[3].toxml()
     # the [2] indicates the 3rd title tag it finds will be parsed, counting starts at 0
     #strip off the tag (data  --->   data)
<br><p>xmlData=xmlTag.replace('</p>
<p>','').replace('<!--[CDATA[','').replace(']]-->
','')</p>
     xmlData=xmlTag.replace('
','').replace('','')
     #write the marker ~ to serial
     ser.write(b'~')
     #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(num.encode('UTF-8'))
          # write 1 space
          ser.write(b' ')
          # THE DELAY IS NECESSARY. It prevents overflow of the arduino buffer.
          time.sleep(1)
     xmlTag = dom.getElementsByTagName('title')[4].toxml()
     # the [2] indicates the 3rd title tag it finds will be parsed, counting starts at 0
     #strip off the tag (data  --->   data)
     xmlData=xmlTag.replace('
','').replace('
','')
     #write the marker ~ to serial
     ser.write(b'~')
     #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(num.encode('UTF-8'))
          # write 1 space
          ser.write(b' ')
          # THE DELAY IS NECESSARY. It prevents overflow of the arduino buffer.
          time.sleep(1)
     xmlTag = dom.getElementsByTagName('title')[5].toxml()
     # the [2] indicates the 3rd title tag it finds will be parsed, counting starts at 0
     #strip off the tag (data  --->   data)
     xmlData=xmlTag.replace('
','').replace('
','')
     #write the marker ~ to serial
     ser.write(b'~')
     #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(num.encode('UTF-8'))
          # write 1 space
          ser.write(b' ')
          # THE DELAY IS NECESSARY. It prevents overflow of the arduino buffer.
          time.sleep(1)
     xmlTag = dom.getElementsByTagName('title')[6].toxml()
     # the [2] indicates the 3rd title tag it finds will be parsed, counting starts at 0
     #strip off the tag (data  --->   data)
  xmlData=xmlTag.replace('
','').replace('
','')
     #write the marker ~ to serial
     ser.write(b'~')
     #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(num.encode('UTF-8'))
          # write 1 space
          ser.write(b' ')
          # THE DELAY IS NECESSARY. It prevents overflow of the arduino buffer.
          time.sleep(1)
     xmlTag = dom.getElementsByTagName('title')[7].toxml()
     # the [2] indicates the 3rd title tag it finds will be parsed, counting starts at 0
     #strip off the tag (data  --->   data)
     xmlData=xmlTag.replace('
','').replace('
','')
     #write the marker ~ to serial
     ser.write(b'~')
     #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(num.encode('UTF-8'))
          # write 1 space
          ser.write(b' ')
          # THE DELAY IS NECESSARY. It prevents overflow of the arduino buffer.
          time.sleep(1)
     xmlTag = dom.getElementsByTagName('title')[8].toxml()
     # the [2] indicates the 3rd title tag it finds will be parsed, counting starts at 0
     #strip off the tag (data  --->   data)
     xmlData=xmlTag.replace('
','').replace('','')
     #write the marker ~ to serial
     ser.write(b'~')
     #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(num.encode('UTF-8'))
          # write 1 space
          ser.write(b' ')
          # THE DELAY IS NECESSARY. It prevents overflow of the arduino buffer.
          time.sleep(1)
     xmlTag = dom.getElementsByTagName('title')[9].toxml()
     # the [2] indicates the 3rd title tag it finds will be parsed, counting starts at 0
     #strip off the tag (data  --->   data)
     xmlData=xmlTag.replace('
','').replace('
','')
     #write the marker ~ to serial
     ser.write(b'~')
     #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(num.encode('UTF-8'))
          # write 1 space
          ser.write(b' ')
          # THE DELAY IS NECESSARY. It prevents overflow of the arduino buffer.
          time.sleep(1)
     xmlTag = dom.getElementsByTagName('title')[10].toxml()
     # the [2] indicates the 3rd title tag it finds will be parsed, counting starts at 0
     #strip off the tag (data  --->   data)
     xmlData=xmlTag.replace('
','').replace('
','')
     #write the marker ~ to serial
     ser.write(b'~')
     #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(num.encode('UTF-8'))
          # write 1 space
          ser.write(b' ')
          # THE DELAY IS NECESSARY. It prevents overflow of the arduino buffer.
          time.sleep(1)
     xmlTag = dom.getElementsByTagName('title')[11].toxml()
     # the [2] indicates the 3rd title tag it finds will be parsed, counting starts at 0
     #strip off the tag (data  --->   data)
     xmlData=xmlTag.replace('
','').replace('
','')
     #write the marker ~ to serial
     ser.write(b'~')
     #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(num.encode('UTF-8'))
          # write 1 space
          ser.write(b' ')
          # THE DELAY IS NECESSARY. It prevents overflow of the arduino buffer.
          time.sleep(1)
# write ~ to close the string and tell arduino information sending is finished
     ser.write(b'~')
# wait 2 seconds before rechecking RSS and resending data to Arduino
     ser.write(b'~TOP TEN NEWS 1= Reuters; 2= BBC; 3 = Fox')
     time.sleep(2)