Vector Clock
Jump to navigation
Jump to search
Synopsis
Use an oscilloscope in XY mode to display time. Uses two MCP4725 and a DS1302.
Notes
Known bug. 12 hour hand is missing. Hour hand does not creep, but instead moves in one hour notches. Ideally, use the Sine function to determine precise positioning.
Code
1 //Arduino UNO
2 //Pin 5 : DS1302 Chip Enable
3 //Pin 6 : DS1302 Data
4 //Pin 7 : DS1302 Data Clock
5 //Pin A4 : MCP4725 SDA pins
6 //Pin A5 : MCP4725 SCK pins
7 //
8 //5 Volt pin powers all external devices
9 //Please verify that your modules are also
10 //compatible with a 5 volt supply.
11 //
12 //On the MCP4725 devices, attach one A0
13 //pin to 5 volts and the other to ground
14 //to ensure these are on different addresses
15 //The SDA and SCK pins on these can be attached
16 //to each other. The device ID of the
17 //MCP4725 had to be discovered experimentally
18 //and you may need to discover those values as
19 //well.
20 //
21 //On the MCP4725, choose the voltage out pins
22 //to be connected to the X and Y inputs of
23 //your oscilloscope such that the clock is suitably rotated.
24
25 #include <Wire.h>
26 #include <Adafruit_MCP4725.h>
27 #include <DS1302.h>
28
29 //Begin DS1302 Configuration
30 const int kCePin = 5; // Chip Enable
31 const int kIoPin = 6; // Input/Output
32 const int kSclkPin = 7; // Serial Clock
33 DS1302 rtc(kCePin, kIoPin, kSclkPin);
34 //End DS1302 Configuration
35
36 // Begin MCP4725 Configuration
37 Adafruit_MCP4725 dac_X;
38 Adafruit_MCP4725 dac_Y;
39 // End MCP4725 Configuration
40
41 //timing and counnters
42 long us;
43 bool toggle;
44 byte t=0;
45
46 const uint16_t DACLookup_FullSine_8Bit[256] =
47 {
48 2048, 2098, 2148, 2198, 2248, 2298, 2348, 2398,
49 2447, 2496, 2545, 2594, 2642, 2690, 2737, 2784,
50 2831, 2877, 2923, 2968, 3013, 3057, 3100, 3143,
51 3185, 3226, 3267, 3307, 3346, 3385, 3423, 3459,
52 3495, 3530, 3565, 3598, 3630, 3662, 3692, 3722,
53 3750, 3777, 3804, 3829, 3853, 3876, 3898, 3919,
54 3939, 3958, 3975, 3992, 4007, 4021, 4034, 4045,
55 4056, 4065, 4073, 4080, 4085, 4089, 4093, 4094,
56 4095, 4094, 4093, 4089, 4085, 4080, 4073, 4065,
57 4056, 4045, 4034, 4021, 4007, 3992, 3975, 3958,
58 3939, 3919, 3898, 3876, 3853, 3829, 3804, 3777,
59 3750, 3722, 3692, 3662, 3630, 3598, 3565, 3530,
60 3495, 3459, 3423, 3385, 3346, 3307, 3267, 3226,
61 3185, 3143, 3100, 3057, 3013, 2968, 2923, 2877,
62 2831, 2784, 2737, 2690, 2642, 2594, 2545, 2496,
63 2447, 2398, 2348, 2298, 2248, 2198, 2148, 2098,
64 2048, 1997, 1947, 1897, 1847, 1797, 1747, 1697,
65 1648, 1599, 1550, 1501, 1453, 1405, 1358, 1311,
66 1264, 1218, 1172, 1127, 1082, 1038, 995, 952,
67 910, 869, 828, 788, 749, 710, 672, 636,
68 600, 565, 530, 497, 465, 433, 403, 373,
69 345, 318, 291, 266, 242, 219, 197, 176,
70 156, 137, 120, 103, 88, 74, 61, 50,
71 39, 30, 22, 15, 10, 6, 2, 1,
72 0, 1, 2, 6, 10, 15, 22, 30,
73 39, 50, 61, 74, 88, 103, 120, 137,
74 156, 176, 197, 219, 242, 266, 291, 318,
75 345, 373, 403, 433, 465, 497, 530, 565,
76 600, 636, 672, 710, 749, 788, 828, 869,
77 910, 952, 995, 1038, 1082, 1127, 1172, 1218,
78 1264, 1311, 1358, 1405, 1453, 1501, 1550, 1599,
79 1648, 1697, 1747, 1797, 1847, 1897, 1947, 1997
80 };
81
82 const long HandsX[60] =
83 {
84 2047, 2261, 2473, 2680, 2880, 3071, 3251, 3417,
85 3569, 3704, 3820, 3918, 3994, 4050, 4083, 4095,
86 4083, 4050, 3994, 3918, 3820, 3704, 3569, 3417,
87 3251, 3071, 2880, 2680, 2473, 2261, 2048, 1834,
88 1622, 1415, 1215, 1024, 844, 678, 526, 391,
89 275, 177, 101, 45, 12, 1, 12, 45,
90 101, 177, 275, 391, 526, 678, 844, 1024,
91 1215, 1415, 1622, 1834
92 };
93 const long HandsY[60] =
94 {
95 4095, 4083, 4050, 3994, 3918, 3820, 3704, 3569,
96 3417, 3251, 3071, 2880, 2680, 2473, 2261, 2048,
97 1834, 1622, 1415, 1215, 1024, 844, 678, 526,
98 391, 275, 177, 101, 45, 12, 1, 12,
99 45, 101, 177, 275, 391, 526, 678, 844,
100 1024, 1215, 1415, 1622, 1834, 2047, 2261, 2473,
101 2680, 2880, 3071, 3251, 3417, 3569, 3704, 3820,
102 3918, 3994, 4050, 4083
103 };
104
105 void Hand(byte v, byte len)
106 {
107 long i,x,y;
108 for(i=0;i<len;i++)
109 //Draw from center
110 {
111 //2048,2048 is the center.
112 x=2048+(HandsX[v]-2048)*i/100;
113 y=2048+(HandsY[v]-2048)*i/100;
114 dac_X.setVoltage(x , false,400000);
115 dac_Y.setVoltage(y , false,400000);
116 }
117 }
118
119 void Circle()
120 {
121 uint16_t i;
122 uint16_t j;
123 for (i = 0; i < 256; i++)
124 {
125 dac_X.setVoltage(DACLookup_FullSine_8Bit[i], false);
126
127 j=i+193;
128 j=j%256;
129 dac_Y.setVoltage(DACLookup_FullSine_8Bit[j], false);
130
131 }
132 }
133
134 void setup(void) {
135 Serial.begin(9600);
136 delay(1000);
137 rtc.writeProtect(true);
138 Serial.println("This page intentionally left blank.");
139
140 dac_X.begin(0x63);
141 dac_Y.begin(0x62);
142 us = 500000 + micros();
143 }
144
145 void loop(void)
146 {
147 byte hr;
148 Time tm;
149 tm = rtc.time();
150 hr=tm.hr;
151 while(hr>12) hr -= 12;
152
153 if(t==0)
154 {
155 //Update time from rtc
156
157 t=1;
158 }
159
160
161 if(micros()<us)
162 {
163 Circle();
164 Hand(tm.min,70); //Minutes
165 Hand(hr*5,50); //Hours
166 if(toggle){Hand(tm.sec,90);} //Seconds
167 }
168 else
169 {
170 us = 500000 + micros();
171 if(toggle) toggle=LOW; else toggle=HIGH;
172
173 t++;
174 }
175 }