誰でもできる電子工作・プログラミング趣味ブログ

電子工作とプログラミングを趣味にする人口を増やすため、
誰でもできる電子工作とプログラミングを紹介します。

音声モジュールISD1820の試し使い

2020年05月16日 | 電子工作

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からの出力です。

 

ユニバーサル基板に実装しました。

なるべく小サイズでと頑張りすぎて、半田付けに手こずってしまいました。

<表面>

青色の素子が可変抵抗器。

<裏面>

<全部品接続状態>

 

美しくなった。さあ、動作確認。

手を近づけると、ブレッドボード時と同じようにモーターが振動し、音声が流れます。

可変抵抗器を変えてみると、意図した通りボイスチェンジャーっぽく音声が変わりました。

 

ただ、もともと実装されていたモジュールと比べると、録音時の音声の音量が

若干小さくなったように感じます。配線の問題か、部品定数の違いか、

調査が必要ですが、ひとまずやりたいことは達成できたので、一旦ここで完了とします。

 

にほんブログ村 その他趣味ブログ 電子工作へ
にほんブログ村


PHPにてMySQLデータをCSVに出力する

2020年05月16日 | PHP/MySQL

今回はMySQLに登録されているデータをCSVに出力する方法を紹介します。

オプションとして、以下2点も付け加えます。

 1.必要なデータ(例えば学校のデータだと学年毎の出力)のみを出力

 2.データをソートして出力(例えば、学籍番号順)

 

//MySQLへの接続開始


$connect = mysqli_connect("MySQL_ServerName", "Login_UserName", "Login_Password", "DatabaseName");


 

//接続状態を確認


if (mysqli_connect_errno()) {
  die("MySQLデータベースに接続できません:" . mysqli_connect_error() . "\n");
} else {
  echo "MySQLデータベースの接続に成功しました。";
}


 

//出力するCSVファイルを準備します


$file_name = "student.csv";  //出力するCSVファイル名の定義

$data_title = ["学年", "名前", "学籍番号", "科目1", "成績", "科目2", "成績"];  //出力するテーブルのタイトルを定義


 

//文字化けを防止するため、文字エンコーディングを変更します

 文字エンコーディングの変更は、mb_convert_encodingを使い、$dataの文字データを以下コマンドで変換。

 使用例:mb_convert_encoding($data, "変換後の文字エンコーディング", "変換前の文字エンコーディング")

 変換前の文字エンコーディングはautoで設定。autoは、"ASCII,JIS,UTF-8,EUC-JP,SJIS"の順番に自動検出します。

 変換後の文字エンコーディングは、一度SJISを使用したが、"髙"などの環境依存文字が文字化けしたので、SJIS-winに変更。


foreach($data_title as $key => $data){
    $header[] = mb_convert_encoding($data, 'SJIS-win', 'auto');
}


//ファイルを生成する

 touch(ファイル名)コマンドを使いファイルを作成します。

 touchコマンドの使い方はこちら→https://www.php.net/manual/ja/function.touch.php

 ファイル作成後、$file->fputcsv($data)にて、先ほど作成したタイトル部分を格納します。

 この$dataは配列(Array)とする必要があり、dataを単一の変数として定義した場合はPHPエラーになります。


if(touch($file_name)){
    $file = new SplFileObject($file_name, "w");
    $file->fputcsv($header);
}


//MySQLからのデータ取り出し

  MySQLのSELECT分でデータを引き出します。ORDER BY *** ASCを使い、ソートを行います。

  ***はソートをかけたいデータ名を設定。

  CSVへの出力は全データではなく一部のデータのみをCSVに出力したいので、一時的に配列変数を作成し格納します。

 ここでも文字化けを防止するため、mb_convert_encodingを使い、文字エンコーディングをSJIS-winに変換。

 $file->fputcsv($wdata);にてCSVに格納します。


$student_data = "SELECT year, name, number, subject1, grade1, subject2, grade2, subject3, grade3 FROM DataTableName ORDER BY number ASC;";
if ($output = mysqli_query($connect, $student_data)) {
  while ($row = mysqli_fetch_assoc($output)) {
    if($row['year'] == 3){ //3年生だけを抽出
      $wdata = array(
        1 => "$row['year']",
        2 => "$row['name']",
        3 => "$row['number']",
        4 => "$row['subject3']",
        5 => "$row['grade3']",
      );
    $wdata = mb_convert_encoding($wdata, "SJIS-win", "auto");
    $file->fputcsv($wdata);
  }
}


 

  //MySQL接続解除

 MySQLの接続を解除して終了


  mysqli_close($connect);


 

これにより、PHPファイルが保存されているフォルダ内にstudent.csvが作成されました。

ページ内にこのファイルに対するリンクを配置すると、Web上からワンクリックでcsvファイルがダウンロードできるようになります。

 

にほんブログ村 IT技術ブログ MySQLへ
にほんブログ村


Unityインターハイ2020の参加受付スタート!

2020年05月13日 | ニュース

Unityインターハイ2020のエントリー募集が始まりましたね。

 リンク: https://inter-high.unity3d.jp/

 

私自身は参加要件の「Under 18 years old」から大きく足を外しているので、残念ながら参加資格はありませんが、

このようなイベントを目にすると胸が躍ります。

私の周辺にも自宅でサーバー構築したり、ゲーム作成のプログラミングを趣味にする中高生が多くおり、

ソフトウェア技術学習の低年齢化が進んでいることを実感しています。

いやいや本当最近の若い人たちは凄い。

 

ちょうど一年前からUnityを使ってスマホゲーム制作にも取り組んでいるので、

完成したらアプリのリンクを載せていきますね。

 


PHPによるMySQLへの接続方法

2020年05月13日 | PHP/MySQL

昨日のBlogにも書きましたが、現在PHPとMySQLを使用して、とある団体のユーザー認証サーバーを構築してます。

本日はPHPからMySQLへの認証方法についての備忘録です。

 

MySQLデータベースの操作APIは、mysqliを使用。

現在PHPからのMySQL APIの主流は使いやすいPDO(PHP Data Object)のようですが、私は過去のmysql構文を

引き継いだmysqliの方がしっくりくる(馴染みがある)ので、mysqli(の手続き型)を使ってます。

*mysqliの先代となるmysqlは、PHP5.5以降は非推奨となり、PHP7.0以降はAPI自体が削除されてます。

 

//MySQLへの接続開始

*mysqli_connectを使います。サーバー名、ログイン名、パスワード、データーベース名(注意:テーブル名では無い)を入力。


$connect = mysqli_connect("MySQL_ServerName", "Login_UserName", "Login_Password", "DatabaseName");

 
 
//接続状態を確認
mysqli_connect_errno()にて、直前の接続コールに対するエラーコードを返り値を読み取ります。
 以下のif文では、エラーがあればtrueとなり、エラーコードを表示しています。
 PHPのdieコマンドは、メッセージを表示後、プログラムを終了させます。

if (mysqli_connect_errno()) {
  die("MySQLデータベースに接続できません:" . mysqli_connect_error() . "\n");
} else {
  echo "MySQLデータベースの接続に成功しました。";
}

 
 
//データの取り出し
* mysqli_queryを使いデータ操作を行います。今回はMySQLのSELECTを使いデーターテーブルから指定する
 columnデータ(email, member_nameなどの情報)を全て抜き出します。
 抜き出されたデータは$outputに格納されます。
* mysqli_fetch_assocを使い、$outputに格納されたデータを連想配列で取得し、$eachdataに格納します。

$data = "SELECT email, password, member_name, member_data FROM DataTableName;";
if ($output = mysqli_query($connect, $data)) {
  while ($eachdata = mysqli_fetch_assoc($output)) {
    echo "$eachdata["email"]";
    echo "$eachdata["password"]";
    echo "$eachdata["member_name"]";
    echo "$eachdata["member_data"]";
  }
}

 
 
//MySQLからの接続解
* mysqli_closeを使い、MySQLサーバーとの接続を切断します。

mysqli_close($connect);

 

PHPを学ぶためのお勧めの書籍を紹介!

マイナビ出版:よくわかるPHPの教科書

PHPを学ぶ入門書としてお勧めです。

プログラムの考え方の基礎から、PHPの基礎、MySQLのデーターベースの基本を学び、

後半は、Webアプリケーション(掲示板)を作成する内容が記載されてます。

にほんブログ村 IT技術ブログ MySQLへ
にほんブログ村

MySQLでデータをソートして読み込む

2020年05月11日 | PHP/MySQL

現在PHPとMySQLを使用して、とある団体のユーザー認証サーバーを構築してます。

秘匿性の無い情報を扱うのでセキュリティはケアせず、PHP/MySQLで各メンバーのユーザー名とパスワードを登録し、

ログインできるような環境を構築します。今回MySQLを使用するのが初めてなので備忘録として残します。


<今回のポイント>

サーバーに登録されたユーザー名を一覧で表示する際、ソートして表示したい。

 

<MySQLコマンド>

データの読み出しはSELECTを使用します。ORDER BY ...を使用することで読み出すデータをソートします。

データーベースのテーブル"TableName"からuser_nameとpasswordを読み出し、user_nameにて昇順にソートするコードです。

$query = "SELECT user_name, password FROM TableName ORDER BY user_name ASC;";

* user_nameとpasswordは読み出すデータに置き換え。

* TableNameも読み出すデーターベースのテーブル名に置き換え。

* PHPプログラム上で使用するコードです。

* 最後のASCは昇順での読み出し、これをDESCに変更すると降順での読み出しとなります。

 ASCは、昇順の英単語ascending orderの頭3文字

 DESCは、降順の英単語descending orderの頭4文字

 

もし、ID, user_name, passwordを読み出し、IDにて降順にソートする場合は以下となります。

$query = "SELECT ID, user_name, password FROM TableName ORDER BY ID DESC;";

 


PHP/MySQLを学び始めにお勧めの書籍を紹介!

マイナビ出版:PHP7 + MariaDB / MySQLマスターブック

PHP基礎、MySQLサーバー構築、また、応用としてPHP/MySQLを使用した実際のデーターベース構築まで掲載された書籍。

当方がメインで使用しているmysqliではなく、PDO(PHP Data Object)を利用したデータベース操作がメインとなってるが、

セキュリティ技術の箇所は有益な内容です。

にほんブログ村 IT技術ブログ MySQLへ
にほんブログ村