Ethernet Twitter RSS to LCD

Hi all-

I recently decided to purchase an Ethernet Shield for my Arduino Uno R3. I'm still pretty new to this kind of thing, but I figured I'd try to make my a code that would allow me to display (on an LCD I took from an AlphaSmart 2000, part#M028C) whatever I posted on Twitter. The only code I could find was the Twitter2LCD. There were two big problems still, though. Some of the libraries were out of date, and Twitter no longer supported RSS feeds. I found a good tutorial on making an RSS feed for Twitter (http://www.labnol.org/internet/twitter-rss-feeds/27931/), so I made my own RSS feed. After I finished editing the code for my particular LCD, I got it to upload to my Arduino. But once plugged into the router, I got the message "Could not find item field". How would I go about resolving this? The code includes the link to the Twitter account's RSS feed. Anything helps, thanks!

/*
 * Twitter2LCD
// * gets xml data from https://script.google.com/macros/s/AKfycbz-MMUp0RmlMPAHn5jTA1ks--D-TduXHagIORr9f7IKzMlSvpA/exec?action=timeline&q=AaronDuino
 * reads the most recent tweet from field:  <title> 
 * writes the output to the LCD.
 
 The circuit:
 * LCD RS pin to digital pin A0
 * LCD Enable pin to digital pin 5
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 
 */


#include <Ethernet.h>
#include <SPI.h>
#include <TextFinder.h>
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(A0, 6, 5, 4, 3, 2);
LiquidCrystal lcd2(A0, 7, 5, 4, 3, 2);

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte server[] = {67,215,65,132}; //Google Scripts

char tweet[140];

EthernetClient client;

TextFinder  finder( client ); 

void setup()
{
  lcd.begin(40,2);
  lcd2.begin(40,2);
  lcd2.print("AlphaDuino (-)(+)");
  lcd.clear();
  lcd.print("Twitter2LCD");
  Serial.begin(9600);
  Ethernet.begin(mac);
}


void loop()
{
  lcd.clear();
  if (client.connect(server, 80)) {
    client.println("GET https://script.google.com/macros/s/AKfycbz-MMUp0RmlMPAHn5jTA1ks--D-TduXHagIORr9f7IKzMlSvpA/exec?action=timeline&q=AaronDuino");
  } 
  else {
    lcd.println("Connection failed");
    Serial.println("Connection failed");
  } 
  if (client.connected()) {
     // get the last tweet by simply parsing the item and title tags
     if((finder.find("<item>")&&(finder.getString("<title>","</title>",tweet,140)!=0)))
     {  
         Serial.println(tweet);
         
         for (int j=0; j<2; j++) {
           // first part of the tweet
           lcd.clear();
           lcd.setCursor(0,0);
           for (int i=0; i<20; i++)
             lcd.print(tweet[i]);
           lcd.setCursor(0,1);
           for (int i=20; i<40; i++)
             lcd.print(tweet[i]);
           lcd2.setCursor(0,0);
           for (int i=40; i<60; i++)
             lcd2.print(tweet[i]);
           lcd2.setCursor(0,1);
           for (int i=60; i<80; i++)
             lcd2.print(tweet[i]);
           delay(10000);
           // second part of the tweet
           lcd.clear();
           lcd.setCursor(0,0);
           for (int i=60; i<80; i++)
             lcd.print(tweet[i]);
           lcd.setCursor(0,1);
           for (int i=80; i<100; i++)
             lcd.print(tweet[i]);
           lcd2.setCursor(0,2);
           for (int i=100; i<120; i++)
             lcd2.print(tweet[i]);
           lcd2.setCursor(0,3);
           for (int i=120; i<140; i++)
             lcd2.print(tweet[i]);
           delay(10000);
           }
     } 
    else
      lcd.println("Could not find item field"); 
  }
  else {
    lcd.println("Disconnected"); 
  }
  client.stop();
  client.flush(); 
  delay(60000); // wait a minute before next update
}

-Aaron

Twitter2LCD.ino (2.88 KB)

Twitter requires SSL now, and the ethernet/wifi libraries do not support SSL. Read this thread.
http://forum.arduino.cc/index.php?topic=185323.0

SurferTim:
Twitter requires SSL now, and the ethernet/wifi libraries do not support SSL. Read this thread.
Twitter Request Error "HTTP/1.1 301 Moved Permanently" (Uno + Ethernet) - Programming Questions - Arduino Forum

So it won't allow me to read the RSS feed I made using Google Script?
https://script.google.com/macros/s/AKfycbz-MMUp0RmlMPAHn5jTA1ks--D-TduXHagIORr9f7IKzMlSvpA/exec?action=timeline&q=AaronDuino
I would think the server would be Google instead of Twitter, so I changed the server IP to that of https://script.google.com/macros/s/. It seems to be connecting alright, it just won't seem to pull my tweets from there (even though it is in XML format). I keep getting the error on my LCD of, "Could not find item field". Is it just a lost cause?

I would think the server would be Google instead of Twitter

Yes, but, it's the https protocol that is not supported on the Arduino.

Oh, gotcha. Thanks for clearing that up for me. So I assume there's no way to make Google revert back to non-secure, plain old http:// ?

Google uses a lot of different servers. It will depend on the server you get locally. If you get a message like this (could be a little different) when the Arduino tries to connect to a http (port 80 rather than 443) request, then you can't use port 80.

HTTP/1.1 301 Moved Permanently
date: Fri, 30 Aug 2013 03:01:12 UTC
location: https://www.google.com

Note the Moved Permanently is to a SSL (port 443 https) server location.

Alright, so I dug in a little further and here's what I've got now.

/*
 * Twitter2LCD
// * gets xml data from http://www.feedyes.com/feed.php?f=myQpZes4KbKhhOti
 * reads the most recent tweet from field:  <title> 
 * writes the output to the LCD.
 
 The circuit:
 * LCD RS pin to digital pin A0
 * LCD Enable pin to digital pin 5
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 
 */


#include <Ethernet.h>
#include <SPI.h>
#include <TextFinder.h>
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(A0, 6, 5, 4, 3, 2);
LiquidCrystal lcd2(A0, 7, 5, 4, 3, 2);

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte server[] = {67,215,65,132}; //Google Scripts

char tweet[140];

EthernetClient client;

TextFinder  finder( client ); 

void setup()
{
  lcd.begin(40,2);
  lcd2.begin(40,2);
  lcd2.clear();
  lcd2.print("AlphaDuino (-)(+)");
  lcd.clear();
  lcd.print("Twitter2LCD");
  Serial.begin(9600);
  Ethernet.begin(mac);
}


void loop()
{
  lcd.clear();
  if (client.connect(server, 80)) {
    client.println("GET http://www.feedyes.com/feed.php?f=myQpZes4KbKhhOti");
  } 
  else {
    lcd.println("Connection failed");
    Serial.println("Connection failed");
  } 
  if (client.connected()) {
     // get the last tweet by simply parsing the item and title tags
     if((finder.find("<item>")&&(finder.getString("<title>","</title>",tweet,140)!=0)))
     {  
         Serial.println(tweet);
         
         for (int j=0; j<2; j++) {
           // first part of the tweet
           lcd.clear();
           lcd.setCursor(0,0);
           for (int i=0; i<20; i++)
             lcd.print(tweet[i]);
           lcd.setCursor(0,1);
           for (int i=20; i<40; i++)
             lcd.print(tweet[i]);
           lcd2.setCursor(0,0);
           for (int i=40; i<60; i++)
             lcd2.print(tweet[i]);
           lcd2.setCursor(0,1);
           for (int i=60; i<80; i++)
             lcd2.print(tweet[i]);
           delay(10000);
           // second part of the tweet
           lcd.clear();
           lcd.setCursor(0,0);
           for (int i=60; i<80; i++)
             lcd.print(tweet[i]);
           lcd.setCursor(0,1);
           for (int i=80; i<100; i++)
             lcd.print(tweet[i]);
           lcd2.setCursor(0,2);
           for (int i=100; i<120; i++)
             lcd2.print(tweet[i]);
           lcd2.setCursor(0,3);
           for (int i=120; i<140; i++)
             lcd2.print(tweet[i]);
           delay(10000);
           }
     } 
    else
      lcd.println("Could not find item field"); 
  }
  else {
    lcd.println("Disconnected"); 
  }
  client.stop();
  client.flush(); 
  delay(60000); // wait a minute before next update
}

This particular RSS feed isn't SSL secured, so it should work with the current libraries, right? I adjusted the server IP to match this new feed. But still getting the 'Could not find field item' on my LCD. Could it be made to work?

This won't work. No protocol or blank line.

    client.println("GET http://www.feedyes.com/feed.php?f=myQpZes4KbKhhOti");

You need something like this.

    client.println("GET /feed.php?f=myQpZes4KbKhhOti HTTP/1.0");
    client.println("Host: www.feedeyes.com\r\nConnection: close\r\n");

SurferTim:
This won't work. No protocol or blank line.

    client.println("GET http://www.feedyes.com/feed.php?f=myQpZes4KbKhhOti");

You need something like this.

    client.println("GET /feed.php?f=myQpZes4KbKhhOti HTTP/1.0");

client.println("Host: www.feedeyes.com\r\nConnection: close\r\n");

Oh, that makes sense, thanks. But even when I added that in, it still couldn't find field item? Is it somehow in the wrong format for it to search through and pull anything between and and print it?

Then you should display what the server is returning. Try this to see if you are getting the correct page.

void loop() {
  lcd.clear();
  if (client.connect(server, 80)) {
    client.println("GET /feed.php?f=myQpZes4KbKhhOti HTTP/1.0");
    client.println("Host: www.feedyes.com\r\nConnection: close\r\n");

    while(client.connected()) {
       while(client.available()) {
            Serial.write(client.read());
        }
    }
    client.stop();
    Serial.println("disconnected");
  } 
  else {
    lcd.println("Connection failed");
    Serial.println("Connection failed");
  } 
  delay(60000); // wait a minute before next update
}

SurferTim:
Then you should display what the server is returning. Try this to see if you are getting the correct page.

void loop() {

lcd.clear();
 if (client.connect(server, 80)) {
   client.println("GET /feed.php?f=myQpZes4KbKhhOti HTTP/1.0");
   client.println("Host: www.feedyes.com\r\nConnection: close\r\n");

while(client.connected()) {
      while(client.available()) {
           Serial.write(client.read());
       }
   }
   client.stop();
   Serial.println("disconnected");
 }
 else {
   lcd.println("Connection failed");
   Serial.println("Connection failed");
 }
 delay(60000); // wait a minute before next update
}

Now nothing is showing up on my LCD, does that mean it's just not connecting to the site?

What is showing on your serial monitor? I don't think your LCD screen will display enough characters to troubleshoot this part.

Oh, wow. This was the first time I actually had it hooked up to a computer and used the serial monitor with it connected to ethernet (the computer I usually use is in another room from the router). So here's what I got on the Serial Moniter:

HTTn: close
Date: Mon, 06 Jan 2014 02:36:04 GMT
Server: OpenDNS Guide

disconnected
Zes4KbKhhOti
Content-Length: 0
Connection: close
Date: Mon, 06 Jan 2014 02:36:04 GMT
Server: OpenDNS Guide

disconnected
HTTP/1.0 303 See Other
Location: http://guidetest.a.id.opendns.com/?url=www.feedyes.com%2Ffeed.php%3Ff%3DmyQpZes4KbKhhOti
Content-Length: 0
Connection: close
Date: Mon, 06 Jan 2014 02:36:09 GMT
Server: OpenDNS Guide

So does this mean it's not connecting to the website? If that's the case, does that mean the website is the problem? Or I messed up in the code?

UPDATE:

I plugged in a different RSS feed (the CNN one for Technology), here's what the serial monitor returned:

H

400 - Bad Request

disconnected g="en"> 400 - Bad Request

400 - Bad Request

disconnected HTTP/1.0 400 Bad Request Content-Type: text/html Content-Length: 349 Connection: close Date: Mon, 06 Jan 2014 02:56:09 GMT Server: OpenDNS Guide <?xml version="1.0" encoding="iso-8859-1"?> 400 - Bad Request

400 - Bad Request

disconnected

I don't know about the message from OpenDNS.
The 303 message is normally a redirect to another server.
The Bad Request is a bad request format.

But none of those are the page you expected, are they? That is why you are not getting the response you expect from your code. You must work on getting the correct server and the request sent to that server.

This sounds awesome!!!

SurferTim:
This won't work. No protocol or blank line.

    client.println("GET http://www.feedyes.com/feed.php?f=myQpZes4KbKhhOti");

You need something like this.

    client.println("GET /feed.php?f=myQpZes4KbKhhOti HTTP/1.0");

client.println("Host: www.feedeyes.com\r\nConnection: close\r\n");

I guess I'm still not totally clear on what exactly the second line there is for. I'm not super familiar with a lot of this library and its functions. But I still want to learn it and figure this project out. So what should my next step be?