Steam Clock code
November 11th, 2009As promised, here is the steam clock source code.
It uses two non-standard Arduino libraries:
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); } } |























