/elec/propeller-clock

To get this branch, use:
bzr branch http://bzr.ed.am/elec/propeller-clock

« back to all changes in this revision

Viewing changes to src/propeller-clock.cc

  • Committer: Tim Marston
  • Date: 2012-03-10 12:31:16 UTC
  • Revision ID: tim@ed.am-20120310123116-l348p5btgecmdj1q
added realtime clock test

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
 
29
29
 * a PC fan is wired up to a 12V power supply
30
30
 
31
 
 * the fan's SENSE (tachometer) pin connected to pin 2 on the
32
 
   Arduino.
 
31
 * the fan's SENSE (tachiometer) pin connected to pin 2 on the
 
32
   arduino.
33
33
 
34
 
 * the pins 4 to 13 on the Arduino should directly drive an LED (the
 
34
 * the pins 4 to 13 on the arduino should directly drive an LED (the
35
35
   LED on pin 4 is in the centre of the clock face and the LED on pin
36
36
   13 is at the outside.
37
37
 
38
38
 * if a longer hand (and a larger clock face) is desired, pin 4 can be
39
39
   used to indirectly drive a transistor which in turn drives several
40
 
   LEDs that turn on and off in unison in the centre of the clock.
 
40
   LEDs that turn on anf off in unison in the centre of the clock.
41
41
 
42
42
 * a button should be attached to pin 3 that grounds it when pressed.
43
43
 
44
 
 * A DS1307 remote clock is connected via I2C on analogue pins 4 and 5.
 
44
 * A DS1307 remote clock is connected via I2C on analog pins 4 and 5.
45
45
 
46
46
Implementation details:
47
47
 
50
50
 * the timing of the drawing of the clock face is recalculated with
51
51
   every rotation of the propeller.
52
52
    
53
 
 * a PC fan actually sends 2 tachometer pulses per revolution, so the
 
53
 * a PC fan actually sends 2 tachiometer pulses per revolution, so the
54
54
   software skips every other one. This means that the clock may
55
55
   appear upside-down if started with the propeller in the wrong
56
 
   position. You will need to experiment to discover the position that
 
56
   position. You will need to experiment to dicsover the position that
57
57
   the propeller must be in when starting the clock.
58
58
    
59
59
Usage instructions:
79
79
#include "button.h"
80
80
#include "time.h"
81
81
#include "Arduino.h"
82
 
#include "modes/analogue_clock.h"
83
 
#include "modes/digital_clock.h"
84
 
#include "modes/test_pattern.h"
85
 
#include "modes/settings_mode.h"
86
 
#include "text.h"
87
 
#include "text_renderer.h"
88
 
#include "common.h"
 
82
#include "analogue_clock.h"
 
83
#include "digital_clock.h"
 
84
#include "test_pattern.h"
89
85
 
90
86
//_____________________________________________________________________________
91
87
//                                                                         data
112
108
static int _major_mode = 0;
113
109
static int _minor_mode = 0;
114
110
 
115
 
#define MAIN_MODE_IDX 1
116
 
#define SETTINGS_MODE_IDX 0
 
111
#define MAIN_MODE_IDX 0
117
112
 
118
113
#define ANALOGUE_CLOCK_IDX 0
119
114
#define DIGITAL_CLOCK_IDX 1
126
121
// activate the current minor mode
127
122
void activate_minor_mode()
128
123
{
129
 
        // reset text
130
 
        Text::reset();
131
 
        leds_off();
132
 
 
133
 
        // give the mode a chance to init
134
124
        switch( _minor_mode ) {
135
 
        case ANALOGUE_CLOCK_IDX: analogue_clock_activate(); break;
136
125
        case DIGITAL_CLOCK_IDX: digital_clock_activate(); break;
137
126
        }
138
127
}
139
128
 
140
 
 
141
 
// activate major mode
142
 
void activate_major_mode()
143
 
{
144
 
        // reset text
145
 
        Text::reset();
146
 
        leds_off();
147
 
 
148
 
        // reset buttons
149
 
        _button.set_press_mode( _major_mode != SETTINGS_MODE_IDX );
150
 
 
151
 
        // give the mode a chance to init
152
 
        switch( _major_mode ) {
153
 
        case MAIN_MODE_IDX: activate_minor_mode(); break;
154
 
        case SETTINGS_MODE_IDX: settings_mode_activate(); break;
155
 
        }
156
 
}
157
 
 
158
 
 
159
129
// perform button events
160
130
void do_button_events()
161
131
{
173
143
                                case DIGITAL_CLOCK_IDX: digital_clock_press(); break;
174
144
                                }
175
145
                                break;
176
 
                        case SETTINGS_MODE_IDX: settings_mode_press(); break;
177
146
                        }
178
147
                        break;
179
148
 
183
152
                        case MAIN_MODE_IDX:
184
153
                                if( ++_minor_mode >= 3 )
185
154
                                        _minor_mode = 0;
186
 
                                activate_minor_mode();
 
155
                                switch( _minor_mode ) {
 
156
                                case DIGITAL_CLOCK_IDX: digital_clock_activate(); break;
 
157
                                }
187
158
                                break;
188
 
                        case SETTINGS_MODE_IDX: settings_mode_long_press(); break;
189
159
                        }
190
160
                        break;
191
161
 
192
162
                case 3:
193
163
                        // looooong press (change major mode)
194
 
                        if( ++_major_mode > 1 )
 
164
                        if( ++_major_mode > 0 )
195
165
                                _major_mode = 0;
196
 
                        activate_major_mode();
 
166
                        switch( _major_mode ) {
 
167
                        case MAIN_MODE_IDX: _minor_mode = 0; break;
 
168
                        }
 
169
                        activate_minor_mode();
197
170
                        break;
198
171
                }
199
172
        }
212
185
        if( reset ) segment = NUM_SEGMENTS - 1 - CLOCK_SHIFT;
213
186
#endif
214
187
 
215
 
        // reset the text renderer
216
 
        TextRenderer::reset_buffer();
217
 
 
218
 
        // frame reset
219
 
        if( reset ) {
220
 
                switch( _major_mode ) {
221
 
                case MAIN_MODE_IDX:
222
 
                        switch( _minor_mode ) {
223
 
                        case ANALOGUE_CLOCK_IDX: analogue_clock_draw_reset(); break;
224
 
                        case DIGITAL_CLOCK_IDX: digital_clock_draw_reset(); break;
225
 
                        }
226
 
                        break;
227
 
                case SETTINGS_MODE_IDX: settings_mode_draw_reset(); break;
228
 
                }
229
 
 
230
 
                // tell the text services we're starting a new frame
231
 
                Text::draw_reset();
232
 
        }
233
 
 
234
188
        // draw
235
189
        switch( _major_mode ) {
236
190
        case MAIN_MODE_IDX:
240
194
                case TEST_PATTERN_IDX: test_pattern_draw( segment ); break;
241
195
                }
242
196
                break;
243
 
        case SETTINGS_MODE_IDX: settings_mode_draw( segment ); break;
244
197
        }
245
198
 
246
 
        // draw any text that was rendered
247
 
        TextRenderer::output_buffer();
248
 
 
249
199
#if CLOCK_FORWARD
250
200
        if( ++segment >= NUM_SEGMENTS ) segment = 0;
251
201
#else
332
282
        static int event_times[] = { 5, 500, 4000, 0 };
333
283
        _button.set_event_times( event_times );
334
284
 
335
 
        // initialise RTC
 
285
        // get time from RTC
336
286
        Time::init();
337
287
 
338
 
        // init text renderer
339
 
        TextRenderer::init();
340
 
 
341
288
        // activate the minor mode
342
 
        activate_major_mode();
 
289
        switch( _major_mode ) {
 
290
        case MAIN_MODE_IDX: activate_minor_mode(); break;
 
291
        }
343
292
}
344
293
 
345
294