/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 propeller-clock/propeller-clock.pde

  • Committer: edam
  • Date: 2011-12-02 01:18:26 UTC
  • Revision ID: edam@waxworlds.org-20111202011826-uzjcdp535mlb98sl
moved kicad files in to "project" directory, which *in future projects) can hold scematics and PCB designs

Show diffs side-by-side

added added

removed removed

1
1
/*
2
 
 * propeller-clock.ino
 
2
 * propeller-clock.pde
3
3
 *
4
 
 * Copyright (C) 2011 Tim Marston <tim@ed.am> and Dan Marston.
 
4
 * Copyright (C) 2011 Tim Marston <edam@waxworlds.org>
5
5
 *
6
6
 * This file is part of propeller-clock (hereafter referred to as "this
7
 
 * program"). See http://ed.am/dev/software/arduino/propeller-clock for more
 
7
 * program"). See http://ed.am/software/arduino/propeller-clock for more
8
8
 * information.
9
9
 *
10
10
 * This program is free software: you can redistribute it and/or modify
23
23
 
24
24
/******************************************************************************
25
25
 
26
 
Set up:
27
 
 
28
 
 * a PC fan is wired up to a 12V power supply
29
 
 
30
 
 * the fan's SENSE (tachiometer) pin connected to pin 2 on the
31
 
   arduino.
32
 
 
33
 
 * the pins 4 to 13 on the arduino should directly drive an LED (the
34
 
   LED on pin 4 is in the centre of the clock face and the LED on pin
35
 
   13 is at the outside.
36
 
 
37
 
 * if a longer hand (and a larger clock face) is desired, pin 4 can be
38
 
   used to indirectly drive a transistor which in turn drives several
39
 
   LEDs that turn on anf off in unison in the centre of the clock.
40
 
 
41
 
 * a button should be attached to pin 3 that grounds it when pressed.
42
 
 
43
 
 * A DS1307 remote clock is connected via I2C on analog pins 4 and 5.
44
 
 
45
 
Implementation details:
46
 
 
47
 
 * for a schematic, see ../project/propeller-clock.sch.
48
 
 
49
 
 * the timing of the drawing of the clock face is recalculated with
50
 
   every rotation of the propeller.
51
 
    
52
 
 * a PC fan actually sends 2 tachiometer pulses per revolution, so the
53
 
   software skips every other one. This means that the clock may
54
 
   appear upside-down if started with the propeller in the wrong
55
 
   position. You will need to experiment to dicsover the position that
56
 
   the propeller must be in when starting the clock.
57
 
    
58
 
Usage instructions:
59
 
 
60
 
 * pressing the button cycles between variations of the current
61
 
   display mode.
62
 
  
63
 
 * pressing and holding the button for a second cycles between display
64
 
   modes (e.g., analogue and digital).
65
 
 
66
 
 * pressing and holding the button for 5 seconds enters "time set"
67
 
   mode. In this mode, the following applies:
68
 
    - the field that is being set flashes
69
 
    - pressing the button increments the field currently being set
70
 
    - pressing and holding the button for a second cycles through the
71
 
      fields that can be set
72
 
    - pressing and holding the button for 5 seconds sets the time and
73
 
      exits "time set" mode
 
26
  For a schematic, see propeller-clock.sch.
 
27
 
 
28
  Set up as follows:
 
29
 
 
30
  - a PC fan is wired up to the 12V supply.
 
31
 
 
32
  - the fan's SENSE (tachiometer) pin is connected to pin 2 on the
 
33
    arduino.
 
34
 
 
35
  - the pins 4 to 13 on the arduino should directly drive an LED (the
 
36
    LED on pin 4 is in the centre of the clock face and the LED on pin
 
37
    13 is at the outside.
 
38
 
 
39
  - if a longer hand (and a larger clock face) is desired, pin 4 can
 
40
    be used to indirectly drive (via a MOSFET) multiple LEDs which
 
41
    turn on and off in unison in the centre of the clock.
 
42
 
 
43
  - a button should be attached to pin 3 that grounds it when pressed.
 
44
 
 
45
  Implementation details:
 
46
 
 
47
  - the timing of the drawing of the clock face is recalculated with
 
48
    every rotation of the propeller (for maximum update speed).
 
49
 
 
50
  - pressing the button cycles between display modes
 
51
 
 
52
  - holding down the button for 2 seconds enters "set time" mode. In
 
53
    this mode, the fan must be held still and the LEDs will indicate
 
54
    what number is being entered for each time digit. Pressing the
 
55
    button increments the current digit. Holding it down moves to the
 
56
    next digit (or leaves "set time" mode when there are no more). In
 
57
    order, the digits (with accepted values) are: hours-tens (0 to 2),
 
58
    hours-ones (0 to 9), minutes-tens (0 to 5), minutes-ones (0 to 9).
74
59
 
75
60
******************************************************************************/
76
61
 
77
62
 
78
63
#include <Bounce.h>
79
 
#include <DS1307.h>
80
 
#include <Wire.h>
81
64
 
82
65
//_____________________________________________________________________________
83
66
//                                                                         data
102
85
static bool inc_draw_mode = false;
103
86
 
104
87
// a bounce-managed button
105
 
static Bounce button( 3, 50 );
 
88
static Bounce button( 3, 5 );
106
89
 
107
90
// the time
108
91
static int time_hours = 0;
160
143
}
161
144
 
162
145
 
163
 
// turn an led on/off
164
 
void ledOn( int num, bool on )
165
 
{
166
 
        if( num < 0 || num > 9 ) return;
167
 
 
168
 
        // convert to pin no.
169
 
        num += 4;
170
 
 
171
 
        // pin 4 needs to be inverted (it's driving a PNP)
172
 
        if( num == 4 ) on = !on;
173
 
 
174
 
        digitalWrite( num, on? HIGH : LOW );
175
 
}
176
 
 
177
 
 
178
146
// draw a segment for the test display
179
147
void drawNextSegment_test( bool reset )
180
148
{
184
152
        segment++;
185
153
 
186
154
        // turn on inside and outside LEDs
187
 
        ledOn( 0, true );
188
 
        ledOn( 9, true );
 
155
        digitalWrite( 4, HIGH );
 
156
        digitalWrite( 13, HIGH );
189
157
 
190
158
        // display segment number in binary across in the inside LEDs,
191
159
        // with the LED on pin 12 showing the least-significant bit
192
160
        for( int a = 0; a < 8; a++ )
193
 
                ledOn( 8 - a, ( segment >> a ) & 1 );
 
161
                digitalWrite( 12 - a, ( ( segment >> a ) & 1 )? HIGH : LOW );
194
162
}
195
163
 
196
164
 
197
165
// draw a segment for the time display
198
166
void drawNextSegment_time( bool reset )
199
167
{
200
 
        static int second = 0;
201
 
        static int segment = 0;
 
168
        static unsigned int second = 0;
 
169
        static unsigned int segment = 0;
202
170
 
203
171
        // handle display reset
204
172
        if( reset ) {
209
177
        // what needs to be drawn?
210
178
        bool draw_tick = !segment && second % 5 == 0;
211
179
        bool draw_second = !segment && second == time_seconds;
212
 
        bool draw_minute = !segment && second == time_minutes;
213
 
        bool draw_hour = !segment && second == time_hours;
 
180
        bool draw_minute = !segment && second == time_minute;
 
181
        bool draw_hour = !segment && second == time_hour;
214
182
 
215
183
        // set the LEDs
216
 
        ledOn( 9, true );
217
 
        ledOn( 8, draw_tick || draw_minute );
218
 
        for( int a = 6; a <= 7; a++ )
219
 
                ledOn( a, draw_minute || draw_second );
220
 
        for( int a = 0; a <= 5; a++ )
221
 
                ledOn( a, draw_minute || draw_second || draw_hour );
 
184
        digitalWrite( 13, HIGH );
 
185
        digitalWrite( 12, draw_tick || draw_minute );
 
186
        for( int a = 10; a <= 11; a++ )
 
187
                digitalWrite( a, draw_minute || draw_second );
 
188
        for( int a = 4; a <= 9; a++ )
 
189
                digitalWrite( 10, draw_minute | draw_second || draw_hour );
222
190
 
223
191
        // inc position
224
192
        if( ++segment >= NUM_SECOND_SEGMENTS ) {
323
291
 
324
292
        // set up mode-switch button on pin 3
325
293
        pinMode( 3, INPUT );
326
 
        digitalWrite( 3, HIGH );
327
 
 
328
 
        // get the time from the real-time clock
329
 
        int rtc_data[ 7 ];
330
 
        RTC.get( rtc_data, true );
331
 
        time_hours = rtc_data[ DS1307_HR ];
332
 
        time_minutes = rtc_data[ DS1307_MIN ];
333
 
        time_seconds = rtc_data[ DS1307_SEC ];
334
294
 
335
295
        // serial comms
336
296
        Serial.begin( 9600 );