交差点の信号と、横断歩道の信号を1つのマイコンで再現しました。

Dependencies:   mbed

main.cpp

Committer:
kohacraft
Date:
2018-05-01
Revision:
1:1943a21b781b
Parent:
0:dff00c5f274e

File content as of revision 1:1943a21b781b:

/* 車両用信号機3つと歩行者用信号機1つを再現するプログラムです   */
/* 信号機1と信号機2で交差点の信号を再現し、                   */
/* 信号機3と信号機4で横断歩道の信号を再現しています            */
/* timingの{}の中を変えることで赤黄青の点灯時間を変更できます   */
/* 自由に改編して楽しんでください this program is public domain */
/* May.1.2018 kohacraft.com */
#include "mbed.h"
#define BLUE 0
#define YELLOW 1
#define RED 2

DigitalOut singo1Led[] = {
    DigitalOut(dp1),    //信号機1 青LED
    DigitalOut(dp2),    //信号機1 黄LED
    DigitalOut(dp4)     //信号機1 赤LED
};

DigitalOut singo2Led[] = {
    DigitalOut(dp9),    //信号機2 青LED
    DigitalOut(dp10),    //信号機2 黄LED
    DigitalOut(dp11)     //信号機2 赤LED
};

DigitalOut singo3Led[] = {
    DigitalOut(dp28),   //信号機3 青LED
    DigitalOut(dp26),   //信号機3 黄LED
    DigitalOut(dp25)    //信号機3 赤LED
};

DigitalOut singo4Led[] = {
    DigitalOut(dp18),   //信号機4(歩行者用) 青LED
    DigitalOut(dp17),   //ダミー(赤と同じdpを指定する)
    DigitalOut(dp17)    //信号機4(歩行者用) 赤LED
};

DigitalOut singo5Led[] = {
    DigitalOut(dp16),   //信号機5 青LED
    DigitalOut(dp15),   //信号機5 黄LED
    DigitalOut(dp14)    //信号機5 赤LED
};


DigitalOut sp(dp27);    //スピーカー接続

/* 赤黄青の点灯時間{ 赤の点灯時間 , 青の点灯時間 , 黄色の点灯時間 , 赤の点灯時間 }*/
/* 1は1.5秒 */
int timing1[] = { 1 , 4 , 2 , 7 }; //信号機1の点灯時間の設定
int timing2[] = { 8 , 4 , 2 , 0 }; //信号機2の点灯時間の設定
int timing3[] = { 1 , 6 , 2 , 7 }; //信号機3の点灯時間の設定
int timing4[] = { 1 , 3 , 2 , 10 }; //信号機4の点灯時間の設定
int timing5[] = { 10 , 4 , 2 , 0 }; //信号機5の点灯時間の設定

Ticker timer;   //歩行者用信号の点滅のためのタイマー

int shingo1mode , shingo2mode , shingo3mode , shingo4mode , shingo5mode;  //現在の点灯している色(赤:0・青:1・黄:2・赤:3) 
int shingo1counter , shingo2counter , shingo3counter , shingo4counter , shingo5counter;  //次の色に変わるまでの残り時間 

//使用する関数の宣言
void singo( DigitalOut led[] , int *mode , int *counter , int timeing[] );
void hokosya( DigitalOut led[] , int *mode , int *counter , int timeing[] );
void sound();

//割り込みによる信号機4の点滅処理
void flip() {
    singo4Led[BLUE] = !singo4Led[BLUE];
}

int main() {
    
    //初期化
    shingo1mode = 0;    shingo2mode = 0;    shingo3mode = 0;
    shingo4mode = 0;    shingo5mode = 0;
    shingo1counter = timing1[0];
    shingo2counter = timing2[0];
    shingo3counter = timing3[0];
    shingo4counter = timing4[0];
    shingo5counter = timing5[0];
    singo1Led[BLUE] = 0;   singo1Led[YELLOW] = 0;   singo1Led[RED] = 1;
    singo2Led[BLUE] = 0;   singo2Led[YELLOW] = 0;   singo2Led[RED] = 1;
    singo3Led[BLUE] = 0;   singo3Led[YELLOW] = 0;   singo3Led[RED] = 1;
    singo4Led[BLUE] = 0;   singo4Led[RED] = 1;
    singo5Led[BLUE] = 0;   singo5Led[YELLOW] = 0;   singo5Led[RED] = 1;

    //無限ループ
    while(1) {
        singo( singo1Led , &shingo1mode , &shingo1counter , timing1 );    //信号機1の処理
        singo( singo2Led , &shingo2mode , &shingo2counter , timing2 );    //信号機2の処理
        singo( singo3Led , &shingo3mode , &shingo3counter , timing3 );    //信号機3の処理
        hokosya( singo4Led , &shingo4mode , &shingo4counter , timing4 );  //信号機4の処理
        singo( singo5Led , &shingo5mode , &shingo5counter , timing5 );    //信号機5の処理
        
        //歩行者用信号が青の時カッコーを鳴らす
        if( shingo4mode == 1 && singo4Led[BLUE])
            sound();
        else
            wait(1.5);    //それ以外はウェイトで待つ
    }
}

//車両用信号の点灯を制御する
void singo( DigitalOut led[] , int *mode , int *counter , int timeing[] )
{   

    //カウンターが0以下になったら点灯するLEDを変更する
    if( *counter <= 0 ){
        
        //modeを一つ増やす 3を超えたら0に戻す
        *mode = *mode +1 ;
        if( *mode > 3 )
            *mode = 0;

        //もし点灯時間が0ならば次のmodeに遷移する
        if( timeing[*mode] == 0 )
        *mode = *mode +1 ;
        if( *mode > 3 )
            *mode = 0;        
        
        //次の色の点灯時間をカウンターにセット
        *counter = timeing[*mode];
        
        //点灯するLEDを変更する
        switch( *mode ) {
            case 0 :    //赤を点灯
                led[BLUE] = 0; led[YELLOW] = 0; led[RED] = 1;
                break;
            case 1 :    //青を点灯
                led[BLUE] = 1; led[YELLOW] = 0; led[RED] = 0;
                break;
            case 2 :    //黄色を点灯
                led[BLUE] = 0; led[YELLOW] = 1; led[RED] = 0;
                break;
            case 3 :    //赤を点灯
                led[BLUE] = 0; led[YELLOW] = 0; led[RED] = 1;
                break;
            default : 
                led[BLUE] = 0; led[YELLOW] = 0; led[RED] = 1;
                break;
        }
    }     
    *counter = *counter -1;
    
}
    
//歩行者用信号の点灯を制御する
void hokosya( DigitalOut led[] , int *mode , int *counter , int timeing[] )
{
    //カウンターが0以下になったら点灯するLEDを変更する
    if( *counter <= 0 ){
        
        //modeを一つ増やす 3を超えたら0に戻す
        *mode = *mode +1 ;
        if( *mode > 3 )
            *mode = 0;
        
        //もし点灯時間が0ならば次のmodeに遷移する
        if( timeing[*mode] == 0 )
        *mode = *mode +1 ;
        if( *mode > 3 )
            *mode = 0;        
        
        //次の色の点灯時間をカウンターにセット
        *counter = timeing[*mode];
        
        //点灯するLEDを変更する
        switch( *mode ) {
            case 0 :    //赤を点灯
                led[BLUE] = 0; led[RED] = 1;
                break;
            case 1 :    //青を点灯
                led[BLUE] = 1; led[RED] = 0;
                break;
            case 2 :    //青を点滅
                led[BLUE] = 1; led[RED] = 0;
                timer.attach(&flip, 0.25);  //点滅用タイマー割り込み開始
                break;
            case 3 :    //赤を点灯
                timer.detach(); //点滅用タイマー割り込み停止
                led[BLUE] = 0; led[RED] = 1;
                break;
            default : 
                led[BLUE] = 0; led[RED] = 1;
                break;
        }
    }     
    *counter = *counter -1;
     
}

//カッコーの音
void sound()
{
    //ミの音を鳴らす
    for( int i=0 ; i<300 ; i++ )
    {
        sp = 1;   //スピーカーをON OFF させて音を作る
        wait(1.0/880.00/4); //1オクターブ上のミ 880*2Hz
        sp = 0;
        wait(1.0/880.00/4);
    
    }
    sp = 1; //スピーカーをオフする
    wait(0.2);
    
    //ドの音を鳴らす
    for( int i=0 ; i<700 ; i++ )
    {
    
        sp = 1;
        wait(1.0/698.45/4); //1オクターブ上のド 698.45*2Hz
        sp = 0;
        wait(1.0/698.45/4);
    
    }
    sp = 1;
    wait(0.5);
}