I built a giant red/blue bar graph to display the electoral vote at my house tonight. It uses 32 ShiftBrite RGB LED modules, two CSG-4M LED numerical displays, a Cubloc CB405 with Quick Start 1000 board, and an ACODE-300B Bluetooth module. I used Eric's code from Hackaday last night to scrape CNN's election results. The code runs on a small 400MHz Linux server I always have running for file storage and random scripting.
Here's how I did it:
I started with the above parts already listed. In addition, there's a carrier board for setting up the ACODE Bluetooth module, an LM1086 3.3 volt regulator for powering the ACODE module later, and a cheap (~$5) Bluetooth USB dongle from DealExtreme.
First, I wanted to make sure the Bluetooth dongle would work from Linux. I've had really good results with these before, Linux seems to pick up all the common chipsets immediately. I plugged it into the old Linux server running in the lab at my house, and checked the results with dmesg:
Lookin' good! Next, let's try to get the Linux computer talking to the ACODE module over Bluetooth. First, I plugged the ACODE module into a USB-RS232 converter and power.
Next, I connected to the USB-RS232 converter at 9600bps on COM4 using PuTTY:
And held the reset button on the ACODE carrier board until the serial configuration terminal appeared:
You can select menu items by typing the letter and pressing Enter. I changed the name to "Election", left authentication off, changed the connection mode to "MODE2" which automatically reconnects to the last connected device. I also disabled the status message since I didn't want to have non-data text coming into the Cubloc serial port. I made sure the role was "SLAVE" since I planned to use the Linux server as the master device. I turned the power to the ACODE on and off, and it's ready to go!
Back in my SSH session to the Linux server, I scanned for the ACODE module with "hcitool scan":
There it is! I also copied the device address since it's required later.
Next, I made sure the Bluetooth serial port service was available with "sdptool search SP":
And everything still looks good. I noted that my RFCOMM service was on Channel 1, this is generally true for a single function device like the ACODE-300, but it may be different on other Bluetooth devices.
To map the remote Bluetooth serial port to a local serial port, I used "rfcomm bind 0 00:06:6E:11:B7:36":
I tested the connection by echoing some text to /dev/rfcomm0, and it appeared in my local serial connection to COM4, from the ACODE-300 Bluetooth serial port.
So I wouldn't have to issue the rfcomm command manually again, I added the following configuration in /etc/bluetooth/rfcomm.conf:
So I've definitely got a wireless link going! I can treate /dev/rfcomm0 as a normal serial port. This will make it easy to communicate from Python later.
First, I've got to get some hardware together. I used the CB405 and Quick Start 1000 board, and added the ACODE-300 module to the breadboard area. The ACODE module needs 3.3 volts, so I used an LM1086 regulator. It's not picky about logic levels, so I was able to run those directly into the TTL serial ports for Channel 1 on the CB405. I also added a 10K pullup resistor on the ACODE Reset line, and a 100 ohm resistor and LED for the status indicator. This will blink at first, but will stay on when a connection is active.
Next, I added connections for a ShiftBrite chain, hooked up the CSG-4M displays, and used some old code to test the ShiftBrites and displays. I lined up 32 ShiftBrites on a piece of 3/4x3/4 hardwood, fastened with zip ties, and chained with the 3.5" cables from my store.
Before writing the Cubloc code, I wanted to get Eric's CNN scraper sending data to the serial port. Here's what I ended up using:
Here's how I did it:
I started with the above parts already listed. In addition, there's a carrier board for setting up the ACODE Bluetooth module, an LM1086 3.3 volt regulator for powering the ACODE module later, and a cheap (~$5) Bluetooth USB dongle from DealExtreme.
First, I wanted to make sure the Bluetooth dongle would work from Linux. I've had really good results with these before, Linux seems to pick up all the common chipsets immediately. I plugged it into the old Linux server running in the lab at my house, and checked the results with dmesg:
Lookin' good! Next, let's try to get the Linux computer talking to the ACODE module over Bluetooth. First, I plugged the ACODE module into a USB-RS232 converter and power.
Next, I connected to the USB-RS232 converter at 9600bps on COM4 using PuTTY:
And held the reset button on the ACODE carrier board until the serial configuration terminal appeared:
You can select menu items by typing the letter and pressing Enter. I changed the name to "Election", left authentication off, changed the connection mode to "MODE2" which automatically reconnects to the last connected device. I also disabled the status message since I didn't want to have non-data text coming into the Cubloc serial port. I made sure the role was "SLAVE" since I planned to use the Linux server as the master device. I turned the power to the ACODE on and off, and it's ready to go!
Back in my SSH session to the Linux server, I scanned for the ACODE module with "hcitool scan":
There it is! I also copied the device address since it's required later.
Next, I made sure the Bluetooth serial port service was available with "sdptool search SP":
And everything still looks good. I noted that my RFCOMM service was on Channel 1, this is generally true for a single function device like the ACODE-300, but it may be different on other Bluetooth devices.
To map the remote Bluetooth serial port to a local serial port, I used "rfcomm bind 0 00:06:6E:11:B7:36":
I tested the connection by echoing some text to /dev/rfcomm0, and it appeared in my local serial connection to COM4, from the ACODE-300 Bluetooth serial port.
So I wouldn't have to issue the rfcomm command manually again, I added the following configuration in /etc/bluetooth/rfcomm.conf:
So I've definitely got a wireless link going! I can treate /dev/rfcomm0 as a normal serial port. This will make it easy to communicate from Python later.
First, I've got to get some hardware together. I used the CB405 and Quick Start 1000 board, and added the ACODE-300 module to the breadboard area. The ACODE module needs 3.3 volts, so I used an LM1086 regulator. It's not picky about logic levels, so I was able to run those directly into the TTL serial ports for Channel 1 on the CB405. I also added a 10K pullup resistor on the ACODE Reset line, and a 100 ohm resistor and LED for the status indicator. This will blink at first, but will stay on when a connection is active.
Next, I added connections for a ShiftBrite chain, hooked up the CSG-4M displays, and used some old code to test the ShiftBrites and displays. I lined up 32 ShiftBrites on a piece of 3/4x3/4 hardwood, fastened with zip ties, and chained with the 3.5" cables from my store.
Before writing the Cubloc code, I wanted to get Eric's CNN scraper sending data to the serial port. Here's what I ended up using:
import urllib2
import re
import serial
class ElectionWon(Exception):
pass
class CNN(object):
def __init__(self):
self.url = "http://www.cnn.com/ELECTION/2008/results/president/"
def get(self):
"""return the electoral balance
(dpopular, delectoral), (rpopular, relectoral)
"""
u = urllib2.urlopen(self.url)
for line in u.readlines():
res = re.search(r'var CNN_NData=(.*?);', line)
if res is not None:
data = res.group(1)
data = data.replace("true", "True")
data = data.replace("false", "False")
data = eval(data)
demp = None
deme = None
repp = None
repe = None
w = "N"
for candidate in data['P']['candidates']:
if candidate['party'] == 'D':
demp = candidate['votes']
deme = candidate['evotes']
if candidate['winner']:
w = 'D'
elif candidate['party'] == 'R':
repp = candidate['votes']
repe = candidate['evotes']
if candidate['winner']:
w = 'R'
return demp,deme,repp,repe,w
if __name__=='__main__':
cnn = CNN()
s=str(cnn.get()) + "\n"
ser = serial.Serial('/dev/rfcomm0', 9600, timeout=1)
ser.write(s)
ser.close()
Next, I needed to process the data coming from the Bluetooth connection. I used the Cubloc's serial routines to iterate through the received string and extract the numbers and winner data. Then, I calculated the position of the bar graph and sent the color commands out to the ShiftBrite array.Const Device = CB405
Ramclear
Opencom 1,9600,3,32,32
On Recv1 Gosub GetSerial
Set Until 1,32,10
Set I2c 45,44
#define CI 2
#define EI 3
#define LI 4
#define DI 5
Low CI
Low LI
Low DI
Low EI
#define Num_ShiftBrites 32
Dim CurrentRGB(Num_ShiftBrites,3) As Integer
Dim RecvString As String * 64
Dim Results(4) As Integer
Dim Winner As String * 1
Dim ElectoralPercentage As Long
Dim i As Byte
Dim j As Byte
Dim k As Integer
Dim n As Integer
Dim tempStr As String * 12
Dim BlinkVal As Integer
DrawShiftBrites
Do
Delay 250
If Winner = "D" Then
For n = 0 To Num_ShiftBrites
CurrentRGB(n,2) = BlinkVal
Next
Elseif Winner = "R" Then
For n = 0 To Num_ShiftBrites
CurrentRGB(n,0) = BlinkVal
Next
Else
CalcBarGraph
Endif
BlinkVal = 1023 * (BlinkVal = 0)
DrawShiftBrites
Csgdec 0,Results(3)
Csgdec 1,Results(1)
Loop
GetSerial:
RecvString = Getstr2(1,32,10)
Bclr 1,2
i = 1
For j = 0 To 3
tempStr = ""
Do While RecvString_A(i) <> 44
tempStr = tempStr + Chr(RecvString_A(i))
Incr i
Loop
Results(j) = Val(tempStr)
Incr i
Incr i
Next
Incr i
Winner = Chr(RecvString_A(i))
Return
End
Sub DrawShiftBrites()
For k = 1 To Num_ShiftBrites
Shiftout CI,DI,1,0b010001101111,12
Shiftout CI,DI,1,0b0001111111,10
Shiftout CI,DI,1,0b0001111111,10
Next
High LI
Low LI
For k = Num_ShiftBrites To 1 Step -1
Shiftout CI,DI,1,CurrentRGB(k-1,2),12
Shiftout CI,DI,1,CurrentRGB(k-1,0),10
Shiftout CI,DI,1,CurrentRGB(k-1,1),10
Next
High LI
Low LI
End Sub
Sub CalcBarGraph()
ElectoralPercentage = (1024*Results(1)/(Results(1)+Results(3)))*Num_ShiftBrites
If Results(1) = 0 And Results(3) = 0 Then ElectoralPercentage = 1024*32/2
For n = 0 To Num_ShiftBrites
If (ElectoralPercentage >= (n*1024) And ElectoralPercentage < (n*1024+1023)) Then
CurrentRGB(n,2) = ElectoralPercentage - (n*1024)
Elseif ElectoralPercentage > (n*1024) Then
CurrentRGB(n,2) = 1023
Else
CurrentRGB(n,2) = 0
Endif
CurrentRGB(n,0) = 1023 - CurrentRGB(n,2)
Next
End Sub
Finally, I fastened everything to a board. Looks pretty good!
Postar um comentário