Steam Clock code

    As promised, here is the steam clock source code.

    It uses two non-standard Arduino libraries:

    1. Stepper – with half-stepping
    2. DateTime – a software clock

    The code is pretty straightforward. move() does most of the stepper work. hour() and minute() do the minimal calculation needed to point at the right places on the dial. minute() is used for seconds as well. wiggle() bounces the needle around the current point. Its fun to look at and makes a nice noise.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    
    #include <DateTime.h>
    #include <Stepper.h>
     
    #define TIME_MSG_LEN  11   // time sync to PC is HEADER and unix time_t as ten ascii digits
    #define TIME_HEADER  't'   // Header tag for serial time sync message
    #define TZ 8               // How many hours off of GMT are you?
     
    Stepper s(200, 4,5,6,7, 1);  // Stepper is on pins 4, 5, 6, 7.  Using the enhanced Stepper library with half-stepping.
     
    int p = 0;
     
    void setup() {
      Serial.begin(9600);
      Serial.println("Steam Clock 0.8");
     
      DateTime.sync(10000000);  // Needs to come from RTC.
     
      pinMode(2, INPUT);  // home sensor
      pinMode(3, OUTPUT); // home ir led
     
      find_home();
      allminutes();
      allhours();
      bouncehome();
    }
     
    void find_home() {
      digitalWrite(3, HIGH);  // turn on LED
      digitalWrite(2, HIGH);  // turn on pull-up for sensor
     
      for(int i=0; i < 900; i++) {
        s.step(1);
        delay(25);
        if(digitalRead(2)) {
           Serial.println("Home!!!");
            p = 0;
           break;
         }
       }
     
       digitalWrite(3, LOW);  // turn off LED
       digitalWrite(2, LOW);  // turn off pull-up.
    }
     
    void allminutes() {
      for(int t=0;t<=60;t++) {
        minute(t);
        delay(500);
        if(t % 10 == 0) {
          wiggle(20);
          delay(500);
        } 
      }
    }
     
    void allhours() {
      for(int t=0;t<=24;t++) {
         hour(t);
         delay(500);
      } 
    }
     
    void bouncehome() {
       minute(0);
       wiggle(100); 
    }
     
    void move(int to,int speed) {
      s.setSpeed(speed);
      if(to != p) {
        int steps = to - p;
        s.step(steps);
        p += steps;
      }
    }
     
    void wiggle(int i) {
      s.setSpeed(200);
      for(; i > 1; i -= 5){
         s.step(i);
         s.step(-i);
         s.step(-i);
         s.step(i);
      }  
    }
     
    void hour(int h) {
    //  move((int)(h * 2.125), 200);  // this shoulnd't be a float...
      move((int)(h * 2), 200);  // oh, 2 seems to work better anyway. yay!
    }
     
    void minute(int m) {
      move(400 - (m * 4), 200);
    }
     
    void getPCtime() {
      // if time available from serial port, sync the DateTime library
      while(Serial.available() >=  TIME_MSG_LEN ){  // time message
        if( Serial.read() == TIME_HEADER ) {        
          time_t pctime = 0;
          for(int i=0; i < TIME_MSG_LEN -1; i++){   
            char c= Serial.read();          
            if( c >= '0' && c <= '9')   
              pctime = (10 * pctime) + (c - '0') ; // convert digits to a number            
          }   
          DateTime.sync(pctime - (TZ * 60 * 60));   // Sync DateTime clock to the time received on the serial port
        }  
      }
    }
     
    void debugOutput() {
      Serial.print('t');
      Serial.println(DateTime.now()); 
     
      Serial.print(DateTime.Hour, DEC);
      Serial.print(':');
      Serial.print(DateTime.Minute, DEC);
      Serial.print(':');
      Serial.println(DateTime.Second, DEC);
     
      Serial.print(DateTime.Day, DEC);
      Serial.print('/');
      Serial.print(DateTime.Month, DEC);
      Serial.print('/');
      Serial.println(DateTime.Year, DEC);
    }
     
    void loop() {
      getPCtime();
      debugOutput();
     
      DateTime.available();
      hour(DateTime.Hour);
      wiggle(20);
      delay(2000);
     
      DateTime.available();
      minute(DateTime.Minute);
      wiggle(20);
      delay(2000);
     
      DateTime.available();
      minute(DateTime.Second);
     
      DateTime.available();
      if(DateTime.Second < 50) {
         move(400 - ((DateTime.Second + 10) * 4), 1);
      } else {
         move(400 - ((60) * 4), 1);
      }
    }

    Leave a Reply

    Looking for something?

    Use the form below to search the site:

    Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

    Visit our friends!

    A few highly recommended friends...

    Archives

    All entries, chronologically...