Just bought one of those small scrolling LED badges from Maplins for £20!
Up till 4 am reverse engineering the BADGE set up code included on the CD - so I could use it with a tomcat7 server on my Pi. Hopefully one of you out there - may find it useful!
import jssc.SerialNativeInterface ;
import jssc.SerialPortList;
import jssc.SerialPort ;
import jssc.SerialPortException;
import java.io.ByteArrayOutputStream ;
import java.io.IOException ;
//javac -cp jssc.jar LEDBadge.java
//java -cp jssc.jar:./ LEDBadge "TEST 1"
// Using JSSC Serial Port class
// Johnny Wilson, Brighton July 2014
public class LEDBadge {
static public int style = 0 ;
static public int speed = 0 ;
static public void log(String s) {
System.out.println("log : " + s) ;
}
public int unsignedint(byte b) {
return (b < 0 ? (int)b + 256 : (int)b);
}
// buildScrollingMessage - build byte array to send to our Maplin's LED Scrolling Badge
// @message 250 size max string -
// @style -1 is HOLD, 0 is SCROLL, 1 = STAR DROP, 2 = FLASH
// @speed 0 is fast , 4 is slow
byte [] buildScrollingMessage(String message, int style, int speed) throws IOException
{
int msgBlockSize = 0 ;
int sum = 0;
ByteArrayOutputStream ba = new ByteArrayOutputStream() ;
byte [] finalHeader = {(byte)0x02, 0x33, 0x01} ;
byte[] blockHeader = {0x02, 0x31, 0x06} ;
byte [] bmessage = message.substring(0,Math.min(250,message.length())).getBytes() ; // Just the 1st 250 characters will be used
int messageSize = bmessage.length ;
log("Messaage : " + message) ;
log("Message size of " + message.length() + " clipped to " + messageSize) ;
ba.write(0x00) ;
ba.write(blockHeader) ;
ba.write(0x00) ;
ba.write((-speed + 0x35)) ; // speed
ba.write(0x31) ; // Memory block
ba.write((style + 0x42)); // display style
ba.write(messageSize) ; // total size of message
// 1st Block of text
msgBlockSize = Math.min(messageSize,60) ;
sum = 0 ;
for (int i = 0 ; i < msgBlockSize ; i++) {
ba.write(bmessage[i]) ;
int val = unsignedint(bmessage[i]) ;
sum = sum + val ;
}
sum = sum + messageSize - 33 + style - speed ; // this is the check sum formula for scrolling messages at speed 5
// Write out remaining zeros
for(int i = 0 ; i < 60 - msgBlockSize ; i++) {
ba.write(0x00) ;
}
// 69th pos
ba.write(sum) ; // Save 1st Check Sum
// 2nd block
ba.write(blockHeader) ;
ba.write(0x40) ;
msgBlockSize = Math.max(0,Math.min((messageSize - 60),64)) ;
sum = 0 ;
for (int i = 0 ; i < msgBlockSize ; i++) {
ba.write(bmessage[i + 60]) ;
int val = unsignedint(bmessage[i + 60]) ;
sum = sum + val ;
}
sum = (sum + 0x77) ;
// Write out remaining zeros
for(int i = 0 ; i < 64 - msgBlockSize ; i++) {
ba.write(0x00) ;
}
// 138th Position
ba.write(sum) ; // Save 2nd Check Sum
// 3rd Block
ba.write(blockHeader) ;
ba.write(0x80) ;
msgBlockSize = Math.max(0,Math.min((messageSize - 60 - 64),64)) ; // I'll leave you to tidy these bits up -
sum = 0 ;
for (int i = 0 ; i < msgBlockSize ; i++) {
ba.write(bmessage[i + 60 + 64]) ;
int val = unsignedint(bmessage[i + 60 + 64]) ;
sum = sum + val ;
}
sum = sum + 0xb7;
// Write out remaining zeros
for(int i = 0 ; i < 64 - msgBlockSize ; i++) {
ba.write(0x00) ;
}
// 207th Position
ba.write(sum) ; // Save 3rd Check Sum
// final 4th block
ba.write(blockHeader) ;
ba.write(0xC0) ;
msgBlockSize = Math.max(0,Math.min((messageSize - 60 - 64 - 64),62)) ;
sum = 0 ;
for (int i = 0 ; i < msgBlockSize ; i++) {
ba.write(bmessage[i + 60 + 64 + 64]) ;
int val = unsignedint(bmessage[i + 60 + 64 + 64]) ;
sum = sum + val ;
}
sum = sum + 0xf7;
// Write out remaining zeros.
// Note although we only allow 250 chars in total [62 chars in final block]
//- we must write out 64 bytes for final block
for(int i = 0 ; i < 64 - msgBlockSize ; i++) {
ba.write(0x00) ;
}
// 276th position
ba.write(sum) ;
// Final few bytes
ba.write(finalHeader) ;
// final size of array should be 280 bytes!
//log("Size = " + ba.size()) ;
return ba.toByteArray() ;
}
static public void main(String [] args)
{
SerialNativeInterface sni = new SerialNativeInterface() ;
//log("SCROLLING MAPLIN LED BADGE") ;
//log("jssc Version " + sni.getLibraryVersion()) ;
String[] portNames = SerialPortList.getPortNames();
if (portNames.length == 0) {
log("No Serial Ports to print to!") ;
return ;
}
//log("Message " + args[0]) ;
for (String name : portNames) {
log("Port : " + name) ;
}
SerialPort serialPort = new SerialPort(portNames[0]); // FUDGE here - Assume we are using the 1st Serial Port in our list.
try {
serialPort.openPort();//Open serial port
serialPort.setParams(SerialPort.BAUDRATE_38400,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
LEDBadge badge = new LEDBadge() ;
// I have seen the serial writes fail on some occassions -
// My guess is that we are missing some kind of flow control
// from our set up - to tell the badge - that we are about to send.
// The failures are exacerbated when the BADGE is doing some more complicated
// display (style) format - such as the falling 'star drop'.
// Please drop me a line if you manage to make your serial sends - more robust.
// Thanks - Johnny, johnnyw66 at gmail dot com
serialPort.writeBytes(badge.buildScrollingMessage(args[0],LEDBadge.style,LEDBadge.speed));//Write data to port
serialPort.closePort();//Close serial port
}
catch (SerialPortException|IOException ex) {
System.out.println(ex);
}
}
}

No comments:
Post a Comment