Go Down

Topic: 7 segment Display Watch (Read 2621 times) previous topic - next topic

Flyingchainsaw

Sep 27, 2012, 12:12 am Last Edit: Sep 27, 2012, 12:21 pm by Flyingchainsaw Reason: 1
Hello there!
I'm fairly new to the more "software" side of Arduino (I've built several robots with it LMR FTW) and I'm trying to make a 7 segment display (1 digit) show the time. I'd like it to show the first digit of the hour, second digit of the hour, first digit of the minute, and the second digit of the minute when I press a button (on pin 1). The pins for the 7 segment are as follows: 2,3,4,5,6,7,8, and 9. I basically mashed two example codes, got rid of the icky stuff, and made myself a sort of core. Ultimately, I'd like to transpose this onto my ATtiny 44A and make a wrist watch out of it (After some pin changes). The code can already keep time, send it to the serial port, and receive time changes using UNIX time stamps. It already has the codes set up for displaying numbers 1 through 9 on the seven segment. It has all been tested up to there. So, do you think you can help me finish the code? Fabulous! Thanks a bunch!
Code: [Select]
#include <Time.h>  

#define TIME_MSG_LEN  11   // time sync to PC is HEADER followed by Unix time_t as ten ASCII digits
#define TIME_HEADER  'T'   // Header tag for serial time sync message
#define TIME_REQUEST  7    // ASCII bell character requests a time sync message

// T1262347200  //noon Jan 1 2010
const int buttonPin = 2;
int buttonState = 0;
byte seven_seg_digits[10][7] = { { 1,1,1,1,1,1,0 },  // = 0
                                                          { 0,1,1,0,0,0,0 },  // = 1
                                                          { 1,1,0,1,1,0,1 },  // = 2
                                                          { 1,1,1,1,0,0,1 },  // = 3
                                                          { 0,1,1,0,0,1,1 },  // = 4
                                                          { 1,0,1,1,0,1,1 },  // = 5
                                                          { 1,0,1,1,1,1,1 },  // = 6
                                                          { 1,1,1,0,0,0,0 },  // = 7
                                                          { 1,1,1,1,1,1,1 },  // = 8
                                                          { 1,1,1,0,0,1,1 }   // = 9
                                                          };
void setup()  {
 Serial.begin(9600);
 pinMode(buttonPin, INPUT);
 pinMode(2, OUTPUT);  
 pinMode(3, OUTPUT);
 pinMode(4, OUTPUT);
 pinMode(5, OUTPUT);
 pinMode(6, OUTPUT);
 pinMode(7, OUTPUT);
 pinMode(8, OUTPUT);
 pinMode(9, OUTPUT);
 writeDot(0);  // start with the "dot" off
}

void writeDot(byte dot) {
 digitalWrite(9, dot);
}
void sevenSegWrite(byte digit) {
 byte pin = 2;
 for (byte segCount = 0; segCount < 7; ++segCount) {
   digitalWrite(pin, seven_seg_digits[digit][segCount]);
   ++pin;
 }
}

void loop(){    
 if(Serial.available() )
 {
   processSyncMessage();
 }
 if(timeStatus() == timeNotSet)
   Serial.println("waiting for sync message");
 else    
     digitalClockDisplay();  
 delay(1000);
}

void digitalClockDisplay(){
 // digital clock display of the time
 Serial.print(hour());
 printDigits(minute());
 printDigits(second());
 Serial.print(" ");
 Serial.print(day());
 Serial.print(" ");
 Serial.print(month());
 Serial.print(" ");
 Serial.print(year());
 Serial.println();
}

void printDigits(int digits){
 // utility function for digital clock display: prints preceding colon and leading 0
 Serial.print(":");
 if(digits < 10)
   Serial.print('0');
 Serial.print(digits);
}

void processSyncMessage() {
 // if time sync available from serial port, update time and return true
 while(Serial.available() >=  TIME_MSG_LEN ){  // time message consists of header & 10 ASCII digits
   char c = Serial.read() ;
   Serial.print(c);  
   if( c == TIME_HEADER ) {      
     time_t pctime = 0;
     for(int i=0; i < TIME_MSG_LEN -1; i++){  
       c = Serial.read();          
       if( c >= '0' && c <= '9'){  
         pctime = (10 * pctime) + (c - '0') ; // convert digits to a number    
       }
     }  
     setTime(pctime);   // Sync Arduino clock to the time received on the serial port
   }  
 }
}
void leddisplay(){
//addition to BOTH of the codes; a sort of marriage between them.
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
 //here the time would convert to the 7 segment display
}
}

If you have read all the way to here, you're the best <3 :*

Flyingchainsaw

Anyone wanna help me?
...
Forever alone  =(

CrossRoads

Quote
//here the time would convert to the 7 segment display

Not clear to me how many digits you will be using - 2? 3? 4?
You have 8 pins available. Will you be using an external shift register?
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Far-seeker

What exactly do you need help with?  
According you your first post, you can:

  • Keep time

  • Communicate over a serial port

  • Receive and understand external time stamps

  • Display the proper digits



You still need to port and test the code on the ATtiny, but by coming this far on your own you appear to be quite capable of that.

Flyingchainsaw

Oh! Gosh! I'm sorry for the confusion! It is only a single digit. That's why it goes 1st hour, 2nd hour, 1st minute, 2nd minute.
It is a direct drive; no shift registers.
Thank you so much for replying! :)

CrossRoads

I would show the digits as part of this
Code: [Select]

void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year());
  Serial.println();
}

Make an array of number fonts, drive the segments from that array.
Every 4 seconds, update a digit.  Display second only when button is pressed.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Flyingchainsaw

Ok! thanks for the reply! The button would display the time when pressed tho. so the button would activate the loop, instead of seconds, to save battery life. And how would I set up an array?

CrossRoads

The array part is easy. Assuming you want a 1 to turn on a segment:
Code: [Select]

// pre-setup code
// array of segments to turn on
//B = binary, with bits= decimal point-g-f-e-d-c-b-a
segmentArray[] = {
B00111111, // 0       a
B00000110, // 1    f      b
B01101011, // 2       g
B01001111, // 3    e     c
B01100110, // 4       d
B01101101, // 5
B01011111, // 6
B00000111, // 7
B01111111, // 8
B01101111, // 9
};
// array of pins to turn on
byte pinArray[] = {2,3,4,5,6,7,8,9};
// 9 = Decimal point, 8=g, 7=f, 6=e,5=d, 4=c, 3=b, 2=a


Code: [Select]

// loop code, or a function
// display a digit
// assumes numberToDisplay is assigned/passed on:
maskBit = 0x01; // masks off all but segment A to start
for (x = 0; x<8; x=x+1){
// for x=0: write pin 2 with (B00000001 & numberToDisplay) to turn on/off segment A
// then 3 with B00000010 & numberToDisplay for segment B, etc.
digitalWrite (pinArray[x], (segmentArray[numberToDisplay] & maskBit) );
maskBit = maskBit <1; // move the bit 1 left to mask for next segment
}


Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Go Up