Freescale KL25Z DCF77 Atomic clock using 4D Systems uOLED160 OLED display. Displays a graphical display of DCF time signal bit build and sets the local clock time. The main signal timing is achieved by using a Ticker ISR that looks at the DCF signal input every 50mS this also produces the seconds on the local clock incase of signal errors or no signal. Many thanks to Lynton Towler for the idea of this part of the code and Wim who helped me convert it from an Arduino program. The Parity code was from Hans program that works. This dsiplay is considerably better that the nokia LCD.

Dependencies:   mbed

/media/uploads/star297/20130308_220041.jpg

Added RTC clock to top of display that is synchronised to the DCF clock on the middle right of display. Both clocks will continue to run with no signal and will synchronise to DCF when signal returns. The RTC clock is set to the DCF time less 3600 seconds that gives UK (GMT) time. Any multiples of 3600 seconds (1 hour) can be added or subtracted to give the correct RTC time depending on european location (see code line 349). The DCF clock will reset on power down however if the back up cell is fitted the RTC clock should continue to keep time and will display correct time when powered up again, I have not checked this yet. The DCF clock will reset and will synchronise within 2 minutes when power is supplied.

/media/uploads/star297/20130308_220102.jpg

The DCF signal is sampled every 50mS each second that is called by the Interrupt Sub Routine (myISR). All code must be able to complete within 50mS otherwise it may cause the processor to 'hang' particularly durring Oled print functions that tend to be slow (even at 256k baud). So the trck here is to run parts of the code at different 50mS segments of the interrupt counter.

The program starts by looking for the 59th second pulse that is not transmitted, sample50 and sample150 will be zero at this point. When this arrives the interrupt counter is synchonised and the sample150 pulses are counted as '1's and '0's. The time and DCF bit map start on the 21st pulse with the last pulse counted at 58 seconds when partity is checked. If the parity is correct and the time variables are within limits as set in the partity_check subroutine, the DCF clock is set and then the RTC the process then repeats continuously alternating the bit map colour every DCF frame. If there is an error in the signal caused by a high level of noise or missing 'bits' the counters will restart looking for the 59th pulse.

This method of sampling has proved to be far more stable against noise in the DCF signal and will continue to run where as pulse width measuring method I have tried from other program examples requires an almost noise free signal.

I'm affraid the code is pretty poor and sure it could be much improved but it does work rather well.

I have made further checks on this board and have found that unlike the Mbed LPC1768 the coin cell is not for RTC back up. This battery is to run the CPU, RGB led and accelerometer and consumes around 15mA.

The other issue becomes apparent when the board is run from the coin cell and without power from the USB connector. In this case the SDA CPU is in 'sleep' mode that means the RTC clock signal is not generated and fed to the main CPU that results in the RTC freezing.

In conclusion the KL25Z would not be viable for general low power RTC clock functions that require the RTC to keep time when shut down.

Committer:
star297
Date:
Fri Mar 08 21:11:11 2013 +0000
Revision:
1:4f254cca2bac
Parent:
0:e3f7b0fd072e
RTC function added + corrected Leap year code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
star297 0:e3f7b0fd072e 1 /**
star297 0:e3f7b0fd072e 2 * mbed library for 4D Systems uOLED-160-G1
star297 0:e3f7b0fd072e 3 *
star297 0:e3f7b0fd072e 4 */
star297 0:e3f7b0fd072e 5
star297 0:e3f7b0fd072e 6 #ifndef _OLED160G1_H_
star297 0:e3f7b0fd072e 7 #define _OLED160G1_H_
star297 0:e3f7b0fd072e 8
star297 0:e3f7b0fd072e 9
star297 0:e3f7b0fd072e 10 #define OLED_BAUDRATE 256000 // 300 baud to 256kbaud supported (256k not always stable?)
star297 0:e3f7b0fd072e 11 #define OLED_INIT_DELAY 1100 // milliseconds
star297 0:e3f7b0fd072e 12
star297 0:e3f7b0fd072e 13 // Initialisation routine
star297 0:e3f7b0fd072e 14 #define OLED_DETECT_BAUDRATE 0x55
star297 0:e3f7b0fd072e 15
star297 0:e3f7b0fd072e 16 // Drawing routines
star297 0:e3f7b0fd072e 17 #define OLED_CLEAR 0x45
star297 0:e3f7b0fd072e 18 #define OLED_BKGCOLOR 0x42
star297 0:e3f7b0fd072e 19 #define OLED_COPYPASTE 0x63
star297 0:e3f7b0fd072e 20 #define OLED_PEN_SIZE 0x70
star297 0:e3f7b0fd072e 21
star297 0:e3f7b0fd072e 22 // Graphics
star297 0:e3f7b0fd072e 23 #define OLED_LINE 0x4C
star297 0:e3f7b0fd072e 24 #define OLED_CIRCLE 0x43
star297 0:e3f7b0fd072e 25 #define OLED_CIRCLEFILL 0x69
star297 0:e3f7b0fd072e 26 #define OLED_PUTPIXEL 0x50
star297 0:e3f7b0fd072e 27 #define OLED_READPIXEL 0x52
star297 0:e3f7b0fd072e 28 #define OLED_RECTANGLE 0x72
star297 0:e3f7b0fd072e 29
star297 0:e3f7b0fd072e 30 // Text properties
star297 0:e3f7b0fd072e 31 #define OLED_TEXT 0x73
star297 0:e3f7b0fd072e 32 #define OLED_SETFONTSIZE 0x46
star297 0:e3f7b0fd072e 33 #define OLED_FONT5X7 0x00
star297 0:e3f7b0fd072e 34 #define OLED_FONT8X8 0x01
star297 0:e3f7b0fd072e 35 #define OLED_FONT8X12 0x02
star297 0:e3f7b0fd072e 36 #define OLED_TEXTFORMATED 0x54
star297 0:e3f7b0fd072e 37 #define OLED_SET_TEXT_BACKGROUND_TYPE 0x4F
star297 0:e3f7b0fd072e 38 #define OLED_SET_BACKGROUND_COLOR 0x42
star297 0:e3f7b0fd072e 39 #define OLED_SET_TEXT_TRANSPARENT 0x00
star297 0:e3f7b0fd072e 40 #define OLED_SET_TEXT_OPAQUE 0x01
star297 0:e3f7b0fd072e 41
star297 0:e3f7b0fd072e 42 // OLED Control
star297 0:e3f7b0fd072e 43 #define OLED_COMMAND_CONTROL 0x59
star297 0:e3f7b0fd072e 44 #define OLED_COMMAND_DISPLAY 0x01
star297 0:e3f7b0fd072e 45 #define OLED_COMMAND_CONTRAST 0x02
star297 0:e3f7b0fd072e 46 #define OLED_COMMAND_POWER 0x03
star297 0:e3f7b0fd072e 47
star297 0:e3f7b0fd072e 48 // Responses
star297 0:e3f7b0fd072e 49 #define OLED_ACK 0x06 // Ok
star297 0:e3f7b0fd072e 50 #define OLED_NAK 0x15 // Error
star297 0:e3f7b0fd072e 51
star297 0:e3f7b0fd072e 52 // Colours
star297 0:e3f7b0fd072e 53 #define OLED_WHITE 0xFFFF
star297 0:e3f7b0fd072e 54 #define OLED_BLACK 0x0000
star297 0:e3f7b0fd072e 55 #define OLED_BLUE 0xA6BF
star297 0:e3f7b0fd072e 56 #define OLED_RED 0xF800
star297 0:e3f7b0fd072e 57 #define OLED_GREEN 0x2500
star297 0:e3f7b0fd072e 58
star297 0:e3f7b0fd072e 59 #define red_min 0//150
star297 0:e3f7b0fd072e 60 #define red_max 255
star297 0:e3f7b0fd072e 61 #define blue_min 0//185
star297 0:e3f7b0fd072e 62 #define blue_max 255
star297 0:e3f7b0fd072e 63 #define green_min 0//195
star297 0:e3f7b0fd072e 64 #define green_max 255
star297 0:e3f7b0fd072e 65
star297 0:e3f7b0fd072e 66
star297 0:e3f7b0fd072e 67 class OLED160G1 : public Stream {
star297 0:e3f7b0fd072e 68 public:
star297 0:e3f7b0fd072e 69
star297 0:e3f7b0fd072e 70 /**
star297 0:e3f7b0fd072e 71 * Default constructor.
star297 0:e3f7b0fd072e 72 */
star297 0:e3f7b0fd072e 73 OLED160G1(PinName serialTx, PinName serialRx, PinName resetPin);
star297 0:e3f7b0fd072e 74
star297 0:e3f7b0fd072e 75 /**
star297 0:e3f7b0fd072e 76 * Reset the display using the reset pin (the reset pin is active-low).
star297 0:e3f7b0fd072e 77 */
star297 0:e3f7b0fd072e 78 void resetDisplay();
star297 0:e3f7b0fd072e 79
star297 0:e3f7b0fd072e 80 /**
star297 0:e3f7b0fd072e 81 * Initialise OLED display.
star297 0:e3f7b0fd072e 82 */
star297 0:e3f7b0fd072e 83 void init();
star297 0:e3f7b0fd072e 84
star297 0:e3f7b0fd072e 85 /**
star297 0:e3f7b0fd072e 86 * Processes responses (ACK or NAK) from the OLED. A new command cannot be sent to the OLED until a NAK is received, so
star297 0:e3f7b0fd072e 87 * this function waits for the minimum time needed.
star297 0:e3f7b0fd072e 88 */
star297 0:e3f7b0fd072e 89 void getResponse();
star297 0:e3f7b0fd072e 90
star297 0:e3f7b0fd072e 91 /**
star297 0:e3f7b0fd072e 92 * Clear the OLED screen.
star297 0:e3f7b0fd072e 93 */
star297 0:e3f7b0fd072e 94 void eraseScreen();
star297 0:e3f7b0fd072e 95
star297 0:e3f7b0fd072e 96 /**
star297 0:e3f7b0fd072e 97 * Calculate 16-bit value from RGB (0 to 63, 565 format)
star297 0:e3f7b0fd072e 98 */
star297 0:e3f7b0fd072e 99 int toRGB(int red, int green, int blue);
star297 0:e3f7b0fd072e 100
star297 0:e3f7b0fd072e 101 /**
star297 0:e3f7b0fd072e 102 *
star297 0:e3f7b0fd072e 103 */
star297 0:e3f7b0fd072e 104 void drawPixel(char x, char y, int color);
star297 0:e3f7b0fd072e 105
star297 0:e3f7b0fd072e 106 /**
star297 0:e3f7b0fd072e 107 *
star297 0:e3f7b0fd072e 108 */
star297 0:e3f7b0fd072e 109 void drawLine(char x1, char y1, char x2, char y2, int color);
star297 0:e3f7b0fd072e 110
star297 0:e3f7b0fd072e 111 /**
star297 0:e3f7b0fd072e 112 *
star297 0:e3f7b0fd072e 113 */
star297 0:e3f7b0fd072e 114 void drawRectangle(char x, char y, char width, char height, int color);
star297 0:e3f7b0fd072e 115
star297 0:e3f7b0fd072e 116 /**
star297 0:e3f7b0fd072e 117 *
star297 0:e3f7b0fd072e 118 */
star297 0:e3f7b0fd072e 119 void drawCircle(char x, char y, char radius, int color);
star297 0:e3f7b0fd072e 120
star297 0:e3f7b0fd072e 121 /**
star297 0:e3f7b0fd072e 122 * Set font size, for use with printf() or OLED_DrawSingleChar(); all other functions override this setting.
star297 0:e3f7b0fd072e 123 *
star297 0:e3f7b0fd072e 124 * @param : fontSize can be: OLED_FONT5X7, OLED_FONT8X8, or OLED_FONT8X12
star297 0:e3f7b0fd072e 125 */
star297 0:e3f7b0fd072e 126 void setFontSize(char fontSize);
star297 0:e3f7b0fd072e 127
star297 0:e3f7b0fd072e 128 /**
star297 0:e3f7b0fd072e 129 * Set font color, for use with printf(); all other functions override this setting.
star297 0:e3f7b0fd072e 130 */
star297 0:e3f7b0fd072e 131 void setFontColor(int fontColor);
star297 0:e3f7b0fd072e 132
star297 0:e3f7b0fd072e 133 /**
star297 0:e3f7b0fd072e 134 * Set the "pen size".
star297 0:e3f7b0fd072e 135 *
star297 0:e3f7b0fd072e 136 * @param penSize : 0 to draw solid objects; 1 to draw wireframe objects.
star297 0:e3f7b0fd072e 137 */
star297 0:e3f7b0fd072e 138 void setPenSize(char penSize);
star297 0:e3f7b0fd072e 139
star297 0:e3f7b0fd072e 140 /**
star297 0:e3f7b0fd072e 141 * Set whether or not text is drawn with an opaque or transparent background.
star297 0:e3f7b0fd072e 142 *
star297 0:e3f7b0fd072e 143 * @param : textBackgroundType can be OLED_SET_TEXT_TRANSPARENT or OLED_SET_TEXT_OPAQUE
star297 0:e3f7b0fd072e 144 */
star297 0:e3f7b0fd072e 145 void setTextBackgroundType(char textBackgroundType);
star297 0:e3f7b0fd072e 146
star297 0:e3f7b0fd072e 147 /**
star297 0:e3f7b0fd072e 148 *
star297 0:e3f7b0fd072e 149 */
star297 0:e3f7b0fd072e 150 void setBackgroundColor(int color);
star297 0:e3f7b0fd072e 151
star297 0:e3f7b0fd072e 152 /**
star297 0:e3f7b0fd072e 153 *
star297 0:e3f7b0fd072e 154 */
star297 0:e3f7b0fd072e 155 void drawText(char column, char row, char font_size, char *mytext, int color);
star297 0:e3f7b0fd072e 156
star297 0:e3f7b0fd072e 157 /**
star297 0:e3f7b0fd072e 158 * Draw a single ASCII character at the specified location.
star297 0:e3f7b0fd072e 159 */
star297 0:e3f7b0fd072e 160 void drawSingleChar(char column, char row, char theChar, int color);
star297 0:e3f7b0fd072e 161
star297 0:e3f7b0fd072e 162 /**
star297 0:e3f7b0fd072e 163 * Display control functions, such as display ON/OFF, contrast and power-up/power-down.
star297 0:e3f7b0fd072e 164 *
star297 0:e3f7b0fd072e 165 * @param value : can be 0x00 to 0x0F is mode is OLED_COMMAND_CONTRAST. Default contrast value is 0x08.
star297 0:e3f7b0fd072e 166 */
star297 0:e3f7b0fd072e 167 void displayControl(char mode, char value);
star297 0:e3f7b0fd072e 168
star297 0:e3f7b0fd072e 169 /**
star297 0:e3f7b0fd072e 170 *
star297 0:e3f7b0fd072e 171 */
star297 0:e3f7b0fd072e 172 char getPenSize();
star297 0:e3f7b0fd072e 173
star297 0:e3f7b0fd072e 174 /**
star297 0:e3f7b0fd072e 175 * Get number of text rows
star297 0:e3f7b0fd072e 176 */
star297 0:e3f7b0fd072e 177 int rows(); //TODO: must depend on font size
star297 0:e3f7b0fd072e 178
star297 0:e3f7b0fd072e 179 /**
star297 0:e3f7b0fd072e 180 * Get number of text columns
star297 0:e3f7b0fd072e 181 */
star297 0:e3f7b0fd072e 182 int columns();
star297 0:e3f7b0fd072e 183
star297 0:e3f7b0fd072e 184 /**
star297 0:e3f7b0fd072e 185 * Set text cursor location
star297 0:e3f7b0fd072e 186 */
star297 0:e3f7b0fd072e 187 virtual void locate(int column, int row);
star297 0:e3f7b0fd072e 188
star297 0:e3f7b0fd072e 189 /**
star297 0:e3f7b0fd072e 190 *
star297 0:e3f7b0fd072e 191 */
star297 0:e3f7b0fd072e 192 int lastCount;
star297 0:e3f7b0fd072e 193
star297 0:e3f7b0fd072e 194 /**
star297 0:e3f7b0fd072e 195 *
star297 0:e3f7b0fd072e 196 */
star297 0:e3f7b0fd072e 197 int NAKCount;
star297 0:e3f7b0fd072e 198
star297 0:e3f7b0fd072e 199 protected:
star297 0:e3f7b0fd072e 200 virtual int _putc(int value);
star297 0:e3f7b0fd072e 201 virtual int _getc();
star297 0:e3f7b0fd072e 202
star297 0:e3f7b0fd072e 203 /**
star297 0:e3f7b0fd072e 204 * Text cursor column number
star297 0:e3f7b0fd072e 205 */
star297 0:e3f7b0fd072e 206 short _column;
star297 0:e3f7b0fd072e 207
star297 0:e3f7b0fd072e 208 /**
star297 0:e3f7b0fd072e 209 * Text cursor row number
star297 0:e3f7b0fd072e 210 */
star297 0:e3f7b0fd072e 211 short _row;
star297 0:e3f7b0fd072e 212
star297 0:e3f7b0fd072e 213 char _fontSize;
star297 0:e3f7b0fd072e 214 char _penSize;
star297 0:e3f7b0fd072e 215 int _fontColor;
star297 0:e3f7b0fd072e 216
star297 0:e3f7b0fd072e 217 private:
star297 0:e3f7b0fd072e 218 Serial s;
star297 0:e3f7b0fd072e 219 DigitalOut reset;
star297 0:e3f7b0fd072e 220 };
star297 0:e3f7b0fd072e 221
star297 0:e3f7b0fd072e 222 #endif