Amazonで販売されていた音声モジュールを購入しました。
ISD1820と呼ばれるチップを搭載したモジュールで、送料込みで268円と格安なモジュール。
スピーカー付属でこの価格は不良品かと半信半疑で購入して試し使いしてみました。
使い方は至ってシンプルで、届いた部品以外に必要なものは電源のみ(3.3V~5.0V)。
電源は三端子レギュレータを使用した回路で5.0Vを生成しました。
実際に使った電源回路は以下回路図です。
付属のハーネスをスピーカーに半田付けし、コネクタを基板に差して準備完了。
モジュールに実装されているRECスイッチを押しながら、声を録音する。
PLAYEスイッチを押すと、録音した音声が流れだした。
約10秒間の音声を録音できる。簡単なボイスメモとして十分な代物です。
結果として、予想に反して意外と使えることがわかりました。
さあ、ここからが本番!
このモジュールを使用してビックリ箱ギミックを製作します。
人が近づいたことをセンサーで検知し、音と動き(振動)で驚かすギミックです。
人を検知するセンサーは、以下の超音波センサーを使用する。
動き(振動)の部分は、PCに使われるDCモーターファンを使い、ファンの羽を折り
回転重心をずらすための錘(今回はボルト)を付けたものを使います。
スマホの振動用モーターを模擬した構造ですね。
メインのコントローラーとしては、PIC12F683を選定。
ADコンバーターも搭載されて、オシレーターも内蔵で120円と手頃なマイコン。
今回は秋月電子で購入しました。(http://akizukidenshi.com/catalog/g/gI-00801/)
PICで制御するロジックは、以下のフロー構成としました。
1.超音波センサーにて距離を検出する(ループ処理で検出)
2.40cm以内の障害物を検知すると以下3,4を実行する
3.サウンドモジュールを駆動
4.モーターを10秒間駆動させて1に戻る
では、回路製作に取り掛かかります。
電源回路は上段で掲載した回路をそのまま使い、
超音波センサーと制御部(PIC)は以下回路で構成しました。
音声モジュール、超音波センサー、PICマイコンはす全て5.0V系なので電源は1系統で済みます。
※電子部品を選定する際は、駆動電圧と消費電流も気にしたほうがよさそうですね。
SPEAKERはSPEAKERモジュールの駆動へMOTORは、モーター駆動用のMOSFETに接続します。
次にモーター駆動回路に取り掛かります。
モーターの駆動電圧は少し高めだったので、供給電源はバッテリー直の6.0Vを供給することにしました。
モーターの下流側(GND)にMOSFET(NPN型)を接続し、PICマイコンの出力ポートに接続させます。
PICの出力ポートをHigh→Lowに切り替えるとモーターが駆動する仕組みですね。
音声モジュールは、購入したモジュールそのまま使用します。
PLAYEが外部出力ピン端子として用意されているので、そこへ接続しました。
結果としてスピーカーモジュールへの配線は3本(POWER, GND, SPEAKER)のみ。
以下が配線の様子です。
ひとまず、回路の検証として上記回路をブレッドボードで構築しました。
構築した回路を掲載します。(雑で申し訳ないです)
PICのプログラムは以下の通り。
PICへの書き込みは、愛用の秋月電子のAKI-PICプログラマーVer.4.0です。
http://akizukidenshi.com/catalog/g/gK-02018
私としては、これが一番使いやすい。
PICKIT3互換品という安価なPICライターも出回っているみたいですが、未検証です。
今回PICのコードの詳細解説は省きますが、別途詳細説明のブログを掲載しますね。
もともとのプログラムは超音波センサーの値をシリアル通信で送るコードをベースに作成しているので、
不要な箇所が多々あります。
//-----------------------------------------------------------------------------
// PICの周波数を32Mhzに設定
//-----------------------------------------------------------------------------
#include
#include
#include
// コンフィグレーションBIT1 設定
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable (PWRT enabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)
// コンフィグレーションBIT2 設定
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = ON // PLL Enable (4x PLL enabled)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = HI // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), high trip point selected.)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
#define _XTAL_FREQ 32000000
#define TX_UART_SIZE 3
#define SONIC_TRIG RA5
#define SONIC_ECHO RA4
#define IO_OFF 0
#define IO_ON 1
volatile unsigned char uart_tx_msg[TX_UART_SIZE] = {0};
volatile unsigned char uart_tx_cnt = 0;
void interrupt isr_ctrl( void )
{
if( TXIF )
{
if( uart_tx_cnt
{
TXREG = uart_tx_msg[ uart_tx_cnt ];
uart_tx_cnt++;
}
else
{
TXIE = 0;
}
if( uart_tx_cnt >= TX_UART_SIZE )
{
uart_tx_cnt = 0;
TXIE = 0;
}
TXIF = 0;
}
}
int main(int argc, char** argv)
{
long echo_time;
long dist;
short work1,work2,work3;
OSCCON = 0b01110000 ; // 内部クロック8MHz
ANSELA = 0b00000000 ; // デジタルI/Oに割当てる
TRISA = 0b00011000 ; // RA3,4を入力にし、他は出力に割当てる
PORTA = 0b00000000 ; // 出力ピンの初期化(全てLOWにする)
T1CON = 0b00110000 ; // FOSC/4を選択 分周比1/8
T1GCON = 0b11010000 ; // ゲート有効、Hiでカウント、単一パルス、T1Gピン
TXSTA = 0x24; // 送信情報設定:非同期モード 8ビット・ノンパリティ
RCSTA = 0x90; // 受信情報設定
BAUDCON = 0x08; // 16bit
SPBRG = 0x40; // ボーレートを9600(高速モード)に設定
SPBRGH = 0x03;
RXDTSEL = 0;
TXCKSEL = 0;
TMR1ON = 1; // タイマー1開始
TXIE = 0;
TXIF = 0;
PEIE = 1;
GIE = 1;
for(;;)
{
// タイマ1のカウンタ準備
TMR1 = 0; // カウンタの初期化
T1GGO = 1; // 単一パルスを使用する
// トリガ送信
SONIC_TRIG = IO_ON;
__delay_us( 10 );
SONIC_TRIG = IO_OFF;
// エコー信号のON待ち
while( SONIC_ECHO == IO_OFF )
{
// 処理なし
}
// エコー信号のOFF待ち
while( SONIC_ECHO == IO_ON )
{
// 処理なし
}
// 超音波の往復時間を取得
echo_time = TMR1;
// 往復時間から片道の時間にする
echo_time /= 2;
// パルス時間から距離(cm)に変更
dist = echo_time * 34 / 1000;
if( dist < 400)
{
// 位で分割
work1 = dist % 10;
dist /= 10;
work2 = dist % 10;
dist /= 10;
work3 = dist;
// 送信データ構築
uart_tx_msg[0] = 0x00; // 少数点位置の設定
uart_tx_msg[1] = 0x0f & work3;
uart_tx_msg[2] = (work2 <
}
else
{
// 送信データ構築
uart_tx_msg[0] = 0x00; // 少数点位置の設定
uart_tx_msg[1] = 0x04;
uart_tx_msg[2] = 0x00;
}
uart_tx_cnt = 0;
TXIE = 1; // 送信開始
__delay_ms( 1000 );
}
return (EXIT_SUCCESS);
}
※goo blogの制約上"<"が使用できないので上記プログラムでは全角の"<"を使用してます。
実際流用する際は、半角の"<"に書き換えて使ってください。
さあ、動作確認!
赤外線センサーへ手を近づけるとモーターが振動し、予め息子の声を録音した
「こんにちは」の声が聞こえました。ひとまず成功。動画も参考に載せておきます。
超音波センサ+音声モジュール+PICを使用したギミック電子工作
動作確認ができたので、ユニバーサル基板に実装しましたが、、、
うーん。基板が2つあるのは美しくない!
そこで、音声モジュールのISD1820チップをユニバーサル基板へ移植することにします。
DIPに挿入されていたので、マイナスドライバーで簡単に抜くことができた。
回路構成を確認するためISD1820PYデータシートをWebから拾い、回路図を起こしました。
<データーシートのリンク>
http://aitendo3.sakura.ne.jp/aitendo_data/product_img/ic/audio/ISD1800/ISD1800.pdf
データシートによるとROSCピンに接続する抵抗値により、録音時間を変更できる。
これは良い。
録音時と再生時で抵抗を変更するとボイスチェンジャーモドキとして使えますね!
そこで、ROSCピンに可変抵抗器を実装することとしました。
抵抗範囲は、80kΩ~160kΩなのでカバーできる部品を選定。
<データーシートの抜粋>
80kΩで約8秒間、160kΩで約16秒間録音再生できるようになります。
<回路構成>
データーシートをもとに、回路図を起こしました。SPEAKER端子はPICからの出力です。
ユニバーサル基板に実装しました。
なるべく小サイズでと頑張りすぎて、半田付けに手こずってしまいました。
<表面>
青色の素子が可変抵抗器。
<裏面>
<全部品接続状態>
美しくなった。さあ、動作確認。
手を近づけると、ブレッドボード時と同じようにモーターが振動し、音声が流れます。
可変抵抗器を変えてみると、意図した通りボイスチェンジャーっぽく音声が変わりました。
ただ、もともと実装されていたモジュールと比べると、録音時の音声の音量が
若干小さくなったように感じます。配線の問題か、部品定数の違いか、
調査が必要ですが、ひとまずやりたいことは達成できたので、一旦ここで完了とします。