Go Down

Topic: 7 Segment Display using SPI (Read 22036 times) previous topic - next topic


I think it's better to have 4 digit Seg7 display circuit with OneWire interface. ;)


How to do with "OneWire" ? SPI needs 4 wires when you have 1 master and 1 slave..  


example code works for me! Now time to tweak...


SparkFun now offers an alternative design.  This one has the interface pins along the top, so you can horizontally stack displays.



Jul 23, 2010, 06:17 pm Last Edit: Jul 23, 2010, 07:52 pm by keebler71 Reason: 1
Stumbling upon this thread... here is my code for interfacing with the Sparkfun 4 digit, 7-segment LCD via SPI.  It demonstrates some of the various command bytes and wraps up most of the functionality into a single function call (once initialized).

I do have one bug yet to be worked out...  on initial reset the display usually reads fine, however upon a subsequent reset the display usually turns to "junk" (random elements lit).  Pressing the reset button again doesn't fix it but closing and reopening the Serial Monitor always does fix it.  I'm guessing it has something to do with the power up sequence of the LCD uC?  Any help with this would be greatly appreciated.  

Here is my code:

Code: [Select]
//this project demonstrates SPI control of sparkfun 4 digit, 7-segment LCD
//Setup section demonstrates commanding the LCD via SPI using byte commands.  
//Loop section demonstrates a counting timer uses SendToLCD() function to simplify
//project by Scott Josselyn
//note that there are different firmware versions for the sparkfun part that may not support all functions
//Part Product Page: http://www.sparkfun.com/commerce/product_info.php?products_id=9230
//Part Reference Manual:  http://www.sparkfun.com/datasheets/Components/LED/SFE-0012-DS-7segmentSerial-v3.pdf

#define MOSI        11     //SPI MOSI Pin definition - arduino pin 11
#define SCLK        13     //SPI CLOCK Pin definition - arduino pin 13
#define LCD_CS      10     //LCD chip select -arduino pin 10

char outBuff[5];  //output buffer
int lastOutToLCD, outToLCD = 0;
byte decimalBitCode = 0;

void setup() {
 //configure serial port
 //the following configures the lcd
 delay(200);  //not sure if this is required or not but want to make sure the LCD uC has finished loading after powerup
 //configure the pins for SPI communication
 pinMode(MOSI, OUTPUT);
 pinMode(SCLK, OUTPUT);
 pinMode(LCD_CS, OUTPUT);
 digitalWrite(LCD_CS, LOW); //this should be moved to inside the function

 /* Enable SPI, Master, set clock rate fck/128 */
 SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);  //SPE=enables SPI, MSTR=arduino is master, DORD=MSB first(default)
 //SPR0 =1, SPR1 =1 SPI2x = 0 => SCK Freq fosc/128
 //now reset the LCD and have it display "9999"
 SPI_MasterTransmit(0x76);  //send a reset
 delay(200);  //not sure if this helps or not
 SPI_MasterTransmit(9);  //send a 9
 SPI_MasterTransmit(9);  //send a 9
 SPI_MasterTransmit(9);  //send a 9
 SPI_MasterTransmit(9);  //send a 9
 SPI_MasterTransmit(0x77); //send decimal command byte
 SPI_MasterTransmit(0);   //clear all decimals
 Serial.println("LCD should show 9999");
 //now dim display
 Serial.println("Dimming Display...");
 SPI_MasterTransmit(0x7a);   //send brightness command byte
 SPI_MasterTransmit(0xfe);   //send min brightness value
 Serial.println("Brightening Display...");
 SPI_MasterTransmit(0x7a);   //send brightness command byte
 SPI_MasterTransmit(0x01);   //send max brightness value  
 for (byte i = 0;i<8; i++){
   decimalBitCode = 1 << i;
   SPI_MasterTransmit(0x77); //send decimal command byte
   SPI_MasterTransmit(decimalBitCode);   //update the decimal position
 delay(3000);  //delay 3 secs
 Serial.println("Now display a min:sec counter...");

void loop(){//begin loop
     int mins = millis()/60000;   //at some point need to add code to watch for wrap around at 99 min1!1 or whenever millis overflows
     long secs = (millis()/1000 % 60);
     outToLCD = mins*100 + secs;
     decimalBitCode = B00010000;  //code to enable the colon between hundreds and thousands place
     //now send it to the LCD (but only if display needs to be changed since last time)
     if (outToLCD != lastOutToLCD) {//begin check for new display data
       SendToLCD( outToLCD, decimalBitCode);
       //send to terminal for debugging
       Serial.print(mins, DEC); Serial.print(":"); Serial.println(secs, DEC);
     }; //end if check for new display data
     //update our variable that keeps track of what it was last time.
     lastOutToLCD = outToLCD;  

}//end loop

void SendToLCD( int n, byte decimalCode)
 //takes an unsigned int, converts to bcd and outputs the least 4 sig digits to the LCD and places
 //decimals on display are defined defined by decimalCode
 //digit1 - digit2 - digit3 - digit4
 //bit 0 = decimal between digit 1 and 2
 //bit 1 = decimal between digit 2 and 3
 //bit 2 = decimal between digit 3 and 4
 //bit 3 = top of colon
 //bit 4 = bottom of colon
 //bit 5 = above and right of digit 3

       //  Most of the following code section is from http://www.cs.uiowa.edu/~jones/bcd/decimal.html
       uint8_t d4, d3, d2, d1, d0, q = 0;

       if (n < 0) {
           putchar( '-' );
           n = -n;

       d1 = (n>>4)  & 0xF;
       d2 = (n>>8)  & 0xF;
       d3 = (n>>12) & 0xF;

       d0 = 6*(d3 + d2 + d1) + (n & 0xF);
       q = (d0 * 0xCD) >> 11;
       d0 = d0 - 10*q;

       d1 = q + 9*d3 + 5*d2 + d1;
       q = (d1 * 0xCD) >> 11;
       d1 = d1 - 10*q;

       d2 = q + 2*d2;
       q = (d2 * 0x1A) >> 8;
       d2 = d2 - 10*q;

       d3 = q + 4*d3;
       d4 = (d3 * 0x1A) >> 8;
       d3 = d3 - 10*d4;

     //Now send SPI bytes to LCD
     SPI_MasterTransmit(0x77);  //command byte for decimal
     SPI_MasterTransmit( decimalCode );  //now place decimal


void SPI_MasterTransmit(char cData)
 /* Start transmission */
 SPDR = cData;
 /* Wait for transmission complete */
 while(!(SPSR & (1<<SPIF)))


Is the SPI code that busaboi uploaded in the public domain?   I used it for an antenna rotor controller.  If I publish my code and include his, am I at risk?


Go Up