Dec 23, 2014

Using LEDcontrol library for Embedded Labs 7-segment displays

Embedded Labs makes 4 and 8 digit seven-segment displays, controlled via SPI, and sold on Tindie for $12-13. Information about the devices and applications is at Embedded Labs displays

Perfect as counters or f.p. displays with number and decimal points accessible. Note that there are no colons for typical time display.

A library has been created [Eberhard Fahle] to place individual numbers or characters of its limited char set at a location. The demo code file is linked from the arduino site. The documentation was a bit hard to follow, and spread into pieces, and a different link gets to the example files. I've summarized below and added my own demo file.

The gist is the main program must separate the digits of the numbers to be displayed and send them out to a position. For example, to display 598, send a
numeral 8 to display position 0,
numeral 9 to position 1 and
numeral 5 to position 2.
For a negative number, send '-' to its respective location. Your program must control position, leading 0 blanking. etc.

You can use the setChar() or setNum() to set numbers.
To display -2.5, you would make three calls to print to positions 2, 1 & 0 respectively.

    className.setChar(SPIdeviceAddress, character position, value, decimal point)

  lc.setChar(SPIaddr, 2, '-', 0);
  lc.setChar(SPIaddr, 1, '2', 1); // decimal point ON
  lc.setChar(SPIaddr, 0, '5', 0);
 
I determined the values for each digit/character and placed them into a character array, then looped through it to update the display all at once.

   for (j=0; j<=6; j++) {
     // print the number from ascii characters placed into array c[]
     lc.setChar(addr,j,c[j],0);  // int addr, int digit, byte value, boolean dp);
   } 
 
 
 
A view of my test setup shows the Teensyduino 3.1 running the red display. Note that the USB is powering the Teensy, and an external 5V supply (from hardkernel/Ameridroid) is powering the display, with the grounds connected together.



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// ds_eight_7_segment 
// demo code to display numbers to eight 7-segment displays
// David Smith, based on libray demo example
//   library: LedControl.h         http://www.wayoda.org/arduino/ledcontrol/   author [Eberhard Fahle] 
//   displays: Embedded-Labs.com   http://embedded-lab.com/blog/?p=4935
//   available at Tindie in various colors  https://www.tindie.com/products/rajbex/spi7segdisp856-kit-eight-digit-serial-spi-seven-segment-led-display-blue/
// 2014-12-22 started
// 2014-12-23
// you can send as a number using setDigit or as a character using setChar. setDigit also accepts hex values a-f
// *some 4-digit display revisions have colons, some do not

/* other letters
 lc.setChar(0,0,'a',false); // a
 lc.setRow(0,0,0x05);       // r
 lc.setChar(0,0,'d',false); // d
 lc.setRow(0,0,0x1c);       // u
 lc.setRow(0,0,B00010000);  // i
 lc.setRow(0,0,0x15);       // n
 lc.setRow(0,0,0x1D);       // o
 */

#include "LedControl.h"

byte SPI_DAT = 12;  // connected to DIN (SPI data)
byte SPI_CLK = 11;  // connected to CLK (SPI clock)
byte SPI_CS  = 10;  // connected to LOAD (Select, active low)

LedControl lc = LedControl(SPI_DAT,SPI_CLK,SPI_CS, 1);  // Initiate class 
// (pins: Din, CLK, Load, number of displays on the SPI bus(1-8);  Note the pin order and names on the actual board

int SPIaddr = 0;  // SPI device address
long delaytime = 10;

void setup() {
  Serial.begin(9600); // add serial for diagnostics

  lc.shutdown(SPIaddr,false); // The MAX72XX is in power-saving mode on startup; do a wakeup call
  lc.setIntensity(SPIaddr,9);  // (0-15) // Set the brightness to a medium value (5 = ~50mA 15 = ~150mA (10mA per digit)
  lc.clearDisplay(SPIaddr);   // and clear the display 

  long t0 = millis();
  // while (!Serial ) {  // 
  while (!Serial && (millis() - t0 < 2000)) {  // or time out if Monitor is not opened
    ; // wait for serial port to connect. 
  }
}

// ----------------------------------------------------------------
void loop() { 
  static long i = -50;  // a place to start counting from
  printNumber(SPIaddr,i);
  Serial.println(i);
  i++ ;
  delay(delaytime);
}

// ----------------------------------------------------------------
void printNumber(int addr, long num) {
  char c[8];  // store values for each of the 8 characters
  int j;
  boolean negative_flag = false; 

  // error checking
  if(num >= 99999999) { // too big
    c[0] = 'E';
    lc.setChar(addr,0,c[0],0);
  }
  else if(num < - 9999999) { // too small
    c[0] = 'e';
    lc.setChar(addr,0,c[0],0);
  }
  else {
    if (num < 0) {
      negative_flag = true;
      num *= -1;  // convert to positive
    }

    for (j=0; j<=6; j++) {
      c[j] = num % 10; // get lowest digit by modulo division remainder
      num /= 10;  // next digit
      lc.setChar(addr,j,c[j],0); // int addr, int digit, byte value, boolean dp);
    }
    if(negative_flag) { //print a minus on the first MAX72XX, leftmost position 
      lc.setChar(addr,7,'-',0);  
    }
    else lc.setChar(addr,7,' ',0);  
  }
}

The code was syntax-colored and HTML-formatted using hilite.me site.