/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 01:25:02 UTC
  • Revision ID: tim@ed.am-20120310012502-v0jwfjghpp63un6n
removed time singleton, not cause it saved much space, but cause i don't want singletons in this project!

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:
82
82
#include "analogue_clock.h"
83
83
#include "digital_clock.h"
84
84
#include "test_pattern.h"
85
 
#include "settings_mode.h"
86
 
#include "text.h"
87
 
#include "text_renderer.h"
88
 
#include "common.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
 
        // give the mode a chance to init
149
 
        switch( _major_mode ) {
150
 
        case MAIN_MODE_IDX: activate_minor_mode(); break;
151
 
        case SETTINGS_MODE_IDX: settings_mode_activate(); break;
152
 
        }
153
 
}
154
 
 
155
 
 
156
129
// perform button events
157
130
void do_button_events()
158
131
{
170
143
                                case DIGITAL_CLOCK_IDX: digital_clock_press(); break;
171
144
                                }
172
145
                                break;
173
 
                        case SETTINGS_MODE_IDX: settings_mode_press(); break;
174
146
                        }
175
147
                        break;
176
148
 
180
152
                        case MAIN_MODE_IDX:
181
153
                                if( ++_minor_mode >= 3 )
182
154
                                        _minor_mode = 0;
183
 
                                activate_minor_mode();
 
155
                                switch( _minor_mode ) {
 
156
                                case DIGITAL_CLOCK_IDX: digital_clock_activate(); break;
 
157
                                }
184
158
                                break;
185
 
                        case SETTINGS_MODE_IDX: settings_mode_long_press(); break;
186
159
                        }
187
160
                        break;
188
161
 
189
162
                case 3:
190
163
                        // looooong press (change major mode)
191
 
                        if( ++_major_mode > 1 )
 
164
                        if( ++_major_mode > 0 )
192
165
                                _major_mode = 0;
193
 
                        activate_major_mode();
 
166
                        switch( _major_mode ) {
 
167
                        case MAIN_MODE_IDX: _minor_mode = 0; break;
 
168
                        }
 
169
                        activate_minor_mode();
194
170
                        break;
195
171
                }
196
172
        }
209
185
        if( reset ) segment = NUM_SEGMENTS - 1 - CLOCK_SHIFT;
210
186
#endif
211
187
 
212
 
        // reset the text renderer
213
 
        TextRenderer::reset_buffer();
214
 
 
215
 
        // frame reset
216
 
        if( reset ) {
217
 
                switch( _major_mode ) {
218
 
                case MAIN_MODE_IDX:
219
 
                        switch( _minor_mode ) {
220
 
                        case ANALOGUE_CLOCK_IDX: analogue_clock_draw_reset(); break;
221
 
                        case DIGITAL_CLOCK_IDX: digital_clock_draw_reset(); break;
222
 
                        }
223
 
                        break;
224
 
                case SETTINGS_MODE_IDX: settings_mode_draw_reset(); break;
225
 
                }
226
 
 
227
 
                // tell the text services we're starting a new frame
228
 
                Text::draw_reset();
229
 
        }
230
 
 
231
188
        // draw
232
189
        switch( _major_mode ) {
233
190
        case MAIN_MODE_IDX:
237
194
                case TEST_PATTERN_IDX: test_pattern_draw( segment ); break;
238
195
                }
239
196
                break;
240
 
        case SETTINGS_MODE_IDX: settings_mode_draw( segment ); break;
241
197
        }
242
198
 
243
 
        // draw any text that was rendered
244
 
        TextRenderer::output_buffer();
245
 
 
246
199
#if CLOCK_FORWARD
247
200
        if( ++segment >= NUM_SEGMENTS ) segment = 0;
248
201
#else
329
282
        static int event_times[] = { 5, 500, 4000, 0 };
330
283
        _button.set_event_times( event_times );
331
284
 
332
 
        // initialise RTC
 
285
        // get time from RTC
333
286
        Time::init();
334
287
 
335
288
        // activate the minor mode
336
 
        activate_major_mode();
 
289
        switch( _major_mode ) {
 
290
        case MAIN_MODE_IDX: activate_minor_mode(); break;
 
291
        }
337
292
}
338
293
 
339
294