100
98
static unsigned long segment_step_sub_step = 0;
 
101
99
static unsigned long segment_step_sub = 0;
 
104
 
static Button button( 3 );
 
107
 
static int major_mode = 0;
 
110
 
static std::vector< MajorMode * > major_modes;
 
 
101
// flag to indicate that the drawing mode should be cycled to the next one
 
 
102
static bool inc_draw_mode = false;
 
 
104
// a bounce-managed button
 
 
105
static Bounce button( 3, 5 );
 
 
108
static int time_hours = 0;
 
 
109
static int time_minutes = 0;
 
 
110
static int time_seconds = 0;
 
 
112
// number of segments in a full display (rotation) is 60 (one per
 
 
113
// second) times the desired number of sub-divisions of a second
 
 
114
#define NUM_SECOND_SEGMENTS 5
 
 
115
#define NUM_SEGMENTS ( 60 * NUM_SECOND_SEGMENTS )
 
112
117
//_____________________________________________________________________________
 
 
117
122
void checkButtons()
 
119
124
        // update buttons
 
120
 
        int event = button.update();
 
125
 
                major_modes[ major_mode ]->short_press();
 
128
 
                major_modes[ major_mode ]->long_press();
 
131
 
                if( ++major_mode >= major_modes.size() )
 
133
 
                major_modes[ major_mode ]->activate();
 
 
127
        // notice button presses
 
 
128
        if( button.risingEdge() )
 
 
129
                inc_draw_mode = true;
 
 
133
// keep track of time
 
 
136
        // previous time and any carried-over milliseconds
 
 
137
        static unsigned long last_time = millis();
 
 
138
        static unsigned long carry = 0;
 
 
140
        // how many milliseonds have elapsed since we last checked?
 
 
141
        unsigned long next_time = millis();
 
 
142
        unsigned long delta = next_time - last_time + carry;
 
 
144
        // update the previous time and carried-over milliseconds
 
 
145
        last_time = next_time;
 
 
146
        carry = delta % 1000;
 
 
148
        // add the seconds that have passed to the time
 
 
149
        time_seconds += delta / 1000;
 
 
150
        while( time_seconds >= 60 ) {
 
 
153
                if( time_minutes >= 60 ) {
 
 
156
                        if( time_hours >= 24 )
 
 
163
// draw a segment for the test display
 
 
164
void drawNextSegment_test( bool reset )
 
 
166
        // keep track of segment
 
 
167
        static unsigned int segment = 0;
 
 
168
        if( reset ) segment = 0;
 
 
171
        // turn on inside and outside LEDs
 
 
172
        digitalWrite( 4, HIGH );
 
 
173
        digitalWrite( 13, HIGH );
 
 
175
        // display segment number in binary across in the inside LEDs,
 
 
176
        // with the LED on pin 12 showing the least-significant bit
 
 
177
        for( int a = 0; a < 8; a++ )
 
 
178
                digitalWrite( 12 - a, ( ( segment >> a ) & 1 )? HIGH : LOW );
 
 
182
// draw a segment for the time display
 
 
183
void drawNextSegment_time( bool reset )
 
 
185
        static unsigned int second = 0;
 
 
186
        static unsigned int segment = 0;
 
 
188
        // handle display reset
 
 
194
        // what needs to be drawn?
 
 
195
        bool draw_tick = !segment && second % 5 == 0;
 
 
196
        bool draw_second = !segment && second == time_seconds;
 
 
197
        bool draw_minute = !segment && second == time_minutes;
 
 
198
        bool draw_hour = !segment && second == time_hours;
 
 
201
        digitalWrite( 13, HIGH );
 
 
202
        digitalWrite( 12, draw_tick || draw_minute );
 
 
203
        for( int a = 10; a <= 11; a++ )
 
 
204
                digitalWrite( a, draw_minute || draw_second );
 
 
205
        for( int a = 4; a <= 9; a++ )
 
 
206
                digitalWrite( 10, draw_minute | draw_second || draw_hour );
 
 
209
        if( ++segment >= NUM_SECOND_SEGMENTS ) {
 
 
139
216
// draw a display segment
 
140
217
void drawNextSegment( bool reset )
 
142
 
        // keep track of segment
 
144
 
        static int segment = ( NUM_SEGMENTS - CLOCK_SHIFT ) % NUM_SEGMENTS;
 
145
 
        if( reset ) segment = ( NUM_SEGMENTS - CLOCK_SHIFT ) % NUM_SEGMENTS;
 
147
 
        static int segment = NUM_SEGMENTS - 1 - CLOCK_SHIFT;
 
148
 
        if( reset ) segment = NUM_SEGMENTS - 1 - CLOCK_SHIFT;
 
152
 
        Drawer &drawer = major_modes[ major_mode ]->get_drawer();
 
153
 
        if( reset ) drawer.draw_reset();
 
154
 
        drawer.draw( segment );
 
157
 
        if( ++segment >= NUM_SEGMENTS ) segment = 0;
 
159
 
        if( --segment < 0 ) segment = NUM_SEGMENTS - 1;
 
 
219
        static int draw_mode = 0;
 
 
221
        // handle mode switch requests
 
 
222
        if( reset && inc_draw_mode ) {
 
 
223
                inc_draw_mode = false;
 
 
230
        switch( draw_mode ) {
 
 
231
        case 0: drawNextSegment_test( reset ); break;
 
 
232
        case 1: drawNextSegment_time( reset ); break;
 
 
236
309
        // set up mode-switch button on pin 3
 
237
310
        pinMode( 3, INPUT );
 
238
 
        digitalWrite( 3, HIGH );
 
239
 
        button.add_event_at( 5, 1 );
 
240
 
        button.add_event_at( 1000, 2 );
 
241
 
        button.add_event_at( 4000, 3 );
 
 
312
        // get the time from the real-time clock
 
 
314
        RTC.get( rtc_data, true );
 
 
315
        time_hours = rtc_data[ DS1307_HR ];
 
 
316
        time_minutes = rtc_data[ DS1307_MIN ];
 
 
317
        time_seconds = rtc_data[ DS1307_SEC ];
 
244
320
        Serial.begin( 9600 );
 
246
 
        // set up major modes
 
247
 
        static ModeSwitcher mode_switcher;
 
248
 
        major_modes.push_back( &mode_switcher );
 
249
 
        major_modes[ 0 ]->activate();