Introduction: Arduino LCD Twitter Display
a.k.a. the gratuitously complicated bidirectionally communicating Arduino-based scrolling Twitter display and notifier.
----
This project was mainly done as an excuse to learn how to use character LCD displays with my Arduino, and figure out how to make a bidirectional serial protocol. One major design goal was that the hardware would take user input and communicate back to the PC, not just run as a "dumb" display being driven entirely by the computer. This allows the Arduino to have a physical scrolling speed control which affects the script running on the PC.
Features:
- 16 x 2 character LCD displaying scrolling tweets from a chosen feed or search term
- Servo-operated flag raises when there are unread tweets (with no Arduino servo twitch!)
- Speed control dial adjusts scroll speed
- It's got Electrolytes
Step 1: System Architecture
A rather grandiose title that essentially means "breaking the design into parts", as this is quite a complex thing.
Hardware:
The hardware forms the Arduino's interface with the real world. The hardware consists of a two-line character LCD for displaying messages, a speed control that lets uers change the scrolling speed while the device is running, and a servo-operated flag that raises when the script detects there are unread tweets.
Firmware:
The sketch running on the Arduino runs a loop doing two main actions. It sends a "status" request to the script running on the server PC and awaits a response containing the number of tweets in the list, and whether there are any unread. It then sends a "message" request, gets the text of a tweet, and displays it scrolling across the display. It reads the potentiometer in real time to get the desired scroll speed, and raises and lowers the flag to notify of new tweets.
Software:
The server software maintains a list of all tweets seen since it started running. When the script receives a "status" request it replies with the number of tweets it currently has in the list, and whether there are any unread tweets. When it receives a "message" request the script sends the next tweet in the list, returning to the beginning of the list either when it reaches the end of the list or when it finds new tweets.
The script also has to keep the list of tweets up to date by checking the Twitter API to get the latest messages. This is also timed to occur at most once every three minutes: when the script receives a "status" request, if more than three minutes have elapsed since the last check, it gets the list of tweets and checks to see whether there are any unread.
Step 2: Hardware
Wiring instructions
Display:
For a serial 16x2 character LCD:
Pin 1. Ground
Pin 2. VCC (+5V)
Pin 3. Contrast
Pin 4. Register Select (RS)
Pin 5. Read/Write (R/W)
Pin 6. Clock
Pin 7. N/A
Pin 8. N/A
Pin 9. N/A
Pin 10. N/A
Pin 11. Bit 4
Pin 12. Bit 5
Pin 13. Bit 6
Pin 14. Bit 7
Pin 15. Backlight Anode (+)
Pin 16. Backlight Cathode (-)
You can find out more about those at the Wikipedia page about this series of character LCDs.
To wire the LCD to the Arduino, connect the following pin numbers on the LCD:
1: GND
2: +ve (+5V)
3: GND*
4: Arduino pin 12
5: GND+
6: Arduino pin 11
11, 12, 13, 14: Arduino 5, 4, 3, 2
*: Pin 3 should technically be connected to a 10K potentiometer between VCC and GND, however my display had a good contrast at the bottom of the potentiometer's range so I just tied the contrast line to ground. Also, I wanted the potentiometer for something else :)
+: Pin 5 switches the LCD between read and write mode, but we never need to read from the LCD so hold this to ground to keep the display in write mode.
Optional: speed control
Potentiometer GND: GND
Potentiometer VCC: VCC
Potentiometer wiper: Arduino analog in 0
Optional: "new tweet" flag
You will need a transistor and servo.
Transistor emitter: GND
Transistor base: Arduino pin 7
Transistor collector: servo GND
Servo VCC: VCC
Servo control: Arduino pin 9 (PWM)
If you want to use the servo, make sure you have your Arduino plugged into an external power supply (USB won't provide enough juice) and put the electrolytic capacitor across the power rails to provide spike current.
Step 3: Firmware
Initialise the LCD
Set up some constants used in the code
Print an initial message to the LCD
Set up the servo and lower the flag
Wait five seconds for the script to be started up on the server PC
Loop:
Request status from server and wait for response
If new tweets: raise the flag and display the number of tweets
else: lower the flag and display the search hashtag
Request next tweet from the server and wait for response
Clear the top row of the display
Display the tweet scrolling across the top row of the display at a speed determined by the speed control
A more complete "pseudocode" of the Arduino code:
Initialise LCD Set up constants Create buffer for incoming messages Set up the LCD as 16x2 characters, no autoscroll Display "Zeitgeistometer!\n (c) PKM 2010" on the display Set up the servo and its control pin Turn on the servo, move the servo to the "down" position and turn off again loop: Note the time when starting the loop Write "status\n" to the serial link Await a message on the serial link or for ten seconds to elapse If a new message arrived: Wait to receive entire message Read the message into a buffer Read the first char of the message If the first character is 'T' Set "new tweet" flag Active the servo, raise and deactivate Print the contents of the message to the bottom row of the display Else If the new tweet flag is set Clear the new tweet flag Active the servo, lower and deactivate print "#instructables" to the bottom row of the display Else Print "No status message" to the display Wait 0.5 seconds Write "tweet\n" to the serial link Await a message on the serial link or for eight seconds to elapse If a new message arrived: Wait to receive entire message Read the message into a buffer Set the current position to character 0 While the character 15 characters beyond the current position is not a null Read the speed control Map [0-1023] to a delay in the range [50-550]ms, wait for that interval Display the 16 characters from the current position on the top row of the LCD Increment the current position Else Print "No twit response" to the display Function clear_buffer: Write 150 null characters to the message buffer Function read_to_buffer: clear_buffer() while characters are available from the serial link read a character from Serial to the message buffer
I've attached the actual source code to this step as a text file, partly because it's messy and not very self-explanatory so not the best thing to read to get an idea of how the system works.
Attachments
Step 4: Software
Pseudocode:
Set up HTTP connection set up serial port Get the HTML of the list of tweets Extract the contents of the title tags and store in an array loop { await a serial message if "status" { if >3 minutes have elapsed since last request { reset twitter request timer get the HTML list of tweets for each tweet in the new list { if it is not the same as the first tweet on the current list, add it to the beginning of the list } } If there are new tweets write "T" and the number of new tweets else write "t" } if "tweet" { if there are new tweets { write the first tweet in the list } else { write the next tweet in the list, or return to the first if we have reached the end } } }Again, my source code is messy, questionably engineered and badly commented, so I've attached it as a text file. It won't run unless you install the appropriate libraries (LWP::UserAgent and Win32::SerialPort, I believe), and I can't even remember how I installed them. YMMV.
Attachments
Step 5: Watch It Go!
Video 2: The startup sequence with my comedy copyright/splash message, and a demo of the speed control. It will actually go faster than this video shows, but there's not much point as you can't read the message at top speed.
8 Comments
6 years ago
The perl code is outdated using an old Twitter API URL.
However, if you want to make it work for OSX you need to change these lines:
use Win32::SerialPort qw( :STAT 0.19 );
my $port = Win32::SerialPort->new('COM3');
if( ! defined($port) ) {
die("Can't open COM3: $^E\n");
}
# we have a serial port- initialise
$port->initialize();
INTO THESE LINES:
use Device::SerialPort qw( :PARAM :STAT 0.07 );
my $port = new Device::SerialPort("/dev/cu.usbmodem1421");
if( ! defined($port) ) {
die("Can't open COM1: $^E\n");
}
# we have a serial port- initialise
$port->start();
ALSO, you need to import the perl module Device SerialPort with the following command:
cpan Device::SerialPort
8 years ago on Introduction
I am a newbie at this!
I am using an Edison Board with integrated wifi. I pasted the arduino code to the IDE and edited it to work with the edison board.
I dont know what to do with the perl code
I already installed Strawberry Perl
Can you please tell me the next steps I should do.
I'm a 15 year old maker , so just getting started with integrating LCD and Twitter.
Thanks! :)
8 years ago on Introduction
Hi,
Nice tus, but you can put "on your PC" in the title because i've some step trouble with my Mac OS !
Perl is not easy on Mac OS for a newbies ;-)
Reply 8 years ago on Introduction
Instructions on how to install Perl on Mac OSX are here:
http://learn.perl.org/installing/osx.html
Using it from the command line ought to be pretty much the same deal (though I don't own a Mac so I can't back that up with personal experience).
Reply 8 years ago
Thank's a lot for your reply ;-)
I'm currently in the final step of the process. I've successfully install Perl and dependencies on my MacBook and it only remains to find how to transform the "Win32::SerialPort" in Mac version!
8 years ago on Introduction
Oh, i forget, and please, i'm a newbies, "what is your transistor value" !!!!?
I want make your tuts please !
Reply 8 years ago on Introduction
That is a very good question which I don't know the answer to. The transistor came in my Arduino experimenter's kit so I'm not sure what the part number is. The servo won't draw much current so the transistor only needs to be capable of switching 5V at about 250mA, so a generic BJT transistor like a 2N2222A would do. The transistor is actually unnecessary, the circuit works just fine without it- it's only there to stop the transistor "twitching" when it's not moving.
Reply 8 years ago on Introduction
That is a very good question which I don't know the answer to. The transistor came in my Arduino experimenter's kit so I'm not sure what the part number is. The servo won't draw much current so the transistor only needs to be capable of switching 5V at about 250mA, so a generic BJT transistor like a 2N2222A would do. The transistor is actually unnecessary, the circuit works just fine without it- it's only there to stop the transistor "twitching" when it's not moving.