Project: SMS Text Scroller by follower
Display SMS text messages on a scrolling LED matrix
[ Hello MAKE readers! :) Do you want to learn electronics and craft? Make sure you check out my Bright Bunny project kit! ]
Source repository: https://github.com/follower/sms-text-scroller
15 May 2012¶
Started working on this yesterday.
The LED matrix display I'm working with is the Freetronics DMD.
Initially I was working with the Freetronics USBDroid but for the moment I've switched to an Arduino Mega ADK because I've run into a pin contention issue between the DMD and the USBDroid. The extra EEPROM/RAM might come in handy too... :)
16 May 2012¶
The pin contention issue is due to both the DMD and USB Host chip (MAX3421E) using Arduino digital pin 9.
When pin 9 is low the DMD doesn't display anything on the LEDs.
The USB Host chip (and shield) connects pin 9 to its output that indicates when an interrupt needs to be processed. Once a device is connected pin 9 spends most of its time low in this situation.
Thus, as soon you connect the USB device the display goes blank. Not very handy.
According to the USBDroid schematic it's possible to use Arduino digital pin 3 as an alternative connection for
USB_INTwith a solder jumper. I may look at doing that--although this will also require modifying the USB Host library. And I've got enough variations of that to keep track of as it is...According to the MAX3421E datasheet (page 5):
In edge mode, the logic level on INT is referenced to the voltage on VL and is a push-pull output with programmable polarity.
In level mode, INT is open-drain and active low.
Set the IE bit in the CPUCTL (R16) register to enable INT.I tried to disable the interrupt but it's actually used in the USB Host Shield library--which I'd thought it wasn't. For some reason I thought the library just polled the chip but apparently it doesn't.
Since I'm not a real EE (and can't really parse the sentence) I'm not sure if "edge mode" would allow us to fix the problem. (Oh, actually, looking at the additional explanation on page 17 it might actually help a bit--it seems it turns the interrupt into a pulse? So, in theory, you might be able to see if you can trigger a pin change interrupt on pin 9 but have the pulse be short enough that it doesn't screw with the DMD. This would require a modification of the USB Host Shield library though--it might be slightly "transparent" though. Either way, too much hassle, it seems...)
(Oh, and here's the MAX3421E Programming Guide.)
Anyway, as a result of all that I started working an Arduino Mega ADK board instead. This doesn't have the pin contention issue because it uses a non-broken out pin for INT instead of pin 9.
The downside is that the SPI pins are in a different location so you can't use the DMDCON connector board directly. You need to wire it up differently.
[TODO: Add wiring description. In the interim see this.]
I needed to make some modifications to the DMD library also, so first I forked it in the GitHub UI and then cloned it locally with:
hg clone git+ssh://git@github.com:follower/DMD.git(Oh, yeah, I'm using the
hg-gitMercurial plugin as per usual. :) )Then I linked it into the Arduino
librariesdirectory with:ln -s /<path>/DMDFirst change is to make the default "other" chip select pin (in order to avoid clashes) to a Mega appropriate value:
#define PIN_OTHER_SPI_nCS 53Even with the above change there was still major flickering, even if I modified how the sketch worked.
It turned out this mostly went away by increasing the speed of the SPI clock (which makes sense). Presumably this affects both the DMD speed and the USB host chip communication speed.
Fortunately I didn't need to figure that all by myself, I just cherry-picked the change from (1, 2):
SPI.setClockDivider(SPI_CLOCK_DIV2)Thanks
cjd!Created a new repository for the
sms-text-scrollerproject. Amazingly I didn't pick an awesome name like "cinnamon-scroll" for the project. Maybe later.
17 May 2012¶
Updated the sketch to scroll message & receive new message & then scroll it.
19 May 2012¶
The first version of the sketch worked with the original unmodified
android-background-service-usb-accessorybinary--since I had it installed on the phone.Once I had the code working I modified it to work with a new customised app
CinnamonScrollAppalthough the plan is to remove the need for a customised app by using Handbag but at present it doesn't have SMS receive capability.Oh, and I took the set up out for a trial run the other night and it (a) worked; and, (b) seemed to acquire some interest. :)
I also bodged together a connecting plate from a piece of wood (alas, no fancy 3d printing for me...) to join the two matrices together which isn't perfect (the first drilled hole is too wide) but does the job mostly.
I then use a Panavise Jr PCB holder to prop everything up.
[TODO: Add pictures.]
Uploaded the Android app to: http://rancidbacon.com/files/cinnamon-scroller/001/CinnamonScrollApp.apk
And the associated Arduino sketch hex file to: http://rancidbacon.com/files/cinnamon-scroller/001/CinnamonScroll.cpp.hex
21 May 2012¶
As an aside: while I was working on this the other day I encountered an error when I tried to build the newly imported Android project:
Error generating final archive: Debug Certificate expiredApparently this means it's my Android development birthday or something... :)
This is caused by the debug certificate being created with a lifetime of only one year. The solution is to delete the debug certificate to force a new one to be created. (I saw some comment that this means user data associated with the app won't be preserved but I haven't tested this.)
The location of the debug keystore is platform dependent:
Delete your debug certificate under
~/.android/debug.keystoreon Linux and Mac OS X;
the directory is something like%USERPROFILE%/.androidon Windows.Doing this on the command line from my home directory was enough for me on OS X:
rm .android/debug.keystoreThen you need to force a rebuild of the package--doing a
Run > Runfrom the menu should be enough.This was considered a bug (Issue: "Debug keystore should not expire or automatically be regenerated") and has apparently been fixed (Patch: "Make debug key expire in 30 years (instead of 1)") but I didn't check to see if this was the case with what I'm using. Guess I'll find out in a year or thirty.
I was working to get things working for the evening of Sat 19th (NZ time) but noticed an issue during the afternoon that stopped much in the way of new feature development.
At a certain point (I think it was when I increased the scroll delay from 10ms to 30ms) I realised there was a point at which the scroll resulted in a "shimmer" that soon made it painful to watch.
I managed to reduce the shimmer by adding this to
stepMarqueejust before the bits are moved:while(bDMDByte != 0);This causes the movement to wait until the beginning of the "frame".
But while this removes the shimmer, at certain speeds it makes it very obvious that the display is refreshed in 4 steps, as each step is offset by 1 LED (most noticable on an
lfor example):. . . . . . . .I played around with a bunch of solutions (including trying out the latest code from cjd) but as I hadn't fully grokked how things were working (and was feeling the time pressure :) ) it was a bit hit and miss.
In the end I tried to get some sort of double-buffering working but that didn't seem to have as much impact as I expect. In the end the combination of that code and increasing the rate at which the scan routine was called provided adequate results.
Originally the scan code was called every 5 milliseconds and I reduced the delay to 2.5 milliseconds. Any more frequent seemed to result in long SMS messages losing characters from them as they were read from the phone.
Once I had the the display working okay I added a couple of features:
-
One permanent message (hardcoded into the sketch) to display.
-
Four "slots" used to store the last four SMS messages received. When a new message is received the oldest message is overwritten. (The display order doesn't change however--i.e. the message in slot 1 is always displayed after the permanent message, even if it's not the most recent/oldest.)
And, then, I rushed to the venue location. :)
-
Overall the device was trouble-free on the night. Once things were connected it worked without needing to be fiddled with--which is a pretty good result.
These first two images show the display located on the speaker stack by the side of the stage. This provided good visibility--and to my relief the vibration of the speakers wasn't enough to walk the sign over the edge:
Here you can see the sign to the right of the stage--it was visible but without being in the main line of sight for people looking at the band onstage:
When the messages people texted were displayed they were preceeded with the last 3 digits of their phone number:
Incidentally, I greatly recommend having project demo photographs taken at a Latin dance evening--it makes them look a lot more interesting than the average. :)
[TODO: Insert construction pictures.]
People who used it seemed to like it but I did wonder if it was not totally obvious that you could actually text to the sign--and not have it cost you anything more than a normal text (which could be nothing for those on plans). (Also, thanks to incoming texts being free in NZ there was no need to do anything other than buy a SIM and chuck it in the phone.)
Then again maybe most people were too busy actually dancing. :)
We'll see what happens next time it gets an outing...
The code on my DMD@7a6cbfb1c2 and sms-text-scroller@c55eb16b97 repositories is what I used but I also used a version of
AndroidAccessorylibrary which is not currently public (and also modified to haveint read(void *buff, int len, unsigned int nakLimit = 1)) so I'm not sure how difficult it would be for people to get things running out of the box...But it will do for now. :)
14 June 2012¶
The project has made it onto the MAKE blog. w00t. :)
Added a little greeting and link to my Bright Bunny project kit in a shameless attempt to help pay the bills. :)
(Did I mention I'm available for freelance consulting..? :D)
Okay, shameless plugs over for now...
Helpfully the revised version of the
AndroidAccessorylibrary (now part of the renamedUsbHostlibrary--based on an enhanced version of theUSB_Host_shield1.x library) I refer to above is now available from the "Running Examples in Accessory Mode" documentation on the Arduino labs site.The direct link to the beta should be: http://labs.arduino.cc/uploads/ADK/GettingStarted/ArduinoADK-beta-001.zip
(It also includes tools for working with Processing but I don't use that here.)