/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-12 21:11:20 UTC
  • Revision ID: tim@ed.am-20120312211120-r86cs574yxztgqij
added time set mode, made text renderer's buffer auto reset/output

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
122
127
void activate_minor_mode()
123
128
{
124
129
        switch( _minor_mode ) {
 
130
        case ANALOGUE_CLOCK_IDX: analogue_clock_activate(); break;
125
131
        case DIGITAL_CLOCK_IDX: digital_clock_activate(); break;
126
132
        }
127
 
}
 
133
 
 
134
        // reset text
 
135
        Text::reset();
 
136
        leds_off();
 
137
}
 
138
 
 
139
 
 
140
// activate major mode
 
141
void activate_major_mode()
 
142
{
 
143
        switch( _major_mode ) {
 
144
        case MAIN_MODE_IDX: activate_minor_mode(); break;
 
145
        case SETTINGS_MODE_IDX: settings_mode_activate(); break;
 
146
        }
 
147
 
 
148
        // reset text
 
149
        Text::reset();
 
150
        leds_off();
 
151
}
 
152
 
128
153
 
129
154
// perform button events
130
155
void do_button_events()
143
168
                                case DIGITAL_CLOCK_IDX: digital_clock_press(); break;
144
169
                                }
145
170
                                break;
 
171
                        case SETTINGS_MODE_IDX: settings_mode_press(); break;
146
172
                        }
147
173
                        break;
148
174
 
152
178
                        case MAIN_MODE_IDX:
153
179
                                if( ++_minor_mode >= 3 )
154
180
                                        _minor_mode = 0;
155
 
                                switch( _minor_mode ) {
156
 
                                case DIGITAL_CLOCK_IDX: digital_clock_activate(); break;
157
 
                                }
 
181
                                activate_minor_mode();
158
182
                                break;
 
183
                        case SETTINGS_MODE_IDX: settings_mode_long_press(); break;
159
184
                        }
160
185
                        break;
161
186
 
162
187
                case 3:
163
188
                        // looooong press (change major mode)
164
 
                        if( ++_major_mode > 0 )
 
189
                        if( ++_major_mode > 1 )
165
190
                                _major_mode = 0;
166
 
                        switch( _major_mode ) {
167
 
                        case MAIN_MODE_IDX: _minor_mode = 0; break;
168
 
                        }
169
 
                        activate_minor_mode();
 
191
                        activate_major_mode();
170
192
                        break;
171
193
                }
172
194
        }
185
207
        if( reset ) segment = NUM_SEGMENTS - 1 - CLOCK_SHIFT;
186
208
#endif
187
209
 
 
210
        // reset the text renderer
 
211
        TextRenderer::reset_buffer();
 
212
 
 
213
        // frame reset
 
214
        if( reset ) {
 
215
                switch( _major_mode ) {
 
216
                case MAIN_MODE_IDX:
 
217
                        switch( _minor_mode ) {
 
218
                        case ANALOGUE_CLOCK_IDX: analogue_clock_draw_reset(); break;
 
219
                        case DIGITAL_CLOCK_IDX: digital_clock_draw_reset(); break;
 
220
                        }
 
221
                        break;
 
222
                case SETTINGS_MODE_IDX: settings_mode_draw_reset(); break;
 
223
                }
 
224
 
 
225
                // tell the text services we're starting a new frame
 
226
                Text::draw_reset();
 
227
        }
 
228
 
188
229
        // draw
189
230
        switch( _major_mode ) {
190
231
        case MAIN_MODE_IDX:
194
235
                case TEST_PATTERN_IDX: test_pattern_draw( segment ); break;
195
236
                }
196
237
                break;
 
238
        case SETTINGS_MODE_IDX: settings_mode_draw( segment ); break;
197
239
        }
198
240
 
 
241
        // draw any text that was rendered
 
242
        TextRenderer::output_buffer();
 
243
 
199
244
#if CLOCK_FORWARD
200
245
        if( ++segment >= NUM_SEGMENTS ) segment = 0;
201
246
#else
282
327
        static int event_times[] = { 5, 500, 4000, 0 };
283
328
        _button.set_event_times( event_times );
284
329
 
 
330
        // initialise RTC
 
331
        Time::init();
 
332
 
285
333
        // activate the minor mode
286
 
        switch( _major_mode ) {
287
 
        case MAIN_MODE_IDX: activate_minor_mode(); break;
288
 
        }
 
334
        activate_major_mode();
289
335
}
290
336
 
291
337
 
306
352
                calculate_segment_times();
307
353
 
308
354
                // keep track of time
309
 
                Time &time = Time::get_instance();
310
 
                time.update();
 
355
                Time::update();
311
356
 
312
357
                // perform button events
313
358
                do_button_events();