Programmable VFD Display & Ticker

This is a project I’ve been working on for a while now, and it’s finally progressed to the point where I feel comfortable sharing it. The goal was to make a small programmable display so I can quickly check the current Bitcoin or Dogecoin price, see the time, weather, etc as I walk into my room. The display also had to look cool – I tried to make it steampunkish / hipster if you will. I am also contemplating the marketability of a reprogrammable display of this nature. If there is enough interest, I may improve it a bit (laser cut acrylic or wood base, etc…) and try to sell it. Price would likely be between 50$ & $100. Of course it would be open source so anyone could build their own or or modify to their liking.

The whole thing is really just a large VFD (Vacuum Fluorescent Display) and a Raspberry Pi, both of which I mounted to a bent metal plate as a stand. There is also a PIR motion sensor which I have setup to put the display to sleep after a set amount of time with no motion in the room. There are green LEDs between the metal plate and the back of the VFD to create a green glow around the edge. The Raspberry Pi is running it’s default debian distro (Raspbian?) and auto connects to wifi on boot, and a Python script controls the VFD through the Raspberry Pi’s serial port.

20140415_144135

This project all started when I purchased a large VFD (Vacuum Fluorescent Display) from a surplus electronics store (Skycraft – greatest surplus store in Orlando) a year or two ago. I found out this display actually accepts serial data. The connector was RS232 voltage level, but there was a MAX232 chip on the back converting the +-12v signal to TTL (+5v) for the onboard controller. I spliced into the 5 volt input to the controller chip and the display happily sprung to life as I sent it simple serial print commands from an Arduino.

To power the Raspberry Pi, I rigged up a LM7805 5v voltage regulator on the back of the metal plate. I’ll hopefully be replacing this with a 5v switching regulator though because the LM7805 heats up the whole metal plate. The PIR sensor is connected directly to one of the I/O pins on the Raspberry Pi, and it triggers an interrupt in the Python script when motion is detected. I may add a photoresistor so the display turns off after a certain amount of time without light (when I go to bed). The last major detail is a small transistor controlling the green leds…I can actually use the Raspberry Pi to PWM the leds to vary the green glow brightness, but this isn’t implemented yet.

More pics:

Here’s the Python Script:

I tried to comment as much as I could, but I’m not a good programmer. Let me know if you have questions about anything.

</span></pre>
#working programmable display code woohoo!

#!/usr/bin/python
import sys, serial, time, requests, json, glob
from time import sleep, strftime
from subprocess import *
from datetime import datetime
global serialport
import RPi.GPIO as GPIO

sensorPin = 7

GPIO.setmode(GPIO.BOARD) #I/O connector layout config
 #GPIO.setmode(GPIO.BCM)
GPIO.setup(sensorPin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

global timeTest #this is used for the interrupt
timeTest = 38 #display function takes 16 seconds to run so 38*16 = 608s or about 10m until display goes to sleep after motion stops.

LCD = serial.Serial('/dev/ttyAMA0',19200) #seup serial port
cmd = "ip addr show wlan0 | grep inet | awk '{print $2}' | cut -d/ -f1" #get IP address

def run_cmd(cmd): #get IP address fnc.
 p = Popen(cmd, shell=True, stdout=PIPE)
 output = p.communicate()[0]
 return output

#def getBitcoinPriceStr(): #Screw Mt. Gox
# URL = 'http://data.mtgox.com/api/2/BTCUSD/money/ticker_fast'
# r = requests.get(URL)
# priceStr = "$" + "{0:.2f}".format(float(json.loads(r.text)['data']['last']['value'])) + "/Doge"
# return priceStr

def getDogePriceStr():
 URL = 'http://api.vaultofsatoshi.com/public/recent_transactions?order_currency=doge&payment_currency=usd&count=1' #fetches data I want
 r = requests.get(URL)
 priceStr = "$" + "{0:.6f}".format(float(json.loads(r.text)['data'][0]['price']['value'])) + "/Doge" #uses json to parse text to find price value
 return priceStr

def getBitcoinPriceCampBX():
 URL = 'http://campbx.com/api/xticker.php'
 r = requests.get(URL)
 priceStr = "$" + "{0:.2f}".format(float(json.loads(r.text)['Last Trade'])) + "/BTC"
 return priceStr

def displayStuff():
 try:
 LCD.write('\x0E\x0C') #clears display
 ipaddr = run_cmd(cmd)
 LCD.write(datetime.now().strftime('%b %d %H:%M:%S\n'))
 #time.sleep(3)
 LCD.write('\x10\x0D') #2nd line on display
 LCD.write('IP %s' % ( ipaddr ))
 time.sleep(8) #pause 8 seconds

outStringDoge = getDogePriceStr()
 outStringCampBX = getBitcoinPriceCampBX()
 LCD.write('\x0E\x0C')
 LCD.write(outStringDoge + " VoS")
 LCD.write('\x0A\x0D')
 LCD.write(outStringCampBX + " CampBX")
 sleep(8)

except:
 print "Error"
 return

def resetTimeTest(self): #function called by interrupt in another thread (requires timeTest to be global to still use here?)
 global timeTest
 timeTest = 38
 #print "hello"
 return

LCD.open() #initialization stuff
LCD.write('\x0E\x0C') #clears display \x0C #LCD.write("whatever")
LCD.write("hello & welcome lostengineer")

GPIO.add_event_detect(sensorPin, GPIO.RISING, callback=resetTimeTest, bouncetime=40) #interrupt for PIR sensor

while 1:

 if(timeTest > 0):
 displayStuff() #display isn't asleep until time runs out. time is reset to 10m (38) or whatever by PIR sensor if motion is detected

else:
 LCD.write('\x0E\x0C')
 LCD.write("sleeping.....")

timeTest = timeTest - 1
 sleep(1) #this main loop runs on a 1s basis with displayStuff() taking 16s during every call.

LCD.close()


There are a couple other things you need to do to make everything work.

  1. Make Python executable with $ sudo chmod +x pythonscript.py
  2. Run script as root or it can’t access the serial port $ sudo ./pythonscript.py
  3. Disable boot crap output on serial port on startup
  4. Setup script to autorun on startup