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.
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.
- Make Python executable with $ sudo chmod +x pythonscript.py
- Run script as root or it can’t access the serial port $ sudo ./pythonscript.py
- Disable boot crap output on serial port on startup
- Setup script to autorun on startup