iModela(iM-01) de sakusei sita PCB no kitchenTimer wo clock ni henko sita monodesu.

Dependencies:   SevenSegLed SwDigital mbed Sound

main.cpp

Committer:
suupen
Date:
2012-04-22
Revision:
1:fe97b047f96b
Parent:
0:b7cdbc649bd3

File content as of revision 1:fe97b047f96b:

//#define debug
//===========================================================================
// mbed seven segment LED PCB board example program
//
// 24h display clock
//
// V1.0 120402
// V2.0 120422 : melody and chime no henko. hyoji no kaizen
// 
// <schematic>
// 1.seven segment numeric LED Display : OSL40562-LR
//       http://akizukidenshi.com/download/OSL40562-LR.pdf
//
//  OSL40562-LR                           Resister        mbed
//  Pin No     Function                   [ohm]           Function
//  ---------------------------------------------------------------------------
//   1         segment E                   200            P13 
//   2         segment D                   200            P12
//   3         segment Dp                  200            P11
//   4         segment C                   200            p10
//   5         segment G                   200            P9
//   6         common  4                   -              P8  
//   7         segment B                   200            P5
//   8         common  3                   -              P6 
//   9         common  2                   -              p7
//  10         segment F                   200            p18
//  11         segment A                   200            P19 
//  12         common  1                    -             p20
// 
// 2.sound speaker
//                                               /
//   mbed                 --------------      --/
//   p21(pwmOut)     -----| R:0[ohm]   |-----|  |  speaker(8[ohm])
//                        --------------     |  |
//                                           |  |
//   p22(DigitalOut) ------------------------|  |
//                                            --\
//                                               \
// 3.sw
//                sw6(left sw)
//                ---- 
//    p25 --------o  o----------- GND
//
//                sw5(up sw)
//                ---- 
//    p26 --------o  o----------- GND
//
//                sw4(down sw)
//                ---- 
//    p27 --------o  o----------- GND
//
//                sw3(right sw)
//                ---- 
//    p28 --------o  o----------- GND
//
//                sw2(b sw)
//                ---- 
//    p29 --------o  o----------- GND
//
//                sw1(a sw)
//                ---- 
//    p30 --------o  o----------- GND
//
// V1.0 2011/12/11 
// 
//
//===========================================================================
#include "mbed.h"
#include "SevenSegLed.h"
#include "Sound.h"
#include "SwDigital.h"

Ticker timeout100ms;     // 100ms interrupt

Sound sound(p21, p22);
SwDigital sw(p25, p26, p27, p28, p29, p30); // left, up, down, right, b, a
enum{
    leftSw,
    upSw,
    downSw,
    rightSw,
    bSw,
    aSw
};

SevenSegLed sevenSegLed(1, 0, p19, p5, p10, p12, p13, p18, p9, p11, p20, p7, p6, p8);   // OSL40562-LR(seikiban)

uint8_t D_7seg[4] = {0, 0, 0, 0};
uint8_t D_dot[4]  = {0, 1, 0, 0};

uint8_t C_flicker; // timer setti ji no henko keta flicker kyoka (100[ms]/count) 0:flicker request ohter:kinsi
#define Z_flicker (5 * 10)

int16_t D_timerSec = 3 * 60; // timer no settai chi (1/1 [s]/count)
int16_t C_timerSec; // timer keiji jikan (1/1[s]/count)

enum timer_t{
    stop,
    setMin,
    setHore,
    count,
 };
timer_t M_timer = stop;

uint8_t F_flip100ms;    // 100ms keika goto ni 0 or 1 
uint8_t F_flip500ms;    // 500ms keika goto ni 0 or 1

time_t seconds;
struct tm  *A_time;   // genzai jikoku

//===================================
// beep (sw sosa ji no oto)
//===================================
void beep(void){
// tone1 
    Sound::sound_t oto = {1,0x95,200,100};
    sound.sound_sound(oto);
}

//**********************************************************
// chime
//**********************************************************
uint8_t C_chime;    // chime kaisuu 1 - 255 (1/1[kai]/count)

//=====================================================
// chime request
//      no : chime no kaisuu 1 - 255 ( 1/1 [kai]/count)
//=====================================================
void chimeSet(uint8_t no){
    C_chime = no;
}

//====================================
// chime check and output
//    10 - 100 ms syuuki de call suru
//====================================
void chimeCheck(void){
    if(C_chime > 0){
        if((sound.sound_sound() == false) && (sound.sound_enso() == false)) {
            Sound::sound_t oto = {1,0xF4,2500,1500};
            sound.sound_sound(oto);
            C_chime--;
        }
    }
}

//***************************************************
// melody data tabel
//***************************************************

//================================
// "westminster chime" merody data
//================================
    const Sound::sound_t WESTMINSTER[] =     {
    //  onkai,hatuon jikan[ms]
        {1,0xA4,1200,1000},
        {1,0xF4,1200,1000},
        {1,0x94,1200,1000},
        {1,0xC4,2400,1000},

        {1,0xC4,1200,1000},
        {1,0x94,1200,1000},
        {1,0xA4,1200,1000},
        {1,0xF4,2400,1000},
 
        {1,0xA4,1200,1000},
        {1,0xF4,1200,1000},
        {1,0x94,1200,1000},
        {1,0xC4,2400,1000},

        {1,0xC4,1200,1000},
        {1,0x94,1200,1000},
        {1,0xA4,1200,1000},
        {1,0xF4,2400,1000},
               
        {1,0xFF,1000,0},    // end
    };

//==========================
// "ramen chime" merody data
//==========================
    const Sound::sound_t RAMEN[] =     {
    //  onkai,hatuon jikan[ms]
        {1,0xC5,300,500},
        {1,0xD5,300,500},
        {1,0xE5,1200,500},
        {1,0xD5,600,500},
        {1,0xC5,1200,500},

        {1,0xC5,300,500},
        {1,0xD5,300,500},
        {1,0xE5,300,500},
        {1,0xD5,300,500},
        {1,0xC5,300,500},
        {1,0xD5,1800,500},

        
        {1,0xFF,1000,500},    // end
    };

//=============================
// "demekin no uta" merody data
//=============================
    const Sound::sound_t DEMEKIN[] =     {
    //  onkai,hatuon jikan[ms]
        {1,0xC5,600,500},     // de
        {1,0xE5,600,500},     // me
        {1,0x95,600,500},     // kin
        {1,0x00,600,500},

        {1,0xC5,600,500},     // de
        {1,0xE5,600,500},     // me
        {1,0x95,600,500},     // kin
        {1,0x00,600,500},

        {1,0xC5,600,500},     // de
        {1,0xE5,600,500},     // me
        {1,0x95,600,500},     // kin
        {1,0x95,600,500},     // no
        {1,0x95,150,500},     // shi
        {1,0x00,900,500},
        {1,0xE5,750,500},     // po
        {1,0x00,450,500},

        {1,0xC5,600,500},     // de
        {1,0xE5,600,500},     // me
        {1,0x95,600,500},     // kin
        {1,0x00,600,500},

        {1,0xC5,600,500},     // de
        {1,0xE5,600,500},     // me
        {1,0x95,600,500},     // kin
        {1,0x00,600,500},

        {1,0x95,600,500},     // ju
        {1,0xE5,600,500},     // go
        {1,0xD5,600,500},     // n
        {1,0xC5,600,500},     // no
        {1,0xE5,150,500},     // shi
        {1,0x00,900,500},
        {1,0xC5,750,500},     // po
        {1,0x00,1350,500},

        {1,0xFF,1000,0},    // end (1s keika go sai enso)
//                                {1,0xFF,0},        // end    (1kaino enso de teisi suru baai)
};

//=============================
// timer SW seni
//=============================
void timerSeni(void){
    static uint8_t B_timesec = 0;

    // aSw(settei SW)
    if(sw.checkEdgeOn(aSw) == 1){
        if((M_timer != setMin) && (M_timer != setHore)){
            beep();
            M_timer = setMin;
            
            // genzai jikoku kakuno
            seconds = time(NULL);
            A_time = localtime(&seconds);
        }
        else if((M_timer == setMin) || (M_timer == setHore)){
            beep();
            M_timer = count;
            
            A_time->tm_sec = 0;
            seconds = mktime(A_time);
            set_time(seconds);       
        }
        else{
            // noting
        }
    }
    
    // bSw(torikesi SW)
    if((sw.checkEdgeOn(bSw) == 1) && (M_timer != count)
    ){
        beep();
        M_timer = count;
    }    

    switch(M_timer){
    case stop:
        // other aSw,bSw then setMin
        if((sw.checkEdgeOn(upSw) == 1)
         ||(sw.checkEdgeOn(downSw) == 1)
         ||(sw.checkEdgeOn(leftSw) == 1)
         ||(sw.checkEdgeOn(rightSw) == 1)
         ){
            beep();
            M_timer = setMin;
            C_flicker = 0;
            
            // genzai jikoku kakuno
            seconds = time(NULL);
            A_time = localtime(&seconds);
        }
        break;
    case setMin:
        if(sw.checkEdgeOn(leftSw) == 1){
            beep();
            M_timer = setHore;
            C_flicker = 0;
        }
        break;
    case setHore:
        if(sw.checkEdgeOn(rightSw) == 1){
            beep();
            M_timer = setMin;
            C_flicker = 0;
        }
        break;
    case count:
        seconds = time(NULL);
        A_time = localtime(&seconds);
        
        // 59 kara 0 byo ni nattara melody wo narasu
        if((B_timesec == 59) && (A_time->tm_sec == 0)){
            // jikoku chime no kaisuu set
            uint8_t C_chime = A_time->tm_hour;
            if(C_chime == 0){
                C_chime = 12;
            }
            else if(C_chime > 12){
                C_chime -= 12;
            }

            // jikoku no melody and chime
            if(A_time->tm_min == 0){
                if(A_time->tm_hour == 12){
                    sound.sound_enso((Sound::sound_t*)RAMEN);
                    sound.sound_enso(true);
                    chimeSet(C_chime);
                }
                else {
                    sound.sound_enso((Sound::sound_t*)WESTMINSTER);
                    sound.sound_enso(true);
                    chimeSet(C_chime);
                }
            }
            
            // 30min no chime               
            if(A_time->tm_min == 30){
                chimeSet(2);
            }
            
            // 15min or 45min no chime
            if((A_time->tm_min == 15) || (A_time->tm_min == 45)){
                chimeSet(1);
            }
         }
        B_timesec = A_time->tm_sec; // jikai hikaku yo time data kioku
      break;
    
     default:
        // nothing
        break;
    }

}
//============================
// time set
//============================
void timerSet(void){

    switch(M_timer){
    case stop:
        break;
    case setMin:
        if(sw.checkEdgeOn(upSw) == 1){
            beep();
            if(A_time->tm_min < 59){
                A_time->tm_min++;
            }
            else{
                A_time->tm_min = 0;
            }
            C_flicker = Z_flicker;
         }
        
        if(sw.checkEdgeOn(downSw) == 1){
            beep();
            if(A_time->tm_min > 0){
                A_time->tm_min--;
            }
            else{
                A_time->tm_min = 59;
            }
            C_flicker = Z_flicker;
        }
        break;
    case setHore:
        if(sw.checkEdgeOn(upSw) == 1){
            beep();
            if(A_time->tm_hour < 23){
                A_time->tm_hour++;
            }
            else{
                A_time->tm_hour = 0;
            }
            C_flicker = Z_flicker;
        }
        
        if(sw.checkEdgeOn(downSw) == 1){
            beep();
             if(A_time->tm_hour > 0){
                A_time->tm_hour--;
            }
            else{
                A_time->tm_hour = 23;
            }
            C_flicker = Z_flicker;
        }
        break;
    case count:
        // nothing
        break;
    default:
        // nothing
        break;
    }
    
 }

//==========================
// seven segment display
//==========================
void sevenSegDisplay(void){
    int16_t work;
    
    switch(M_timer){
    case stop:
 
        D_7seg[0] = 0x0f;
        D_7seg[1] = 0x0f;
        D_7seg[2] = 0x0f;
        D_7seg[3] = 0x0f;
 
        
        D_dot[0] = 0;
        D_dot[1] = 0;
        D_dot[2] = 0;
        D_dot[3] = 0;
        
        break;
    case setMin:    // setHore to onaji
    case setHore:
        sevenSegLed.smoothSet(1);   // hyoji hard
        D_7seg[0] = A_time->tm_hour / 10;
        D_7seg[1] = A_time->tm_hour % 10;
        D_7seg[2] = A_time->tm_min / 10;
        D_7seg[3] = A_time->tm_min % 10;

        // settei basyo no tenmetu        
        if((C_flicker == 0) && (F_flip500ms == 0)){
            if(M_timer == setMin){
                D_7seg[2] = 0x10;
                D_7seg[3] = 0x10;
            }
            else{
                D_7seg[0] = 0x10;
                D_7seg[1] = 0x10;
            }
        }

        D_dot[0] = 0;
        D_dot[1] = 1;         
        D_dot[2] = 0;
        D_dot[3] = 1;

        break;
    case count:
        sevenSegLed.smoothSet(0);   // hyoji smooth
        seconds = time(NULL);
        A_time = localtime(&seconds);
        
        D_7seg[0] = A_time->tm_hour / 10;
        D_7seg[1] = A_time->tm_hour % 10;
        D_7seg[2] = A_time->tm_min / 10;
        D_7seg[3] = A_time->tm_min % 10;

        D_dot[0] = 0;
        D_dot[1] = 1;
        D_dot[2] = 0;

        // byo no dot no tenmetu   
        if((A_time->tm_sec % 2) == 0){
            D_dot[3] = 0;
        }
        else{
            D_dot[3] = 1;
        }
        break;

    default:
        break;
    }
    sevenSegLed.SevenSegLed_main(D_7seg, D_dot);    // 7segment hyoji
}

//================================
// 100ms interrupt
//================================
void interrupt100ms(void){
    static uint8_t C_100ms = 0;
    
    C_100ms++;
    if(C_100ms > 9){C_100ms = 0;}
    
    // flip flag 
    F_flip100ms = !F_flip100ms;

    if(C_100ms < 5){F_flip500ms = 1;}
    else{F_flip500ms = 0;}

    // settei keta flicker
    if(C_flicker > 0){C_flicker--;}

    // timer counter decrement
    if((C_100ms == 0) && (C_timerSec > 0)){C_timerSec--;}        

}

//================================
// main
//================================
int main() {
    timeout100ms.attach(&interrupt100ms, 0.1);  // 10ms interrupt

    // kido ji no melody
    sound.sound_enso((Sound::sound_t*)DEMEKIN);
    sound.sound_enso(true);

    while(1) {
        // sw level and edge data refresh
        sw.refreshEdgeData();
    
        timerSeni();
        timerSet();
        sevenSegDisplay();
        chimeCheck();
    }
}