Pages: [1]   Go Down
Author Topic: 7-Segment Serial Display (4-digits)  (Read 867 times)
0 Members and 1 Guest are viewing this topic.
Greece
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi to everyone

I have a 4-digit 7-segment serial display connected to the arduino using SPI. The serial display is from Sparkfun. Item number COM-09230.
http://www.sparkfun.com/commerce/product_info.php?products_id=9230

I followed the instructions and the code found in this post and it worked great.
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1247533060


I have modified the code so as the arduino receives data from the computer and display the data on the serial display.
However, the problem is that went i sent numbers, for example 0, the display shows the number 48 which corresponds to 0 according to ASCII. When i send 1 the display shows 49 and so on.

The following part of the code passes the data from the computer over to the function to display the data onto the serial display.

Code:
if (Serial.available() > 0) {
    
   incomingByte = Serial.read();
   write_led(incomingByte,10,1);
  
  }

Also, if i put a number directly in the function (the first parameter, in this case the number 7), the serial display shows the correct number 7. As such, only when the numbers as sent over the serial port are not show up correctly.

Code:
write_led(7,10,1);


I have included the full code below if someone knows what the problem is.

John

Code:
// Send alphanumeric data to the Sparkfun Serial LED Display (COM-09230) using SPI
// Tested using Arduino Pro Mini w/ ATMega168 @ 5V
// July 21, 2009  - Quazar & Busaboi
// No guarantees expressed or implied just a good starting point
// Based upon the many SPI tutorials on Arduino.cc
//
// "num" specifies the number to display
// "base" specifies the base to use (2-16).
//    Use 2 for binary, 8 for octal, 10 for decimal, or 16 for hex
// "pad" indicates whether leading zeros should be replaced with spaces.
//    pad==0 means spaces ("   0"), pad==1 means zeros ("0000")
//
// Notes: The display's decimal/punctuation indicators are not changed.
// Numbers that don't fit into 4 digits show as " OF " for "Overflow".
// Assumptions: "unsigned short" is assumed to be at least 16b wide.

#define DATAOUT 11 //MOSI
#define DATAIN 12 //MISO - not used, but part of builtin SPI
#define SPICLOCK 13 //SCK
#define SLAVESELECT 10 //SS - CSN
byte incomingByte;

char spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
  return SPDR;                    // return the received byte
}

void setup()
{
  Serial.begin(9600);
  byte clr;
  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK, OUTPUT);
  pinMode(SLAVESELECT, OUTPUT);
  digitalWrite(SLAVESELECT, HIGH); //disable device
  // SPCR = 01010010
  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
  //sample on leading edge of clk,system clock/64
  SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1);
  clr=SPSR;
  clr=SPDR;
  delay(10);
  write_led_numbers(0x78,0x78,0x78,0x78); //Blank display
  write_led_decimals(0x00); // All decimal points off
}

void write_led_decimals(int value)
{
   digitalWrite(SLAVESELECT, LOW);
   delay(10);
   spi_transfer(0x77);     // Decimal Point OpCode
   spi_transfer(value);    // Decimal Point Values
   digitalWrite(SLAVESELECT, HIGH); //release chip, signal end transfer
}
void write_led_numbers(int digit1, int digit2, int digit3, int digit4)
{
   digitalWrite(SLAVESELECT, LOW);
   delay(10);
   spi_transfer(digit1);    // Thousands Digit
   spi_transfer(digit2);    // Hundreds Digit
   spi_transfer(digit3);    // Tens Digit
   spi_transfer(digit4);    // Ones Digit
   //spi_transfer(0x7A);    // Special command
   //spi_transfer(0x01);    // Special command
   digitalWrite(SLAVESELECT, HIGH); //release chip, signal end transfer
}
void write_led(unsigned short num, unsigned short base, unsigned short pad)
{
    unsigned short digit[4] = { 0, ' ', ' ', ' ' };
    unsigned short place = 0;

    if ( (base<2) || (base>16) || (num>(base*base*base*base-1)) ) {
        write_led_numbers(' ', 0x00, 0x0f, ' ');  // indicate overflow
    } else {
        while ( (num || pad) && (place<4) ) {
            if ( (num>0)  || pad )
                digit[place++] = num % base;
            num /= base;
        }
        write_led_numbers(digit[3], digit[2], digit[1], digit[0]);
    }
}

void loop()
{
 
  if (Serial.available() > 0) {
    
   incomingByte = Serial.read();
   write_led(incomingByte,10,1);
  
  }
 
 
 /*
 for (int i = 0; i < 9999; i++) {
     write_led(i,10,1);
     delay(80);
  }
 */

}
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 149
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

you have to convert the received digits (ASCII Code) to a byte,
simply change your code as follows:
Code:
if (Serial.available() > 0) {
    
   incomingByte = Serial.read();
   write_led(incomingByte-48,10,1);
  
  }

Mike
Logged

Greece
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Mike

It's ok now!

Thanks
Logged

Pages: [1]   Go Up
Jump to: