OSRAM SLx-2016 on Arduino
The Osram SLx-2016 alphanumeric LED displays look great, they are quite easy to interface and, last but not least, quite expensive. I bought one to play with at Conrad some time ago. It was gathering dust for a while, but I stubled upon it again today and kludged together a small piece of Arduino code to talk to my nice and shiny green (SLG-2016) display.
I might use this later in a PID mod for my Rancilio Silvia espresso machine.
But for now, here is the code. Hope it is of use to someone:
/*
* SLx-2016 display interfacing test for the Arduino Diecimila
* Hessel Schut, hessel@isquared.nl
* version 0.32
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// address lines
int a0 = 3;
int a1 = 4;
// !wr (write, active low)
int _wr = 2;
int d7 = 5; // too few pins on port C. borrow another
void setup()
{
// define pin modes
pinMode(a0, OUTPUT);
pinMode(a1, OUTPUT);
pinMode(_wr, OUTPUT);
pinMode(d7, OUTPUT);
// port C (the Arduino analog pins) is used as data bus
// set data direction register of this port to output
DDRC |= B11111111;
// display string on init
char test[] = "init";
// flash init string
for (int i = 0; i <= 10; i++) {
clearDisplay();
delay(50);
for (int pos = 0; pos <= 3; pos++) {
writeDigit(3 - pos, test[pos]);
};
delay(50);
};
delay(1000);
// setup finished, jump to loop()
}
void clearDisplay() {
// The 2016 has a pin for this, but this is more economic on IO pins:
for (int pos = 0; pos <= 3; pos++) {
// write a bunch of spaces to the display
writeDigit(3 - pos, 0x20);
};
}
// write a character 'dchar' in position 'digit' on the display
void writeDigit(int digit, char dchar) {
// set address, the SLx-2016 defines address 0 as the rightmost digit
digitalWrite(a0, digit&1);
digitalWrite(a1, digit&2);
// initialize write cycle
digitalWrite(_wr, LOW);
// write character data
PORTC = dchar;
digitalWrite(d7, dchar & B01000000); // port C is 6 bits breed, ascii 7... ;)
// finish write cycle
digitalWrite(_wr, HIGH);
}
// write ascii text to the display
void print_slx2016(char mesg_string[]) {
// initialize display buff
char disp[5] = " ";
clearDisplay();
if (strlen(mesg_string) > 4) {
// scroll through the message
for (int pos = 0; pos < strlen(mesg_string); pos++) {
writeDigit(0, mesg_string[pos]);
for (int offset = 1; offset <= 3; offset++) {
if (pos > (offset - 1)) {
writeDigit(offset, mesg_string[pos - offset]);
};
};
delay(200);
};
}
else {
// string fits on display, no scrolling
// assign mesg_str to blank display buffer
for (int i = 0; i <= strlen(mesg_string) - 1; i++) {
disp[i] = mesg_string[i];
};
// write display buffer to display
for (int pos = 0; pos <= 3; pos++) {
writeDigit(3 - pos, disp[pos]);
};
};
}
// int to ascii string ('borrowed' from http://www.jb.man.ac.uk/~slowe/cpp/itoa.html)
char* itoa(int val, int base){
static char buf[32] = {
0 };
int i = 30;
for(; val && i ; --i, val /= base)
buf[i] = "0123456789abcdef"[val % base];
return &buf[i+1];
}
// get length of string (iterate until nul terminator)
int strlen(char *str) {
char *i;
for (i=str; *i; i++);
return i-str;
}
void loop() {
print_slx2016("Hello, world!");
delay(500);
for (int n = 0; n <=9999; n++) {
print_slx2016(itoa(n, 10));
delay(15);
};
delay(500);
}
isquared.nl rss (atom)