Test of Embedded Artists LPCXpresso baseboard ethernet, SD card, audio and OLED display facilities. The program displays the day, date and time on the baseboard OLED and sounds the Big Ben chimes on the hour and quarter hour. On initial startup the program checks that the mbed clock is set and that the chime wav files can be accessed on the SD card. If not it asks to be connected to the internet to obtain the current time and to download the wav files to the SD card.

Dependencies:   EthernetNetIf NTPClient_NetServices mbed EAOLED

main.cpp

Committer:
tom_coxon
Date:
2010-08-14
Revision:
0:f61e8db0570d

File content as of revision 0:f61e8db0570d:

/*  EA_BigBen

 Just for fun this turns the Embedded Artists LPCXpresso baseboard into a Big Ben substitute.

 Well OK it is a little smaller and the sound is a little tinnier than the real thing but it works.

 This pulls together the following test programs for the Embedded Artists LPCXpresso baseboard:

 EA_InternetClock (now superseded by this program)
 EA_WavPlayer
 EA_DownloadToSD

 The program displays the day, date and time on the baseboard OLED and sounds the Big Ben chimes
 on the hour and quarter hour.

 On initial startup the program checks that the mbed clock is set and that the wav files can be accessed
 on the SD card.  If not it asks to be connected to the internet to obtain the current time and to download
 the wav files to the SD card.

 The wav file player works with uncompressed wav files with 8 or 16 bit sample sizes.

 Setup of the baseboard:

 Please set all jumpers on board to the default case except for
 the following:

 Audio setup:

 1. Insert a jumper in J31 to connect signal PIO1_2 to the low
 pass filer as described in section 4.7.2. of base board users
 guide.

 2. Insert three jumpers in J33 to connect PIO3_0, PIO3_1 and
 PIO3_2 to control the amplifier as described in section 4.8
 of base board users guide.

 3. Insert a jumper in J32 and remove any from J34 to use the
 internal speaker as described in section 4.8
 of base board users guide.

 SD Card setup:

 4. Insert all five jumpers in J39 as described in section 4.3.3
 of base board users guide.

 5. Remove jumper marked "A" in J55 In order to connect PIO1_11
 to CS signal of J40 (the SPI-SSEL signal)  as described in section 4.3.3
 of base board users guide.

 OLED setup:

 1. The LCPXpresso board does not provide the data/command signal to the mbed.
 To provide this signal please connect a jumper wire from PIO2_7 of baseboard mbed socket
 (empty 2nd hole below mbed pin 21) to  to PIO2_5 (on J6 right side ninth hole from bottom).

*/

#include "mbed.h"
#include "wavplayer.h"
#include "SDHCFileSystem.h"
#include "EthernetNetIf.h"
#include "NTPClient.h"
#include "EAOLED.h"
#include "HTTPClient.h"

int debug = 0;

EthernetNetIf eth;
NTPClient ntp;
HTTPClient http;

int ethernetUp = 0;//flag ethernet status 1 = up 0 = down

WavPlayer myWavPlayer;

EAOLED oled(p5, p21, p7, p8, p25); // mosi, dnc, sclk, cs, power

SDFileSystem sd(p5, p6, p7, p24, "sd");//mosi, miso, sclk, cs, name

DigitalOut led1(LED1);
//DigitalOut led2(LED2);
//DigitalOut led3(LED3);
DigitalOut led4(LED4);

Ticker secTicker;
Ticker blink;

int hour, minute, second, bongCount;

char day[12];
char dmy[12];
char hms[12];


void startUpMsgToOLED() {
    oled.cls();
    oled.locate(0,1);
    oled.printf(" mbed clock\n");
    oled.locate(0,3);
    oled.printf(" connect\n");
    oled.locate(0,5);
    oled.printf(" ethernet\n");
    oled.locate(0,7);
    oled.printf(" to start..\n");
}

//sets up ethernet connection only once
void ethernetSetup() {
    if (!ethernetUp) {
        printf("Connecting to network ...\r\n");
        EthernetErr ethErr = eth.setup();
        if (ethErr) {
            printf("Error %d in setup.\r\n", ethErr);
        }
        printf("Network interface is up\r\n");
        ethernetUp = 1;
    }
}

//blinks led4 during download
void blinkLED4() {
    led4 = !led4;
}

void downloadFileToSD(char *url, char *path) {
    oled.cls();
    oled.locate(0,1);
    oled.printf("Downloading\n");
    oled.locate(0,3);
    oled.printf(" Wav files\n");
    oled.locate(0,5);
    oled.printf("Please wait\n");

    HTTPFile httpfile(path);

    printf("Downloading to ");
    printf("%s", path);
    printf(" please wait ... \r\n");

    blink.attach(& blinkLED4, 0.5);

    HTTPResult result = http.get(url, &httpfile);

    if (result == HTTP_OK) {
        printf("File downloaded OK\r\n");
    } else {
        printf("Error during download %d\r\n", result);
    }

    blink.detach();

    led4 = 0;
}

void downloadFiles() {

    ethernetSetup();

    printf("\r\n----------- Starting file download ------------\r\n");

    downloadFileToSD("http://homepage.ntlworld.com/green_bean/mbed/bong.wav", "/sd/bong.wav" );
    downloadFileToSD("http://homepage.ntlworld.com/green_bean/mbed/quarter.wav", "/sd/quarter.wav" );
    downloadFileToSD("http://homepage.ntlworld.com/green_bean/mbed/hour.wav", "/sd/hour.wav" );

    printf("-------------- Files downloaded ------------\r\n");

}

void checkChimeWavFilesExist() {
    int filesExist = 1;//default exist
    FILE *fp1 = fopen("/sd/bong.wav", "rb");
    if (fp1 == NULL) {
        filesExist = 0;
    } else fclose(fp1);
    FILE *fp2 = fopen("/sd/quarter.wav", "rb");
    if (fp2 == NULL) {
        filesExist = 0;
    } else fclose(fp2);
    FILE *fp3 = fopen("/sd/hour.wav", "rb");
    if (fp3 == NULL) {
        filesExist = 0;
    } else fclose(fp3);

    if (!filesExist) downloadFiles();
}

void setmbedClock() {

    startUpMsgToOLED();
    printf("Setting mbed clock\r\n");

    ethernetSetup();

    printf("Connecting to time server...\r\n");

    Host server(IpAddr(), 123, "0.uk.pool.ntp.org");
    ntp.setTime(server);

    printf("Time updated\r\n");
    oled.cls();
}

void updateTimeDisplay() {

    time_t seconds;
    seconds = time(NULL);

    struct tm *timeStruct = localtime(&seconds);

    if (timeStruct->tm_isdst) {//daylight savings is on add one hour
        seconds+=3600;
        tm *timeStruct = localtime(&seconds);
    }

    strftime(day,sizeof(day)," %A ", timeStruct);//localtime(&seconds));
    strftime(dmy,sizeof(dmy),"%d/%m/%Y", timeStruct);//localtime(&seconds));
    strftime(hms,sizeof(hms),"%H:%M:%S", timeStruct);//localtime(&seconds));

    //global hour, minute & second used in main() to set chimes
    hour = timeStruct->tm_hour;
    minute = timeStruct->tm_min;
    second = timeStruct->tm_sec;

    if (debug == 1) printf("%s %s %s\r\n", hms,day,dmy);

    oled.locate((12-strlen(day))/2,1);
    oled.printf("%s", day);
    oled.locate((12-strlen(hms))/2,4);
    oled.printf("%s", hms);
    oled.locate((12-strlen(dmy))/2,7);
    oled.printf("%s", dmy);

}

void  checkIfChimesRequired() {

    //check if time to sound hour
    if (minute == 59 && second == 34) {
        second ++; // ensure does not reenter this before updateTime
        secTicker.detach();
        myWavPlayer.play_wave("/sd/hour.wav");
        secTicker.attach(& updateTimeDisplay, 1);
        bongCount = (hour % 12) + 1; // No. bongs to count the hours
        //check if time to sound quarter hour
    } else if (minute % 15 == 0 && second == 0 ) { // will not strike on hour as caught above
        second ++; // ensure does not reenter this before updateTime
        secTicker.detach();
        myWavPlayer.play_wave("/sd/quarter.wav");
        secTicker.attach(& updateTimeDisplay, 1);
        //check if time for next hour bong
    } else if (bongCount > 0 && second % 5 == 0) {
        second ++; // ensure does not reenter this before updateTime
        secTicker.detach();
        myWavPlayer.play_wave("/sd/bong.wav");
        bongCount --;
        secTicker.attach(& updateTimeDisplay, 1);
    }
}

int main() {

    printf("\r\n------ Starting Big Ben -------\r\n");

    startUpMsgToOLED();

    //Check if chime wav files are on SD card if not download them
    checkChimeWavFilesExist();

    //Check if clock already set if < year 1990 assume needs setting
    time_t seconds = time(NULL);
    if (seconds < 630720000) {
        setmbedClock();
    }
    oled.cls();


    // starting ticker to update time display once per second
    secTicker.attach(& updateTimeDisplay, 1);

    // On startup the quarter hour chime will play to ensure the SD card can be read
    // if you do not want this to happen remove the comment from the following line
    //  second = 1; // so does not sound the quarter hour on first start

    while (1) {

        checkIfChimesRequired();
        
        wait(0.1);
    }

}