本物の踏切っぽい音が鳴る踏切のプログラムです

Dependencies:   mbed

main.cpp

Committer:
kohacraft
Date:
2021-06-29
Revision:
0:1927c2db569e

File content as of revision 0:1927c2db569e:

#include "mbed.h"

/* 踏切を再現するプログラム */
/* 作り方 */
/* https://kohacraft.com/archives/202106291603.html */
/* https://kohacraft.com/archives/202106150823.html */
/* https://kohacraft.com/archives/1035056914.html */

PwmOut sp(dp1);     //スピーカーをつなぐピンをPWM出力に設定
DigitalIn sw(dp2);      //スイッチをつなぐピンを入力に設定
DigitalOut led1(dp14);  //LED1をつなぐピンを出力に設定
DigitalOut led2(dp18);  //LED2をつなぐピンを出力に設定

const int humikiriMax = 5;           //スイッチが反応してから踏切が終わるまでの長さ

Ticker sound_ticker;    //サウンドのためのタイマー割り込み

//カーンカーンの音の発生
void sound() {
    static int counter_0 = 0;
    static int counter_1 = 0;
    
    static int envelope = 0;
    
    float out = 0;
    int sin1 = (((counter_0 >> 15) & 1) * 2) - 1;
    int sin2 = (((counter_1 >> 15) & 1) * 2) - 1;
    out = sin1 * ((float)(sin2 + 1) / 2) * ((float)((~envelope >> 16) & 0xff) / 255);   //波形を生成
    sp.write((out * 0.5) + 0.5);
    
    counter_0 += 700 * 256 * 256 / 10000;   //700Hzの音を発生
    counter_1 += 750 * 256 * 256 / 10000;   //750Hzの音を発生
    
    envelope += 130 / 60 * 256 * 256 * 256 / 10000; //60秒間に130回音を鳴らす
}

int main() {
    sp.period_us(10);   //スピーカーのPWMを100KHzに設定
        
    int count = 0;  //踏切がなり終わるまでのカウント 0になったら鳴り終わる
    while(1) {
        
        //両方のLEDを消す
        led1 = 0;
        led2 = 0;

        //センサが反応したらカウンターに踏切が終わるまでの長さを入れる
        if( sw == 0 )
        {
            count = humikiriMax;
            sound_ticker.attach_us(&sound, 100);//100us = 10KHz タイマー割り込み開始
        }
        
        //踏切がなり終わるまでのカウントが0以上ならば踏切が鳴る
        while(count > 0)
        {
            //片方のLEDだけを点灯
            led1 = 1;
            led2 = 0;

            for( int i=0 ; i<5 ; i++ )  //5回繰り返す
            {        
                //センサが反応したらカウンターに踏切が終わるまでの長さを入れる
                if( sw == 0 )
                {
                    count = humikiriMax;
                }
                wait(0.1);  //0.1秒待つ
            }
            
            //もう片方のLEDだけを点灯
            led1 = 0;
            led2 = 1;

            for( int i=0 ; i<5 ; i++ )  //5回繰り返す
            {   
                //センサが反応したらカウンターに踏切が終わるまでの長さを入れる
                if( sw == 0 )
                {
                    count = humikiriMax;
                }
                wait (0.1); //0.1秒待つ
            }
            
            count--;    //カウンタを1減らす
        }
        sound_ticker.detach();  //タイマー割り込み終了
        sp.write(0);    //スピーカーをオフ
    }
}