Pages: [1]   Go Down
Author Topic: 4 digit 7 segment display - first digit blinks  (Read 1319 times)
0 Members and 1 Guest are viewing this topic.
Los Angeles
Offline Offline
Newbie
*
Karma: 0
Posts: 22
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am using the 7 segment display i got from sparkfun to create an alarm clock. It works very well, however I have an issue with the first digit. When I want it to be blank (between 1 and 9 o'clock) i send it 0x78 and it causes the first digit to blink. If i send 0x78 to any of the other digits it clears them just fine. This is only an issue on the first digit. I have also tried using (0x7b)(0x00) and get the problem where it writes so that the numbers all shift one to the left because it is hoping to receive each of the 4 digits in order.

I realized i didn't explain the blink very well. By blink i mean that it cycles between being blank and showing 0. After it rolls over to 1 it continues to blink between 1 and blank.

Can anybody help me get past this glitch i have?

I am currently hardcoding the time in until my RTC gets here.

here is my code

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.
#include <Time.h>  
#include <Wire.h>  
#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t

#define DATAOUT 11 //MOSI
#define DATAIN 12 //MISO - not used, but part of builtin SPI
#define SPICLOCK 13 //sck
#define SLAVESELECT 10 //ss (CSN)
#define PHOTOCELL 0 //Photo Cell Analog Pin
#define LEDPIN 5 //LED PIN
int brightValue =0;
int brightMap = 0;

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);//remove
   setTime(4,18,00,14,8,2010); // another way to set the time
  byte clr;
  pinMode(DATAOUT, OUTPUT);
  //pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK, OUTPUT);
  pinMode(SLAVESELECT, OUTPUT);
  pinMode(LEDPIN, 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(0x18); // set decimals
}

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
   digitalWrite(SLAVESELECT, HIGH); //release chip, signal end transfer
}

void write_led(int hr, int mn)
{
  int digit[4];
  //hrs
  if(hr <= 9){
    digit[0] = 0x78;
    digit[1] = hr;
  }else{
    digit[0] = 1;
    digit[1] = hr - 10;
  }
  //mins
  if(mn<10){
    digit[2] = 0;
    digit[3] = mn;
  }else{
     digit[2] = mn/10;
     digit[3] = mn-(digit[2]*10);
  }

     write_led_numbers(digit[0], digit[1], digit[2], digit[3]);
    
}

void write_brightness(int value){
  brightMap = map(value, 35, 1024, 0,200);
  analogWrite(LEDPIN, brightMap);
  
  digitalWrite(SLAVESELECT, LOW);
  delay(10);
  spi_transfer(0x7a);     // Brightness OpCode
  spi_transfer(brightMap); // Brightness Values
  digitalWrite(SLAVESELECT, HIGH); //release chip, signal end transfer
}



void loop()
{
   if(isAM()){
     write_led_decimals(0x10); // :
  }else{
     write_led_decimals(0x18); // :pm
  }
  brightValue = analogRead(PHOTOCELL);
  write_brightness(brightValue);
  
  write_led(hourFormat12(), minute());
  delay(100);

}
« Last Edit: August 16, 2010, 02:54:30 pm by abocanegra » Logged

Los Angeles
Offline Offline
Newbie
*
Karma: 0
Posts: 22
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have solved it. The issue was that although i was calling the SLAVESELECT LOW/HIGH in different functions they didn't get along.

To make the display show clean you must call it only once per loop cycle and place all display calls between a single SLAVESELECT low and SLAVESELECT high
Logged

Pages: [1]   Go Up
Jump to: