Four Digit Seven Segment LED Display

  

 

Update: LDR control of brightness can be found here.

This display has a TM1637 display driver and was made by Seed Studio although there are a number of copies around. The display has four connections, Vcc, Gnd, Clock and Data. I had so much trouble trying to get this to work, I found two different libraries but neither seemed to work. Even the library and example from Seed Studio just would not work for me.

Eventually I found this blog that explained what was needed. Most of the other tutorials used a number of libraries (anything up to five!) but this sketch used no library at all. It seems that the sequence used to send data to the driver has to be done in a specific way.

I wanted to build a clock, but the blog gave a sketch for a timer, so I have modified the original sketch so that the clock shows Hours and Minutes. The sketch is the work of the original blogger, but I publish my modified version here with the original author data intact.

The time can be set by editing the time set section, mine was set to start at 22:11. Edit this setting the time a minute or so fast then at the correct time press Reset on the Arduino. The clock shows time in the 24 hour format.

Connections:

Arduino TM1637 display
PIN #7 ------------------ CLK
PIN #8 ------------------ DIO
5V ---------------------- VCC
GND --------------------- GND

The Sketch:

/* TM1637 4 Digit Seven Segment Display, Clock
Credit to Blog 3D Logic.com */


/* 24 hour clock code by Chris Rouse

Connections:
Vcc on Display to 5 volts on Arduino
Gnd on Display to Gnd on Arduino
CLK on Display to Pin 2 on Arduino
DIO on Display to pin 3 on Arduino
*/

const int clock = 2;
const int data = 3;

/*0*/ /*1*/ /*2*/ /*3*/ /*4*/ /*5*/ /*6*/ /*7*/ /*8*/ /*9*/
uint8_t digits[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f };
byte tcnt2;
//unsigned long time = 0; // 86390000;

/********************************************************
Set clock to desired time if required
Otherwise REM the next 3 lines out and the clock
will start from 00:00
Do not add leading zeros to the values
time is in 24 hour format
**********************************************************/
unsigned long setMinutes = 11;
unsigned long setHours = 22;
unsigned long time = (setMinutes * 60 * 1000) + (setHours * 3600 *1000);
/***************************************************************/

void setup()
{
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
setupInterrupt();

pinMode(clock, OUTPUT);
pinMode(data, OUTPUT);

// initialise display and set brightness
// 0x88 is dim and increasing value to 0x8C increases brightness
start();
writeValue(0x8c);
stop();

// clear display
write(0xff, 0xff, 0xff, 0xff);
}

// Credits for the interrupt setup routine:
// http://popdevelop.com/2010/04/mastering-timer-interrupts-on-the-arduino/
void setupInterrupt()
{
/* First disable the timer overflow interrupt while we're configuring */
TIMSK2 &= ~(1<<toie2);

</toie2);

/* Configure timer2 in normal mode (pure counting, no PWM etc.) */
TCCR2A &= ~((1<<wgm21) |="" (1<<wgm20));

TCCR2B &= ~(1<<wgm22);

</wgm22);

/* Select clock source: internal I/O clock */
ASSR &= ~(1<<as2);

</as2);

/* Disable Compare Match A interrupt enable (only want overflow) */
TIMSK2 &= ~(1<<ocie2a);

</ocie2a);

/* Now configure the prescaler to CPU clock divided by 128 */
TCCR2B |= (1<<cs22) |="" (1<<cs20);="" set="" bits

TCCR2B &= ~(1<<cs21); clear="" bit

/* We need to calculate a proper value to load the timer counter.
* The following loads the value 131 into the Timer 2 counter register
* The math behind this is:
* (CPU frequency) / (prescaler value) = 125000 Hz = 8us.
* (desired period) / 8us = 125.
* MAX(uint8) + 1 - 125 = 131;
*/
/* Save value globally for later reload in ISR */
tcnt2 = 131;

/* Finally load end enable the timer */
TCNT2 = tcnt2;
TIMSK2 |= (1<<toie2);
}</toie2);
/*
* Install the Interrupt Service Routine (ISR) for Timer2 overflow.
* This is normally done by writing the address of the ISR in the
* interrupt vector table but conveniently done by using ISR() */
ISR(TIMER2_OVF_vect) {
/* Reload the timer */
TCNT2 = tcnt2;

time++;
time = time % 86400000;

}

void loop()
{
unsigned long t = (unsigned long)(time/1000);
uint8_t minutes = (byte)((t / 60) % 60);
uint8_t hours = (byte)((t / 3600) % 23);
uint8_t seconds = (byte)(t % 60);

// blink onboard LED every Second
if(((seconds/2)*2) == seconds) {
digitalWrite(13, LOW);
}
else {
digitalWrite(13, HIGH);
}
//
// display the time
write(digits[hours / 10], digits[hours % 10] | ((seconds & 0x01) << 7), digits[minutes / 10], digits[minutes % 10]);
}

void write(uint8_t first, uint8_t second, uint8_t third, uint8_t fourth)
{
start();
writeValue(0x40);
stop();

start();
writeValue(0xc0);
writeValue(first);
writeValue(second);
writeValue(third);
writeValue(fourth);
stop();
}

void start(void)
{
digitalWrite(clock,HIGH);//send start signal to TM1637
digitalWrite(data,HIGH);
delayMicroseconds(5);

digitalWrite(data,LOW);
digitalWrite(clock,LOW);
delayMicroseconds(5);
}

void stop(void)
{
digitalWrite(clock,LOW);
digitalWrite(data,LOW);
delayMicroseconds(5);

digitalWrite(clock,HIGH);
digitalWrite(data,HIGH);
delayMicroseconds(5);
}

bool writeValue(uint8_t value)
{
for(uint8_t i = 0; i < 8; i++)
{
digitalWrite(clock, LOW);
delayMicroseconds(5);
digitalWrite(data, (value & (1 << i)) >> i);
delayMicroseconds(5);
digitalWrite(clock, HIGH);
delayMicroseconds(5);
}

// wait for ACK
digitalWrite(clock,LOW);
delayMicroseconds(5);

pinMode(data,INPUT);

digitalWrite(clock,HIGH);
delayMicroseconds(5);

bool ack = digitalRead(data) == 0;

pinMode(data,OUTPUT);

return ack;
}

Things to do:
The brightness of the display can be altered and there are eight levels from dim to bright, adding an LDR circuit could be used to dim the display as the light level drops. 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s