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.

OLED160G1/OLED160G1.h

Committer:
star297
Date:
2013-03-08
Revision:
1:4f254cca2bac
Parent:
0:e3f7b0fd072e

File content as of revision 1:4f254cca2bac:

/**
 * mbed library for 4D Systems uOLED-160-G1
 *
 */

#ifndef _OLED160G1_H_
#define _OLED160G1_H_


#define OLED_BAUDRATE                       256000  // 300 baud to 256kbaud supported (256k not always stable?)
#define OLED_INIT_DELAY                     1100    // milliseconds

// Initialisation routine
#define OLED_DETECT_BAUDRATE                0x55

// Drawing routines
#define OLED_CLEAR                          0x45
#define OLED_BKGCOLOR                       0x42
#define OLED_COPYPASTE                      0x63
#define OLED_PEN_SIZE                       0x70

// Graphics
#define OLED_LINE                           0x4C
#define OLED_CIRCLE                         0x43
#define OLED_CIRCLEFILL                     0x69
#define OLED_PUTPIXEL                       0x50
#define OLED_READPIXEL                      0x52
#define OLED_RECTANGLE                      0x72

// Text properties
#define OLED_TEXT                           0x73
#define OLED_SETFONTSIZE                    0x46
#define OLED_FONT5X7                        0x00
#define OLED_FONT8X8                        0x01
#define OLED_FONT8X12                       0x02
#define OLED_TEXTFORMATED                   0x54
#define OLED_SET_TEXT_BACKGROUND_TYPE       0x4F
#define OLED_SET_BACKGROUND_COLOR           0x42
#define OLED_SET_TEXT_TRANSPARENT           0x00
#define OLED_SET_TEXT_OPAQUE                0x01

// OLED Control
#define OLED_COMMAND_CONTROL                0x59
#define OLED_COMMAND_DISPLAY                0x01
#define OLED_COMMAND_CONTRAST               0x02
#define OLED_COMMAND_POWER                  0x03

// Responses
#define OLED_ACK                            0x06  // Ok
#define OLED_NAK                            0x15  // Error

// Colours
#define OLED_WHITE                          0xFFFF
#define OLED_BLACK                          0x0000
#define OLED_BLUE                           0xA6BF
#define OLED_RED                            0xF800
#define OLED_GREEN                          0x2500

#define red_min 0//150
#define red_max 255
#define blue_min 0//185
#define blue_max 255
#define green_min 0//195
#define green_max 255


class OLED160G1 : public Stream {
public:

    /**
     * Default constructor.
     */
    OLED160G1(PinName serialTx, PinName serialRx, PinName resetPin);
    
    /**
     * Reset the display using the reset pin (the reset pin is active-low).
     */
    void resetDisplay();

    /**
     * Initialise OLED display.
     */
    void init();

    /**
     * Processes responses (ACK or NAK) from the OLED. A new command cannot be sent to the OLED until a NAK is received, so
     * this function waits for the minimum time needed.
     */
    void getResponse();

    /**
     * Clear the OLED screen.
     */
    void eraseScreen();
    
    /**
     * Calculate 16-bit value from RGB (0 to 63, 565 format)
     */
    int toRGB(int red, int green, int blue);
    
    /**
     * 
     */
    void drawPixel(char x, char y, int color);
    
    /**
     * 
     */
    void drawLine(char x1, char y1, char x2, char y2, int color);
    
    /**
     * 
     */
    void drawRectangle(char x, char y, char width, char height, int color);
    
    /**
     * 
     */
    void drawCircle(char x, char y, char radius, int color);
    
    /**
     * Set font size, for use with printf() or OLED_DrawSingleChar(); all other functions override this setting.
     *
     * @param : fontSize can be: OLED_FONT5X7, OLED_FONT8X8, or OLED_FONT8X12
     */
    void setFontSize(char fontSize);
    
    /**
     * Set font color, for use with printf(); all other functions override this setting.
     */
    void setFontColor(int fontColor);
    
    /**
     * Set the "pen size".
     *
     * @param penSize : 0 to draw solid objects; 1 to draw wireframe objects.
     */
    void setPenSize(char penSize);
    
    /**
     * Set whether or not text is drawn with an opaque or transparent background.
     *
     * @param : textBackgroundType can be OLED_SET_TEXT_TRANSPARENT or OLED_SET_TEXT_OPAQUE
     */
    void setTextBackgroundType(char textBackgroundType);
    
    /**
     * 
     */
    void setBackgroundColor(int color);
    
    /**
     * 
     */
    void drawText(char column, char row, char font_size, char *mytext, int color);
    
    /**
     * Draw a single ASCII character at the specified location.
     */
    void drawSingleChar(char column, char row, char theChar, int color);
    
    /**
     * Display control functions, such as display ON/OFF, contrast and power-up/power-down.
     *
     * @param value : can be 0x00 to 0x0F is mode is OLED_COMMAND_CONTRAST. Default contrast value is 0x08.
     */
    void displayControl(char mode, char value);
    
    /**
     * 
     */
    char getPenSize();
    
    /**
     * Get number of text rows
     */
    int rows(); //TODO: must depend on font size
    
    /**
     * Get number of text columns
     */
    int columns();
    
    /**
     * Set text cursor location
     */
    virtual void locate(int column, int row);
    
    /**
     * 
     */
    int lastCount;
    
    /**
     * 
     */
    int NAKCount;
    
protected:
    virtual int _putc(int value);
    virtual int _getc();
    
    /**
     * Text cursor column number
     */
    short _column;
    
    /**
     * Text cursor row number
     */
    short _row;
    
    char _fontSize;
    char _penSize;
    int _fontColor;
    
private:
    Serial s;
    DigitalOut  reset;
};

#endif