1
/* -*- mode: c++; compile-command: "BOARD=pro5v make"; -*- */
4
* Copyright (C) 2011 Tim Marston <edam@waxworlds.org>
5
* Copyright (C) 2011 Tim Marston <tim@ed.am> and Dan Marston.
6
7
* This file is part of propeller-clock (hereafter referred to as "this
7
* program"). See http://ed.am/software/arduino/propeller-clock for more
8
* program"). See http://ed.am/dev/software/arduino/propeller-clock for more
10
11
* This program is free software: you can redistribute it and/or modify
35
36
13 is at the outside.
37
38
* if a longer hand (and a larger clock face) is desired, pin 4 can be
38
used to indirectly drive (via a MOSFET) multiple LEDs which turn on
39
and off in unison in the centre of the clock.
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.
41
42
* a button should be attached to pin 3 that grounds it when pressed.
44
* A DS1307 remote clock is connected via I2C on analog pins 4 and 5.
43
46
Implementation details:
45
* for a schematic, see project/propeller-clock.sch.
48
* for a schematic, see ../project/propeller-clock.sch.
47
50
* the timing of the drawing of the clock face is recalculated with
48
51
every rotation of the propeller.
170
// turn an led on/off
171
void ledOn( int num, bool on )
173
if( num < 0 || num > 9 ) return;
175
// convert to pin no.
178
// pin 4 needs to be inverted (it's driving a PNP)
179
if( num == 4 ) on = !on;
181
digitalWrite( num, on? HIGH : LOW );
158
185
// draw a segment for the test display
159
void drawNextSegment_test( bool reset )
186
void drawNextSegment_test( int segment )
161
// keep track of segment
162
static unsigned int segment = 0;
163
if( reset ) segment = 0;
166
// turn on inside and outside LEDs
167
digitalWrite( 4, HIGH );
168
digitalWrite( 13, HIGH );
188
// turn on outside LEDs
170
191
// display segment number in binary across in the inside LEDs,
171
192
// with the LED on pin 12 showing the least-significant bit
172
for( int a = 0; a < 8; a++ )
173
digitalWrite( 12 - a, ( ( segment >> a ) & 1 )? HIGH : LOW );
193
for( int a = 0; a < 9; a++ )
194
ledOn( 8 - a, ( segment >> a ) & 1 );
177
198
// draw a segment for the time display
178
void drawNextSegment_time( bool reset )
199
void drawNextSegment_time( int segment )
180
static unsigned int second = 0;
181
static unsigned int segment = 0;
183
// handle display reset
201
int second = segment / NUM_SECOND_SEGMENTS;
202
int second_segment = segment % NUM_SECOND_SEGMENTS;
189
204
// what needs to be drawn?
190
bool draw_tick = !segment && second % 5 == 0;
191
bool draw_second = !segment && second == time_seconds;
192
bool draw_minute = !segment && second == time_minute;
193
bool draw_hour = !segment && second == time_hour;
205
bool draw_tick = ( !second_segment && second % 5 == 0 && second ) ||
206
( second == 0 && second_segment == 1 ) ||
207
( second == 59 && second_segment == NUM_SECOND_SEGMENTS - 1 );
208
bool draw_second = !second_segment && second == time_seconds;
209
bool draw_minute = !second_segment && second == time_minutes;
210
bool draw_hour = segment == time_hours * 5 * NUM_SECOND_SEGMENTS +
211
( 5 * NUM_SECOND_SEGMENTS * time_minutes / 60 );
196
digitalWrite( 13, HIGH );
197
digitalWrite( 12, draw_tick || draw_minute );
198
for( int a = 10; a <= 11; a++ )
199
digitalWrite( a, draw_minute || draw_second );
200
for( int a = 4; a <= 9; a++ )
201
digitalWrite( 10, draw_minute | draw_second || draw_hour );
204
if( ++segment >= NUM_SECOND_SEGMENTS ) {
215
ledOn( 8, draw_tick || draw_second );
216
for( int a = 6; a <= 7; a++ )
217
ledOn( a, draw_minute || draw_second );
218
for( int a = 0; a <= 5; a++ )
219
ledOn( a, draw_minute || draw_second || draw_hour );