/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-21 20:35:28 UTC
  • Revision ID: tim@ed.am-20120321203528-wfhpych1tub75rgj
fixed bug initialising text services on mode activation

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 (tachiometer) pin connected to pin 2 on the
32
 
   arduino.
 
31
 * the fan's SENSE (tachometer) 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 anf off in unison in the centre of the clock.
 
40
   LEDs that turn on and 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 analog pins 4 and 5.
 
44
 * A DS1307 remote clock is connected via I2C on analogue 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 tachiometer pulses per revolution, so the
 
53
 * a PC fan actually sends 2 tachometer 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 dicsover the position that
 
56
   position. You will need to experiment to discover 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"
85
89
 
86
90
//_____________________________________________________________________________
87
91
//                                                                         data
108
112
static int _major_mode = 0;
109
113
static int _minor_mode = 0;
110
114
 
111
 
#define MAIN_MODE_IDX 0
 
115
#define MAIN_MODE_IDX 1
 
116
#define SETTINGS_MODE_IDX 0
112
117
 
113
118
#define ANALOGUE_CLOCK_IDX 0
114
119
#define DIGITAL_CLOCK_IDX 1
121
126
// activate the current minor mode
122
127
void activate_minor_mode()
123
128
{
 
129
        // reset text
 
130
        Text::reset();
 
131
        leds_off();
 
132
 
 
133
        // give the mode a chance to init
124
134
        switch( _minor_mode ) {
 
135
        case ANALOGUE_CLOCK_IDX: analogue_clock_activate(); break;
125
136
        case DIGITAL_CLOCK_IDX: digital_clock_activate(); break;
126
137
        }
127
138
}
128
139
 
 
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
 
129
156
// perform button events
130
157
void do_button_events()
131
158
{
143
170
                                case DIGITAL_CLOCK_IDX: digital_clock_press(); break;
144
171
                                }
145
172
                                break;
 
173
                        case SETTINGS_MODE_IDX: settings_mode_press(); break;
146
174
                        }
147
175
                        break;
148
176
 
152
180
                        case MAIN_MODE_IDX:
153
181
                                if( ++_minor_mode >= 3 )
154
182
                                        _minor_mode = 0;
155
 
                                switch( _minor_mode ) {
156
 
                                case DIGITAL_CLOCK_IDX: digital_clock_activate(); break;
157
 
                                }
 
183
                                activate_minor_mode();
158
184
                                break;
 
185
                        case SETTINGS_MODE_IDX: settings_mode_long_press(); break;
159
186
                        }
160
187
                        break;
161
188
 
162
189
                case 3:
163
190
                        // looooong press (change major mode)
164
 
                        if( ++_major_mode > 0 )
 
191
                        if( ++_major_mode > 1 )
165
192
                                _major_mode = 0;
166
 
                        switch( _major_mode ) {
167
 
                        case MAIN_MODE_IDX: _minor_mode = 0; break;
168
 
                        }
169
 
                        activate_minor_mode();
 
193
                        activate_major_mode();
170
194
                        break;
171
195
                }
172
196
        }
185
209
        if( reset ) segment = NUM_SEGMENTS - 1 - CLOCK_SHIFT;
186
210
#endif
187
211
 
 
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
 
188
231
        // draw
189
232
        switch( _major_mode ) {
190
233
        case MAIN_MODE_IDX:
194
237
                case TEST_PATTERN_IDX: test_pattern_draw( segment ); break;
195
238
                }
196
239
                break;
 
240
        case SETTINGS_MODE_IDX: settings_mode_draw( segment ); break;
197
241
        }
198
242
 
 
243
        // draw any text that was rendered
 
244
        TextRenderer::output_buffer();
 
245
 
199
246
#if CLOCK_FORWARD
200
247
        if( ++segment >= NUM_SEGMENTS ) segment = 0;
201
248
#else
282
329
        static int event_times[] = { 5, 500, 4000, 0 };
283
330
        _button.set_event_times( event_times );
284
331
 
 
332
        // initialise RTC
 
333
        Time::init();
 
334
 
285
335
        // activate the minor mode
286
 
        switch( _major_mode ) {
287
 
        case MAIN_MODE_IDX: activate_minor_mode(); break;
288
 
        }
 
336
        activate_major_mode();
289
337
}
290
338
 
291
339
 
306
354
                calculate_segment_times();
307
355
 
308
356
                // keep track of time
309
 
                Time &time = Time::get_instance();
310
 
                time.update();
 
357
                Time::update();
311
358
 
312
359
                // perform button events
313
360
                do_button_events();