Here's a Siemens DL2416 intelligent LED alphanumeric display being run by a Boarduino:
/* DL2416T intelligent 16-segment display test
version: 0.2
author: Alex Davis
hardware: Atmega168 or Atmega328 Arduino
Sends text to a directly-connected DL2416T 16-segment
four-character alphanumeric display.
There are probably enough pins to do four displays
without external logic. As is the code does just one.
If you debug using Serial you will set d0 high and throw off every other character.
*/
#include <avr/pgmspace.h>
// strings to display stored in EEPROM
// don't put spaces at the start - the code assumes there won't be any
// do put a space on the end
prog_char string0[] PROGMEM = "SING WHILE YOU MAY ";
prog_char string1[] PROGMEM = "LIKE A FLY THAT'S TRAPPED ON A WINDOW ";
prog_char string2[] PROGMEM = "SING WHILE YOU MAY ";
prog_char string3[] PROGMEM = "THOUGH THERE'S NOTHING IN THE WORLD ";
prog_char string4[] PROGMEM = "THAT YOU CAN CHANGE ";
prog_char string5[] PROGMEM = "SING WHILE YOU MAY ";
prog_char string6[] PROGMEM = "'CAUSE IT MAY NOT BE VERY LONG ";
#define NUM_STRINGS 7
#define MAX_SIZE 81
// an array of strings
// if you change the number of strings above
// update this as well to match
PROGMEM const char *stringSet[] = {string0,
string1,
string2,
string3,
string4,
string5,
string6
};
// function prototypes
void formatStr(char []);
void displayChar(char, int, byte);
// set ports and pins
void setup()
{
byte pinLoop;
// set port d to all outputs, except serial in
// then set them low
DDRD = B11111110;
PORTD = B00000000;
// set pins 8-16 to outputs
for (pinLoop = 8; pinLoop < 17; pinLoop++) {
pinMode(pinLoop, OUTPUT);
}
// set the pin states
// use 8 for BL and set to HIGH
digitalWrite(8, HIGH);
// use 9 for AO and set to LOW
digitalWrite(9, LOW);
// use 10 for A1 and set to LOW
digitalWrite(10, LOW);
// if you tie C1 and C2 on each display
// then 11 can be for display0
// and 12 can be for display1
// use 11 for C1 and set to HIGH
digitalWrite(11, HIGH);
// use 12 for C2 and set to HIGH
digitalWrite(12, HIGH);
// use 13 for CLR and set to HIGH
digitalWrite(13, HIGH);
// use 14 for CU and set to HIGH
digitalWrite(14, HIGH);
// use 15 for WR and set to HIGH
digitalWrite(15, HIGH);
// use 16 for CUE and set to LOW
digitalWrite(16, LOW);
}
// main
void loop()
{
byte i;
// buffer string stored in RAM
char currentString[MAX_SIZE];
for (i = 0; i < NUM_STRINGS; i++)
{
// copy a string from the array of strings in the EEPROM
// to a local buffer string in RAM
strcpy_P(currentString, (char*)pgm_read_word(&(stringSet[i])));
// parse the string for display
formatStr(currentString);
// pause a bit
delay(1000);
}
}
/* ------------------------------------------------------------
function formatStr
purpose: formats a string for display on a DL2416T
expects: a pointer to a string
returns: nothing
------------------------------------------------------------ */
void formatStr(char toDisplay[])
{
int wStart = 0, // start of word in string
wEnd = 0; // end of word in string
int count = 0, // string position counter
x = 0, // string position counter for word < 5
n = 0, // display counter for word > 5 mid-word
wordLen = 0, // length of string
d = 0, // display counter for word >5 end word
dLen = 0; // length - 1 for display purposes
byte displayNum = 0; // selects display 0 or 1
byte setChar;
int segCount = 0;
// loop until the end of the string
while (toDisplay[count] != '\0')
{
// assume string begins a word and not with a space
wStart = count;
wordLen = 0;
// find the length of the word until we reach a space
// or the end of the string
while ((toDisplay[count] != ' ') && (toDisplay[count] != '\0'))
{
// set the end to the current location
// when we drop out of the loop this will be
// the last character in the word
wEnd = count;
// move to the next position in the string
count++;
// increment the character count
wordLen++;
}
// display directly if it fits on the display
if (wordLen < 5)
{
// write the characters between wStart and wEnd directly
// to the display
// back through the buffer array and set one character
// on the display at a time
// blank the display
digitalWrite(8, LOW);
delay(1);
// go through the buffer array backwards and write the
// characters to the display
segCount = 0;
for (n = wEnd; n > (wStart - 1); n--)
{
// send the character, display position and display
displayChar(toDisplay[n], segCount, displayNum);
segCount++;
}
// unblank the display
digitalWrite(8, HIGH);
// a pause to read the word
delay(750);
// clear the display
digitalWrite(13, LOW);
delay(2);
digitalWrite(13, HIGH);
}
// if it is more than four characters long
// display using the scrolling method
if (wordLen > 4)
{
dLen = wordLen - 1;
// write the characters between wStart and wEnd so they
// appear to scroll from left to right
// it takes length + 2 iterations to scroll
// all the way to the last character
// we will use x to keep track of where we are in the
// scrolling process
for (x = 0; x < (wordLen + 3); x++)
{
// clear the display
digitalWrite(13, LOW);
delay(2);
digitalWrite(13, HIGH);
// scroll until the fourth character in the word
// read the buffer backwards
if (x < 4) {
segCount = 0;
for (d = (wEnd - (dLen - x)); d > (wStart - 1) ; d--)
{
// send the character, display position and display
displayChar(toDisplay[d], segCount, displayNum);
segCount++;
}
}
// after the fourth character scroll on
// until the end of the word
if ((x > 3) && (x < wordLen))
{
segCount = 0;
for (d = wEnd - (dLen - x); d > ((wStart + (x - 3)) - 1); d--)
{
// send the character, display position and display
displayChar(toDisplay[d], segCount, displayNum);
segCount++;
}
}
// once we get to the end of the word
// scroll off by reading forwards in the array
// while counting backwards in the display position
if (x > dLen)
{
segCount = 3;
for (d = (wStart + (x - 3)); d < (wEnd + 1); d++)
{
// send the character, display position and display
displayChar(toDisplay[d], segCount, displayNum);
segCount--;
}
}
// a small delay between scroll
delay(200);
}
// clear the display
digitalWrite(13, LOW);
delay(2);
digitalWrite(13, HIGH);
}
count++;
}
} // end function formatStr
/* ------------------------------------------------------------
function displayChar
purpose: displays a character on a DL2416T
expects: a character, a position and a display (0,1,2 etc...)
returns: nothing
------------------------------------------------------------ */
void displayChar(char myChar, int myPos, byte myDisp)
{
/* here's how to set a character:
1. select an address using a0-a1 which here are arduino pins 9-10
2. pull WR to LOW to enable loading
3. send the bit-shifted character to the data lines d0-d6 all at once using PORTD
4. set the WR pin back to HIGH
5. repeat for next character
*/
// right now we only do one display
// but logic for more would be added here
// using a case if more than one were used
if (myDisp == 0)
{
// enable display 0 by setting C1-C2 LOW
digitalWrite(11, LOW);
// disable display 1 by setting C1-C2 HIGH
digitalWrite(12, HIGH);
delay(2);
}
// we are going to set the ASCII character all at once on PORTD
// but we must avoid pin 0, which is serial RX
// so we will shift one bit to the left
myChar = myChar << 1;
// the segment position is the opposite of the array
// eg. seg0 is array[3]
// set the character pin state
// cheap binary conversion of setChar
switch (myPos)
{
case 0:
digitalWrite(9, LOW);
digitalWrite(10, LOW);
break;
case 1:
digitalWrite(9, HIGH);
digitalWrite(10, LOW);
break;
case 2:
digitalWrite(9, LOW);
digitalWrite(10, HIGH);
break;
case 3:
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
break;
}
// set the WR pin LOW to enable loading
digitalWrite(14, LOW);
delay(2);
// set the shifted character to PORTD
PORTD = myChar;
delay(2);
// set WR pin HIGH to finish loading
digitalWrite(14, HIGH);
delay(2);
} // end function displayChar