消しゴムレーザーポインタを作ろう

皆さんは消しゴムを加工したことがあるでしょうか。中学生の頃、退屈な授業中に、消しゴムを加工して中に機械やらコンピュータを隠したスパイグッズのようなものを作りたいと考えたものです。

今回は、消しゴムを加工して、レーザーポインタを埋め込もうと思います。秋月電子では、レーザーポインタのモジュールが380円で販売されています。これと、10円のタクトスイッチ、100円の消しゴムがあれば、レーザーポインタがたったの500円でできます。ぜひ、作ってみましょう。

写真1;これが消しゴムレーザーポインタだ
写真2;レーザーモジュールが秋月で380円

レーザーのしくみ

写真3;レーザーモジュール

レーザー光は指向性にすぐれ、明るい小さなスポットとして照らすことができるからです。

レーザーの光源は半導体レーザーです。半導体レーザーはレーザーダイオード(LD)とも呼ばれるため、発光ダイオード(LED)と混同されたりしますが、両者が放つ光は大きく異なります。発光ダイオードは“自然放出”、半導体レーザーは“誘導放出”という原理によるものです。自然放出の光(自然界の光やLEDの光など)は、波長が一定でも位相や波形がそろっていない光です。そのため、距離が長いほど光が拡散してしまいポインタのように集まりません。

一方、レーザー光は原色の波長を使うことと、結晶のレンズで集光させることで、位相も波形をそろえることで、まっすぐで拡散しない光を作ることができます。


さっそく作ってみよう

さっそく、消しゴムレーザーポインタを作りましょう。第1図が回路図です。レーザーは、使い方が難しいように思えますが、豆電球などと同じで、電池をつなぐだけで光ります。コイン電池にはCR2032、ボタンは、秋月で販売されている1cm角のスイッチを使いました。第2図の寸法で消しゴムを加工し、第3図のように取り付けます。

第2図;加工図面
第3図;部品の取り付け位置
第4図;表面
第5図;裏面

まず、第2図の寸法を消しゴムに書いていきます<写真4>。寸法に忠実になる必要はありません。部品を実際においてなぞるのもよいでしょう。表面、裏面はこのようにかきました<写真5><写真6>。

写真4本体に線をひいていく
写真5;表面
写真6;裏面
写真7;使用したルーター
写真8 ルーターで消しゴムを削っていく

消しゴムを掘るのは、彫刻刀などでもできますが、ケガしやすいのと力加減が難しいので、ルーターを使うことにしました。

まともなルーターはとても高価(1万円くらい)しますが、加工対象は消しゴムですから、そんなに高いものはいりません。近所のホームセンターで販売されていた電池式のもの(700円程度)を使います。これでも、消しゴムでしたら十分削れます。ケガに注意して削りましょう<写真8>。

少し削っては、部品をおいて深さを確かめ、また削るを繰り返します<写真9>。電池側も同じように削ります<写真10><写真11>。

写真9;実物でサイズを確認
写真10;さらに削る
写真11;実物で確認

削っている様子は、冒頭の動画にも詳しく載せますのでそちらもぜひ見てください。

写真12 不要な突起を切り落とす
写真13 切り落としたスイッチ

スイッチには突起がついています。消しゴムの厚さは11mmしかないので、これがあると収まりが悪いですので、ニッパーで切り落としてしまいましょう<写真12>。切り落とすと写真13のようになります。すこし表面が汚くなりますが、消しゴムのカバーに隠れるので問題ないです。

レーザーモジュールのケーブルは4cm程度に切り、ひふくを剥きます<写真14>。 上側の貫通穴にケーブルを通し、黒い線とスイッチをはんだづけします<写真15><写真16>。

写真14  レーザーのひふくを剥く
写真15 貫通穴に通す
写真16; 黒線とタクトスイッチをはんだづけ
写真17 赤線にスズめっき線をつける
写真18 レーザーモジュールをはめこむ

また、スズめっき線(抵抗の余り足など)を用意し、3cm程度に切ります。スイッチのレーザーをはんだづけした端子とは対角の端子に、めっき線をはんだづけします<写真17>。また、レーザーの赤い線にもう一本、スズめっき線をはんだづけしましょう。レーザーは裏側に組付けます<写真18>。

写真19 レーザーの照射口を開ける
写真20 少し顔を出す程度

また、レーザーの照射口をカッターで切り出します<写真19><写真20 >。

写真21 タクトスイッチ側のめっき線は電池の下
写真22 レーザーの赤い線は電池の上

写真21のように、スイッチにつけたスズめっき線は,電池のマイナス(下)側につなぎます。電池をセットして、電池の上に、レーザーの赤い線とつながったスズめっき線を置きます<写真22>。

最後に、消しゴムのカバーをつけて完成です<写真23>。MONOのロゴのMあたりを押すと光るはずです。どうでしょうか、無事にできたでしょうか。

写真23 カバーをかぶせる
写真24 完成

部品表 (合計500円)

記号部品名部品の内容使用数[個]購入数[袋]価格(円)店舗名通販サイトデータシート
LEDレーザーモジュール11380秋月電子通商通販リンクデータシート
スイッチ1cm角タクトスイッチ1110秋月電子通商通販リンク通販リンク
消しゴムMONO PE-04A11110文具店
部品表

瓶づめLED時計を作る

2021年1月31日

コルク瓶に自作のデジタル時計をつめこんだ、おしゃれな時計を作りました。

この時計は、はんだづけからプログラミング、装飾、プリント基板づくりにいたるまで、一から作っています。

今回は、このLED時計の製作過程を書きつづりたいと思います。

Fusion360で概要設計

まず最初に、思いついたイメージを3D-CADでモデル化しました。イメージは、コルク栓の試験管に空中配線された7セグメントLEDを立てて表示する構想にしました。試験管は、東急ハンズで販売されていた試験管(リカシツ:リム付 平底試験管 40φx190)を使うことにしました。

リカシツオンラインSHOP 【理化学用耐熱ガラスの専門店】

リム付 平底試験管 40φx190

https://rikashitsu.jp/online-shop/products/detail1201.html

〈3D設計の写真〉

3D-CADで設計

回路設計

回路図を下図に示します。

〈CK-02の回路図〉

回路図はpdfファイルにもとっております。

回路自体はとても単純です。殆どの機能をArduinoのマイコン(ATmega328-P)にまとめています。ブートローダ書込み済のマイコンを使えば、Arduinoの基板をわざわざ使わなくても、なかのICチップとクロックのみで動かすことができます。

[Arduinoを単体で動かす方法は下記のpdfがわかりやすいです]

https://akizukidenshi.com/download/ds/akizuki/ArduinBootloader_ArduinoUno_compatible_sch_20180118.pdf

また時間を数える機能は、マイコンの中ではなく、外部にRTCモジュール(M3231)をつけることにしました。

7セグLEDは、アノードコモンのオレンジ色(型番)を使い、アノードコモン側をPNPトランジスタでON/OFFします。カソード側は330Ωの抵抗を介してマイコンのデジタルピンに直接つながっています。LEDの最大電流は10mAであるため、マイコンの供給能力(20mA)で十分まかなえます。

基板設計

次に基板を設計します。基板設計はいつもKiCadというソフトを使います。

基板サイズは、コルク瓶に入れるために25mm×120mmと最初に決めました。

それに合うようになんとかして配線を押し込みます。今回は片面一層基板を使うので、線同士の交差はできません。そのため、どうしても部品を交差させるときは、5025サイズの0オーム抵抗を置いて対応します。

KiCadの便利な特徴として、3Dで表示できるのも魅力です。

最後に白紙の紙にパターンを白黒で印刷して、実際に部品を載せてピッチを確認します。

時計の基板図面をpdfにしています。

基板製作

今回は、エッチングという方法で基板を作ります。

https://www.marutsu.co.jp/pc/i/40779/

パターンは、インクジェットモードの白黒モードで印刷します。

基板はサンハヤトのクイックポジ感光基板(片面ガラスエポキシ)を選びました。基板のサイズは最小で100×150mmなので、1枚だけ切り出すにはもったいないので、3枚まとめてデータを作りました。

基板製作エッチングの方法は、サンハヤトの公式に掲載されていたのでリンクを貼ります。

https://www.sunhayato.co.jp/problem-solving/step_of_original_circuit.html

ここでは、簡単に手順を掲載します。

感光基板を露光してパターンを転写
現像液に浸して現像する
腐食液に浸してエッチング
水洗い
部品を差し込む穴をあける

はんだ付け

基板に部品をはんだ付けしていきます。

表面実装部品のはんだ付けはP板ドットコムの動画がわかりやすかったと思います。

表面実装部品をはんだ付けしていきます。抵抗のサイズは1608サイズという、ほぼお米サイズです。

7セグメントLEDは、空中配線立てます。構想してた時は不安でしたが、いざ組み立ててみると、結構しっくりきました。

基板にスイッチなどもはんだ付けすれば完成!いい感じになってきた。

ソフト設計

次に、プログラミングをします。

プログラムは、Arduinoを使って書きました。後日、プログラムも詳しく説明した投稿を載せたいと思います。

#include <DS3232RTC.h>//ライブラリーをインクルード
void setup() {
Serial.begin(115200);
DDRD = DDRD | B11111100;      //D7 6 5 4 3 2 1 0 の入出力設定(1で出力 0で入力)
DDRB = DDRB | B00111111;      //D * * 13 12 11 10 9 8の入出力設定(1で出力 0で入力)
DDRC = DDRC | B00000000;      //A* * 5 4 3 2 1 0の入出力設定(1で出力 0で入力)
//setTime(17, 31, 0, 29, 12, 2020);//初期設定 時、分、秒、日、月、年の順で入力
//RTC.set(now());//初期設定時間の書き込み
}
boolean Number_Array[11][7]={    //Number_Array[数字の数][セグ数]
                              //{g,f,a,b,e,d,c}で入力。1がOFF,0がON(アノードコモンのため)
{1,0,0,0,0,0,0},//0
{1,1,1,0,1,1,0},//1
{0,1,0,0,0,0,1},//2
{0,1,0,0,1,0,0},//3
{0,0,1,0,1,1,0},//4
{0,0,0,1,1,0,0},//5
{0,0,0,1,0,0,0},//6
{1,0,0,0,1,1,0},//7
{0,0,0,0,0,0,0},//8
{0,0,0,0,1,0,0} //9
};
//LED表示関数を定義
void Number(int x){
  for (int seg=0; seg<=6; seg++){
    digitalWrite(seg+2,-Number_Array[x][seg]);
  }
}
void loop() {
PORTD |= 0b11111100;      //D7 6 5 4 3 2をHIGH(一旦非表示にする)
PORTB |= 0b00111111;      //D * * 13 12 11 10 9 8をHIGH(一旦非表示にする)
int com[]={13,12,10,11};  //COMポートを設定{comA,comB,comC,comD}
int y[]={0,0,0,0};        //各桁に表示する数字の変数を宣言{時,時,分,分}
tmElements_t tm;
RTC.read(tm);
y[0]= tm.Hour/10;
y[1]= tm.Hour%10;
y[2]= tm.Minute/10;
y[3]= tm.Minute%10;
int dots = tm.Second%2;
dots = 255- dots *10;
analogWrite(9,dots);
  for(int i=0;i<=3;i++){        //ダイナミック点灯のループ
    digitalWrite(com[i],LOW);   //表示する桁を開ける
    int x=y[i];                 //その桁で表示する数字をxに代入
    Number(x);                  //xの数字を表示する
    delay(3);
    digitalWrite(com[i],HIGH);  //表示した桁を閉じる
  }  
}

このプログラムを、USBシリアル変換器を通して時計に書込みます。

書込みがうまくいけば、狙い通り、時間が表示される。

装飾

完成した基板をそのまま瓶に詰めました。うーん、なんかもの足りない、、、、

そこで、空いたすきまに百円ショップで購入した造花を加えてみました。

お、なんかしっくりきた。

ちなみに、電源はUSBからとっています。自作のものなので万が一、電源がショートしてしまったりする心配もしました。なので、いくらUSBだからといって、パソコンなどには刺さず、USBの充電器だけにしています(通常の充電器は、コンセントとトランスで絶縁されている、保護回路が必ずはいっているので)

完成品を棚のアンプの上にかざりました。円筒型なのでたまに転がってしまうので、なにか足になるものを作ろうと思います。

とりあえず、製作の記録としてホームページに載せてみました。

これからもいろいろなものを製作していこうと思っていますのでよろしくお願いいたします。

瓶づめマトリックスの製作

今回は、電光掲示板でおなじみの、LEDマトリックスを、コルク瓶の中におさめた時計を製作しました。全て空中配線で構成しています。

LEDマトリクス時計

と言っても回路設計からしたのではなく、

秋月電子のマトリクス時計キットを使いました。今回は、これを直径3センチ、高さ13センチの試験管に、空中配線で実装します。

秋月のマトリクスキット
部品点数は意外と少ない

秋月のキットには回路図が付属されているのでとても作りやすいです。

基本的な機能は全て、PICマイコンに集約されています。電源は、6~9V程度とかいてありますが、レギュレータで5VにしてICに供給しているようです。

今回は、USBから供給しようと思うので、レギュレータの回路は取っ払います。

空中配線といっても、一番下の土台にはユニバーサル基板を使いました。ここから、1.6mmのVVF線を柱として生やしました。

キットには回路図がついているので作りやすい
VVF線を柱に建造
マトリクスの裏にも小さい基板を配置
自立させることができる

今回は、試験管に組み込んでみました。電源は、5VのUSBをそのまま接続。

思った以上に、良い見た目です。

試験管に入れる
MFTに出展

2021.9.4 GIXIEオーディオの回路設計

前回、ブロック図で設計した回路ブロックの、回路設計に入ります。

前回示したブロック図を下記に示します。

ここで設計要素がある回路ブロックは、3つ。Audio Amplifier、Power Regulator、VU meter driverの三つです。

まず、設計したアンプの回路図を示します。

Audio Amplifer(オーディオアンプ回路)

まず、アンプの回路です。

今回は、細かい設計をしなくて済む、アンプ用ICを使いました。

ICは、PAM8304です。

D級パワーアンプIC PAM8304ASR

■主な仕様
・電源電圧:2.8~6V
・出力:
3W typ(5V・4Ω)
1.75W typ(5V・8Ω)
・ゲイン:300000/Rin
(Rin=10kΩなら30倍)
・無信号時消費電流:5mA typ(VDD=5V)
・効率:93% typ(RL=8Ω、THD=10%)
・パッケージ:0.65mm、MSOP8

**秋月電子HPより引用**

回路は、ここのデータシートに記載されている参考回路を使いました。抵抗値やコンデンサは、感覚的に決めました。

SD(シャットダウン)の端子は、プルアップしないと停止してしまうので、プルアップにしています。

 

VU meter (VUメータ―回路)

次に、VUメーターの回路です。

VUメータは、いわば直流の電流計です。音声信号を直接入力するのではなく、オペアンプで増幅して、ダイオードで整流(交流から直流に変換する)して、抵抗で電流を調節してVUメータに流します。

オペアンプには、汎用的に使えるNJM4580を使いました。

 

Power Regulator Circuit

次に電源回路です。

アンプICPAM8304の電源電圧が最大6Vなので、5Vの定電圧を流せる回路が必要になります。

回路は3端子レギュレターの一般的な回路です。C4とC5が発振防止のコンデンサ。C6がリップル除去用です。また、R5とC9でRCのローパスフィルタにもなっています。

 

三端子レギュレーター 5V1.5A TO-252 NJM7805SDL1

■主な仕様
・出力方式:シリーズ
・出力正負:正電源
・入力電圧:~35V
・出力電圧:5V
・最大出力電流:1.5A
・ドロップアウト電圧:2.2V
・許容損失:1190mW
・リップル除去比(PSRR):78dB
・パッケージ:TO-252

**秋月電子より引用**

最後に、全体の回路図を示します。

次回は、この回路の基板設計を行います。

2021.9.2 AM/FMラジオの受信原理について

・AMとFMの違いって何?

電波と言って思い浮かべるのは、ラジオやテレビの電波だと思います。しかし、電波自体は音声や映像を伝えることは出来ません。

電波に何らかの工夫を施す必要があります。

ここで音声信号と電波を合成する、変調という技法を用いて電波に乗せます。変調には、AMラジオ放送の振幅変調(Amplitude Modulation)、FM放送の周波数変調(Frequency Modulation)などがあります。

振幅変調は、搬送波(高周波)の振幅の上下を変化させる方式です。この方法は技術的に簡単で、古くから使われていますが、その性質上ノイズ(雑音)の影響を受けやすく、音質もあまりよくありません。

これに対して、周波数変調は搬送波の周波数を部分的に変化させる方法で、波形の疎密で合成します。音声信号の振幅が低いとき、送信波の波形は疎になり、高いときは密になります。

AMラジオの受信原理(包絡線検波)

AMラジオの受信原理は至ってシンプルです。受信電波の振幅がそのまま音声信号になっているわけですから、搬送波成分を取り除けばOKです。

AMラジオを、一番簡単に表した図を下図に示します。

これは、ゲルマラジオとよく呼ばれます。

 

アンテナには数多くの放送局の電波を受信します。

そのため、その中からほしい放送局を選定する必要があります。そこで、コイルとバリコン(可変コンデンサ)を並列につないだ共振回路を用意し、ほしい周波数以外の電波をカットします。

次に検波回路です。これは、ダイオードとコンデンサを使い搬送波の成分を取り除きます。

取り除いた結果、音声の成分だけが残るわけです。

この検波ダイオードはゲルマニウムダイオードを使うため、よくゲルマラジオと呼ばれています。

 

ストレート方式ラジオ

先ほど紹介したゲルマニウムラジオでは、感度も音量も小さすぎます。

そこで、一般的なAMラジオでは、同調回路、検波回路はほぼ同じ形の回路ですが、それぞれに増幅回路を挟みます。まず、感度を上げるために同調回路の出力に高周波増幅回路入れます。そしてより大きな音量で聴けるように、検波回路の出力に増幅回路を挟み、スピーカーでも聞けるようになります。

 

FMラジオの受信(スーパーヘテロダイン)

FMラジオで一般的なのは、スーパーヘテロダイン方式です。

これは、今度じっくり説明したいとおもいますが、下記に簡単に申し上げます。

スーパーヘテロダイン受信機の一番の特徴は,受信した信号を低い周波数帯に下げてから検波、復調をするという点です。周波数を下げることで,感度と周波数選択度を上げられるメリットがある.

周波数を下げるためには,下図のように,アンテナで受信した信号を局部発振回路で用意した高周波信号とミキサーで混合します。

すると、混合した波と、受信した波の差(うなり)の周波数が発生します。

このうなりを抽出し、検波(FMの電波を音声に変えること)をすることで、安定して高音質なラジオが出来ます。

今日は、ここまで。

2021.8.31 OT-01の回路設計

前回のブログでは、超音波楽器のブロック図まで設計しました。

さっそく回路設計に入ります。

下記が前回設計したブロック図です。

要するに、各モジュールをいかにしてマイコンに接続するかが大事になります。

まず、使用するマイコンのピン配置を確認します。

ATmega328PUのピン配置
ATmega328PUの各通信端子

SRF-02の接続

SRF-02はI2Cという形式で通信します。

I2Cの接続方法はとても簡単です。今回は超音波センサを2台並列でつなげられるようにします。

I2Cの通信は、センサ(Slave)とマイコン(Master)にそれぞれあるVcc,GNDの電源端子、同期クロックのSCL、信号線のSDAの4つの端子同士をつなぎます。

並列でつないでいても、それぞれのセンサにはアドレスが振り分けられているため、問題ありません。

YMF-825の接続

YMF-825はSPIで通信します。

SPIの通信は、音源IC(Slave)とマイコン(Master)にそれぞれあるVcc,GNDの電源端子、同期クロックのSCKと接続対象のSlaveを選択するSS(Slave Select)、MasterからSlaveに信号を送るMOSI(Master Out Slave In)とSlaveからMasterに信号を送るMISO(Master In Slave Out)があり、合計6本の線で構成されます。

Software Writer

ソフト書込みは前回のブログでも紹介しました。

ソフト書込みはUARTで通信しますので、変換器のTXD(送信)を,ATmega328のRXD(受信)に、変換器のRXD(受信)をATmega328のTXD(送信)に接続します。あとは、TTL変換器の+5VとGNDを、ATmega328にも供給します。そして、変換器からリセットの信号を送れるように、RTSとATmega328のResetを、0.1uFのコンデンサを経由して接続します。

Speaker Driver

YMF-825の使い方次第ではメモリーが足りなくなります。そういうときのために、単純な電子音であれば出せる、スピーカーのドライバ回路を用意しました。

以前のブログにもまとめています。

さいごにこれらの回路を統合した回路図を書きました。

次回は、KiCadで基板設計をします。

2021.8.28 GIXIEケースオーディオの設計

今回から新企画になります。

以前、謎の木の箱を分解しました。

前回のブログでは、このケースを分解して、正体をさぐる内容でした。結果として、時計だったんでしたが、時計は以前も作ったし、ギクシー管を6個もそろえるのはお金がかかりすぎるので諦めました。

そこで、せっかくこのおしゃれなケースがあるんだから、せめて何かに応用できないかと思考錯誤しました。

とくにこのケースは、直径34mmの丸い穴が6個も開いている点です。

これには、スピーカーとVUメータ―がぴったりでした。

そこで、スピーカー4つ、VUメータ2つのオーディオアンプスピーカーを作ろうと思います。

スピーカーの選定

今回は、サイズも小型なので、音質はあまり求めず、デザイン優先で作ることにしました。

スピーカーは、同じ直径34mmのものを選びました。

Amazon 小口径アルミコーン!フルレンジスピーカーユニット1.5インチ(34mm)3Ω/MAX8W

価格;590円

  • ユニット1個単位での販売です
  • 1.5インチフルレンジスピーカー
  • 15mmボイスコイル
  • アルミコーン
  • ネオジウムマグネット仕様(防磁仕様)

インピーダンスが3Ωしかないのがすこし気になりますが、おおむね大丈夫だと思います。

 

VUメータ―

VUメータ―は、最近は手に入るのかなと心配しましたが、Amazonを探すと、海外の安いものがありました。

Amazon VUパネル レベルメーター 6V〜12V 500μA 高精度 バックライト付 2個

価格;1990円

  • 材質:プラスチック、電子部品
  • ヘッダDC抵抗:630オーム
  • バックライトフィラメント電圧:DC / AC 6V〜12V
  • フィラメントによるバックライト付き500μAVUメーター
  • それはオーディオレコーダー機器で広く使われています

二個セットで1990円。結構お手頃です。

 

ブロック図

下記にブロック図を示します。

スピーカー単体のインピーダンスが低いため、一個のアンプからスピーカーを並列で接続するのは厳しいと思います。そのため、それぞれにアンプをつけなければなりません。

アンプの手前に、二連の可変抵抗を置き、これをボリュームとして使います。

音声入力から、アンプと分岐させて、VUメータのドライバを並列で繋ぎます。

また、DCジャックで任意の電圧を入れられるようにして、レギュレターの回路を入れ、各回路に供給します。

Block Diagram

次回は、これを回路図に起こします。

2021.8.26 KTF5002を分解してみた

今回から新企画です。

市販の製品を分解して、そこに秘められた技術を学びます。

今回は、AM/FMラジオチューナー、KENWOOD製のKTF5002を分解します。

これは、近所のハードオフで1500円で販売されていました。

ジャンク品だったのですがかなり状態がよく、FMラジオ、AMラジオ共に音も問題なく鳴っています。

FMラジオが受信できる

AMラジオが受信できる

まずは、このラジオについて調べてみました。

調べると、発売はなんと1997年ごろ。僕の年齢の一つ下です。

価格は25000円とお手頃価格です。

取扱説明書のpdfも上がっていたので下記にリンクを貼ります。

KTF-5002の取扱説明書

下記に仕様を示します。

 

FMラジオの受信周波数範囲は76MHz~90MHz。当時のFMラジオでは十分な帯域です。90MHz以上はアナログテレビの音声信号の帯域でした。現在は、この空いた帯域がAMラジオの補完放送(WideFM)になっています。

全高調波歪率は0.5% オーディオ機器としてはまずまずかなと思います。

個人的に驚いたのは、FMラジオのSN比が70dBであること。当時としてはかなり高い性能ではないかと思います。

また、AMのSN比は40dB。やはりFMよりノイズが多くなってしまうのがAMラジオです。

 

フロントパネル

Auto(自動選局)やスリープ、時間予約などの設定ができるみたいです。

パッと見ボリュームだと思いましたが、これは選局です。ぐるぐる回すことはできず、傾かせるだけです。

後ろはこんな感じ。FMのアンテナ端子、AMのアンテナ端子、オーディオ出力、コンセント、検波出力があります。FMのアンテナ端子はテレビのアンテナ線と同じものです。

それではカバーを外して中身を見てみましょう。

なるほど。複雑かと思いましたが中身は基板一枚に収まっていました。

さらに基板を取り出します。

ざっくりと、回路の名称を示します。

FMのフロントエンド、FMのマルチプレクサ、AMステレオの復調回路、PLL回路、電源回路等、多くの回路から成り立っています。今後のブログにて、これらの回路を一つづつ説明していきます。

今日は、分解したばかりですので、基板全体に着目します。

まず、基板の素材は、紙フェノール基板です。安価で耐久性はあまりありませんが、置き型のオーディオ機器ではこれで十分です。基板は片面一層構造で、部品は片方の面にしかついていません。そのため、線と線の交差のため、ジャンパ線が多く使われています。また、表面実装部品は、裏面についているマイコン(ぶ厚い、、)だけで、あとはすべてディスクリート部品です。部品の足が基板の裏で曲げられているところから、この部品はすべて人の手で手挿入されています。そして、人の手でカットしているのがわかります。

また、はんだづけに一切のムラがないことから、はんだ槽に基板をあてがう、フロー式ではんだ付けをしていることがわかります。マイコンだけは後付けでクリームはんだのリフローかもしれません。

正直これは、今の時代から見ると、かなり人件費がかかっているなと思います。

これを、25000円ぽっきりで売っているのはすごいと思います。

また、電源回路も注目です。

オーディオ関連の機器がやたら重いのは、電源回路にスイッチング方式を使わないからです。スイッチング方式の電源は、たとえば携帯の充電器やパソコンの充電アダプタなどです。このラジオも、スイッチングを使えば回路は軽くなりますが、スイッチングはノイズを多く発生させるため、とくにラジオの電源に使えばSN比は一気に下がります。そのため、大きなトランスを置き、昔ながらの電源回路で作るしかありません。

また、表示はVFDという表示方式です。よく、スーパーのレジで青白い文字で「ゴウケイ2350エン」って出てるアレです。今では液晶表示(電卓などの)や、LEDが多いですが、これは真空管の技術を応用した昔ながらの表示です。

これも、今後のブログで詳しく書けたらなと思います。

最後に、スイッチ類の裏側です。かなりシンプルでした。

今日は、ざっくり分解したレポートでした。今後は、下記の計画で、この製品をより詳しく分析していこうと思います。次回は、9/2にそもそもAMラジオ、FMラジオの受信原理について解説します。PLL、MPXの話も触れようと思います。

現在の連載; 「FM/AMステレオチューナーKTF-5002の分解調査」

更新日      題名          
8/26KTF5002を分解してみた(仕様、解体手順、基板構成、機構について)
9/2AM/FMラジオの受信原理(AM・FMとは、主に使われる受信方式について、PLL・MPXとは)
9/9KTF5002で使用されているICについて調べた
9/16FMフロントエンド回路、FM-IF回路、AM-RF回路 について
9/23PLL回路の原理
9/30FM-AM DET回路について
10/7FM-MPX回路について
10/14Audio AMP回路について
10/21電源回路について
10/28VFD表示回路について

 

2021.8.24 超音波楽器OT-01の構想と設計

今回から新企画です。

新しい、楽器を作ってみたいと思います。

今回のブログはその構想からブロック図の設計までをやりたいと思います。

作りたい楽器のイメージ

イメージは右図のように、超音波センサを上向きで配置します。

センサの上に手をかざして、演奏をします。かざす手の高さで音階が決まるシンプルなものです。

ブロック図

次にブロック図です。

メインとなるマイコンは、Arduinoで簡単にプログラムできる利便性から、ATmega328を使います。

超音波センサにはSRF-02を使用しました。最大2台のセンサをつなげられるようにします。超音波センサとマイコンの間は、I2C通信によって情報伝達を行います。

また、様々な音色を作れるYAMAHAの音源ICを使ったモジュールYMF-825を接続します。

これは、SPI通信にて情報交換をします。

あとは、音を出すタイミングを手動で入れられるジョイスティック。

そして、マイコンのメモリーオーバーなどで、YMF-825と超音波センサを同時に動かせないときのために、

スピーカーを直で駆動できる回路も備えます。

また、マイコンを単体で動かすので、ソフトの書込み端子を用意しなければなりません。まだ開発段階なので、RAM値を読み込めるように、UART通信により、パソコンのUSBと接続できるようにします。

次に、各ブロックを詳細に見ていきましょう。

マイコン

使用するマイコンについて、秋月電子の販売ページに簡単にまとまってたので下記に示します。

ATmega328 (秋月電子HPより引用)
ATmega328 (秋月電子HPより引用)

ATmega168のメモリ倍増版です。ブートローダと呼ばれるプログラムを書き込んだものは、Arduinoに搭載されるなど電子工作においてポピュラーなマイコンの一つです。

■主な仕様
・シリーズ:ATMEGA
・電源電圧:1.8~5.5V
・コア:megaAVR
・コアサイズ:8bit
・クロック:20MHz
・プログラムメモリ:32kB
・EEPROM:1kB
・RAM:2kB
・GPIO:23pin
・ADC:6Ch
・UART/USART:1Ch
・I2C:1Ch
・SPI:1Ch
・タイマ:3Ch
・オシレータ:内蔵/外付
・パッケージ:DIP28

**秋月電子HPより引用**

汎用性は、かなり高く、メモリー容量もまずまずです。

 

超音波センサ(SRF-02)

まず、SRF-02の通信には二つのモードがあり、I2CとUARTがありますが、今回はI2Cに焦点を当てて説明します。

まずは、SRF-02の主な特徴です。

詳しくは以前のブログを参考にしてください。

◆主な仕様
・使用マイコン:16F687-I/ML
・測定範囲:16cm~6m.
・電源:5V(消費電流4mA Typ.)
・使用周波数:40KHz.
・アナログゲイン:64段階の自動ゲインコントロール
・接続モード:モード1=I2C、モード2=シリアルバス
・全自動調整機能:電源投入後キャリブレーション不要
・測距タイミング:エコー時間計測、ホストによるタスクコントロール
・測定単位:μS(マイクロ秒)、ミリ、インチ
・サイズ:24mmx20mmx17mm
・入出力端子:5ピン
・重量:4.6グラム

音源IC(YMF-825)

ヤマハのFM音源チップYMF825(SD-1)を搭載した音源ボードについて以前のブログに掲載してますので参考にしてください。ヤマハ独自のFMシンセサイザを搭載し、数種類のパラメータ指定により豊かなサウンドを再生することが可能です。

ArduinoやRaspberry Pi等のマイコンボードから、SPIを通して直接YMF825のレジスタを制御することで発音させます。スピーカーアンプも搭載しているので、アンプ回路を別途外部に用意する必要がありません。

※3.5 mmのヘッドホンジャックを搭載していますが、iPhone用などの4極CTIA採用のイヤホンはお使いいただけません(OMTPのものはお使いいただけます)。**Switch science様の販売ページより**

**Switch science様より画像引用**

仕様

  • 4オペレータのFM音源
  • 最大16音同時に発音可能
  • FMの基本波形29種類内蔵、アルゴリズム8種類
  • SPIによるシリアルインタフェース
  • スピーカアンプ内蔵
  • 3バンドイコライザ内蔵
  • 16 bitモノラルD/Aコンバータ内蔵
  • 動作電圧:5 V
  • 3.3 Vでも改造することで利用可能

スピーカードライバー回路

スピーカーの駆動回路について以前のブログでまとめてますので参考にしてください。

この回路は、電子音を鳴らすことに特化させているので、この回路で普通の音楽を流すことには向かないとおもいます。

回路はいたってシンプルです。Arduinoからはデジタル出力の矩形波が出力される。このデジタル信号がトランジスタQ1のベースに入力される。ベースに電流を流すと、コレクタエミッタ間がONとなち、スピーカーに電流が流れる。デジタル信号のHIGH/LOWの周期によって、すぴーかーに電流を流す、流さないが変化する。したがって、デジタル信号の周波数の電子音がスピーカーから発せられる。

R1の抵抗は、デジタル信号の電流が、ベースには高すぎるので、抵抗R1を挟んで電流を小さくしている。

また、R2の抵抗も、スピーカーに流れる直流電流が大きすぎるため、R2の抵抗を挟み電流を小さくしている。

また、D1のダイオードは、スピーカーのコイルを矩形波でON/OFFしてしまうと、スピーカーの電圧が一気に跳ね上がってしまうため、電圧が跳ね上がらないようび、スピーカーのコイルにたまった電流を逃がす回生ダイオードを積んでいる。

ソフト書込み

ソフト書込みに関しても以前のブログを参考にしています。

UARTの通信ですので、変換器のTXD(送信)を,ATmega328のRXD(受信)に、変換器のRXD(受信)をATmega328のTXD(送信)に接続します。あとは、TTL変換器の+5VとGNDを、ATmega328にも供給します。

そして、変換器からリセットの信号を送れるように、RTSとATmega328のResetを、0.1uFのコンデンサを経由して接続します。

あとは、ATmega328のクロックとして、16MHzの水晶発振子を接続します。


今日はここまで。次回は回路設計に入ります。

2021.8.21 Wiiリモコンを分解した

今回は、wiiリモコンを分解しました。

一時は大人気だったwiiですが、みなさん覚えているでしょうか。

今や、ハードオフで300円で投げ売りされています。

せっかくなので、分解してみることにしました。

さっそく、開封します。

なるほど、まあこんなもんだろうな。

やはり、wiiといえばリモコンの傾きや振ったり、高さや水平移動を検知していました。さて、そのセンサはどこにあるでしょうか。

くわしく見ていきます。

本体上面の裏側にはスピーカーがついていました。

なるほど、ボタン周りはすごくシンプルです。導電体をはりつけたシリコーンのボタンを基板の接点にあてることで、ボタンの役割を果たします。

あとは、振動モーターと、前にCMOSカメラがついていました。なるほど、水平移動などはこのカメラで見ていたのでしょうか。

真ん中にあった十字のボタンは、導電体が4つ。。?と思っていましたが、一つでした。

また、接点が4つです。どの、接点同士を繋げるかで、十字の方向を決めているようです。

ジョイコンをつなげるコネクターは金メッキでした。

また、電源の入力には、ルビコン製の電解コンデンサが入っています。

基板の裏面には、ジョイスティックと通信するためのDTMFレシーバIC(BU8872)や、Wii本体と無線で通信するためIC、BLOADCOM製のBCM2042が搭載されています。また、BCM2042の四隅に、三角のパットがありました。

おそらくこれは、ノイズ試験がうまくいかなかったときに、ここに金属のカバーをつけるためのパットでしょう。

ノイズ耐性がよかったので未実装になっているのでしょう。

また、表面にはEEPROMのようなものがありました。これは、データを保管するメモリのようなものです。最低限の動作を記憶しています。

また、表面の上側に加速度センサーがありました。これでwiiリモコンの傾きを検知しています。

また、近いうちに、これらのICチップを調べて、ブログにできたらと思います。

2021.8.19 謎の箱を分解した

先日、近所のハードオフに行って、よくわからない箱と、wiiリモコンを分解用に衝動買いしました。

 

今回は、この謎の木の箱の正体を確認します。

もし、中身がなにかわからなくても、このケースはいろいろ使い道があるだろうなと思いました。

まず、上に6か所、なにかを置くスペースがあります。

そして、横には3つのボタンがありました。

 

なにかを置く場所は、二つの磁石と、その真ん中に端子が3つありました。

二つ仮説が考えられ、一つは、この二つの磁石が、それぞれ電源の+、ーになっており、真ん中の3本は信号線(3本だとSPI通信)の可能性があります。

もう一つの仮説は、磁石に電圧はかかっておらず、3本の端子のうち二つは、電源の+とー、残り1本が信号線です。データが多くなければ(7セグメント等)、サーボモータのような制御でも問題ないのかなと思います。

裏面は、DCジャックがあるのみです。

電圧は書かれておらず、怖いのでまだ電圧は掛けません。DCジャックは秋月で販売されてる2.1φのものなので、とても親近感がわきます。

それではさっそく中を開けてみましょう。

!!!!!!!!!

中はとてもシンプルでした。まず、真ん中にマイコンが一つ、クリスタル,そしてコイン電池が入っています。

基板を詳しく見てみましょう。

まず、基板から見るに、これは時計です。

表示系をコントロールするマイコンチップはATmega8A、クロックに16MHzの一般的な水晶発振子を使用しています。また、その横にあるチップがRTC(リアルタイムクロック)だと思います。

これは、時間を常に正確に刻みつづけ、現在時刻のデータをマイコンに送り続ける素子です。電源を抜いても、最省電力で時間を刻み続けられるために、コイン電池を積んでいます。コイン電池の電圧は3V、それに対し、電源から供給される電圧は5Vであるため、電源の電圧がコイン電池に流れ込まないよう、また、コイン電池の電圧がマイコン等にながれこまないために、ダイオードが二つ付いています。

また、未実装の部品もありました。まず、マイコンのとなりにある6ピンの端子は、プログラム書き込み端子です。これは、ArduinoのISP端子とつなぐことで簡単にプログラムを書き換えることができます。

また、未実装部品も気になります。とくに、JDY-16と書かれた未実装端子は気になります。これはBluetooth通信のモジュールです。おそらく、スマホなどと接続して時計をあんなことやこんなことにするためのものでしょう。オプションによってはあるんですかねえ。わかりませんが。

基板にGIXIECLOCKと書かれていたので調べました。

思ったよりすごいものを手に入れたみたいです。

やはり時計でした。

下記にリンクを貼ります。

AZUREST(アズレスト)✖️Gixie Clock (ギクシークロック )

これらはのケースは、すごく使えそうなので、なにか考えます。

とても面白かったです。

2021.8.17 Arduino 関数について

本日のTOPIC

今回は、ArduinoのVoid関数についてです。

Arduinoの関数とは、プログラムを機能ごとに分割し、特定の仕事をこなすモジュールを作成するといったことが簡単にできます。このモジュールの単位のことを関数(function)と呼びます。

関数には大きく分けて二種類あり、戻り値を返すタイプと返さないタイプに分かれます。

戻り値を返さない関数

まず、戻り値を返さないタイプのプログラムを下記に示します。

void 関数名(void) {
  
  //処理内容//

}

      関数名();      

戻り値を返さない関数というのは、関数に何かの作業だけをさせ、その作業結果をスケッチ内で特に利用しない場合に利用します。関数に対して、作業をさせるために情報を渡す(引数と言う)場合もあります。

関数の考え方は、あらかじめ省略したい処理を、一つの関数(数式?)としてひとまとまりにして作っておけば、メインのプログラムの流れに関数の名前を入れるだけで、その処理を一通りこなしてくれるため、プログラムの見た目がシンプルになり、わかりやすくなります。

下図が、プログラムの例です。

void setup() {
  // put your setup code here, to run once:
pinMode(13,OUTPUT);
pinMode(A1,INPUT);
}
void LED_ON_OFF(void) {
   digitalWrite(13,HIGH);
   delay(500);
   digitalWrite(13,LOW);
   delay(500);
   digitalWrite(13,HIGH);
   delay(500);
   digitalWrite(13,LOW);
   delay(500);
}
void loop() {
  // put your main code here, to run repeatedly:
    int a;
    a=digitalRead(A1);
    if(A==1){
    LED_ON_OFF();      
    }else{
    }
}

これを要約した図を下記に示します。

戻り値を返さないプログラム例

上の方に void LED_ON_OFF(void){ 処理 } でLEDをON/OFFするプログラムを関数化し、プログラムの途中に関数名を一言いれるだけで、関数を実行できる。

戻り値を返す関数

次に、戻り値を返すタイプのプログラムです。

戻り値があるタイプとしては、たとえば関数に計算式を入れておき、メインのプログラムから計算したいパラメータを関数に送り、関数で計算して、計算結果を戻り値として返すものです。

下記に例を示しますと、速度の計算を関数にしたいとします。

戻り値を返すタイプのプログラムの定義を示します。

int 関数名(int 変数1,int 変数2,・・・){

     実行する処理

  return 戻り値の変数;
}

  関数名(変数1,変数2・・・);

なお、intはdoubleでも構いません。また、送り値の変数はいくつあっても大丈夫です。

メインプログラムから、距離と時間のパラメータを関数に送ります。それを関数内で計算して、計算結果(速度)を戻り値として戻すわけです。

次に、プログラム例を示します。

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
}
int sokudo(int d, int s) {
   int a;
   a=d/s;
   return a;
}
void loop() {
  // put your main code here, to run repeatedly:
    int d;
    d=105;
    s=100;

    x=sokudo(d,s);
    
    Serial.println(x);
}

 

sokudoという名前の関数を整数型(int)で定義して、()内に送り値の距離dと時間sをintで記載し、計算結果をaに代入、これをreturn a;で戻り値として返します。

以上が、関数のおおまかな内容です。

今日は、ここまで。

2021.8.18 今後の目標

柊工房の今後やりたいことをまとめました。

Maker Fair Tokyoに出展したい

現在は、コロナの影響でなかなか展示会には足を運べませんが、来年以降2022年度のMaker Fairや、Nico Tech, Creema, minne様の展示会に出展したいと考えています。

現在、Creemaで販売している時計や試験管立てに加え、超音波の楽器などを展示し、今後の活動につながる人脈を形成する狙いです。

そのためにも、超音波楽器をはじめとした新たな楽器、おもしろ工作のラインナップをもっと充実させる必要があります。

柊工房のホームページを電子工作の総合情報サイトにする

私の理念は、いままで電子工作に触れる機会がない、難しそう、ダサそう、といった思い込みを払拭し、より多くの方々に電子工作を始めていただきたい。そのお手伝いができたらと考えています。そのためにも、このHPの情報量をより増やし、電子工作に関して検索すれば、大体このサイトにあたる。といった総合情報サイトを目指します。

そのためにも、今は情報量を増やすときです。日本語版を毎週火、木、土。英語版を水、金、日のほぼ毎日投稿を徹底し、情報量拡大につとめます。

ある程度、情報が増えたら、それらをまとめ、辞書のようにお使いいただける、より分かりやすいHPを目指します。

 

本を出版したい

ブログの情報がある程度そろいましたら、内容別に本を出版したいと考えています。といっても、出版社を通さずに、同人誌のような形での出版となると思います。また、Kindleなどの電子書籍でも直接出版することができるため、それらも活用したいと考えています。

YouTube配信をする

できる範囲で、Youtubeに首を突っ込みます。といっても、HPの作成でだいぶ忙しいはずなので、あくまでブログの補助教材としてYouTubeに動画をアップする形になるかと思います。

また、新しい楽器ができたら、さまざまな曲をカバーした演奏動画を出したいと思います。

2021.8.14 YMF-825を使いこなす2

前回のつづきです。

今回は、YMF-825のサンプルスケッチを用いて、様々な音を鳴らします。

サンプルスケッチは、GitHubに上がっていました。

下記を参考にしてください。

YMF-825サンプルスケッチ

このサンプルスケッチをArduinoNanoに書き込みます。

GitHubのフォルダーを開くと、下記のようなファイルが入っています。

この中の、sample1のプログラムを今回はいじります。

sample1のプログラムはこんな感じです。

/*
 Conditions only for Arduino UNO
   RST_N- Pin9   
   SS   - Pin10
   MOSI - Pin11
   MISO - Pin12
   SCK  - Pin13
 */
#include <SPI.h>
//0 :5V 1:3.3V
#define OUTPUT_power 0

// only for Arduino UNO
void set_ss_pin(int val) {
    if(val ==HIGH) PORTB |= (4);
    else PORTB &= ~(4);
}

// only for Arduino UNO
void set_rst_pin(int val) {
    if(val ==HIGH) PORTB |= (2);
    else PORTB &= ~(2);
}

void if_write(char addr,unsigned char* data,char num){
  char i;
  char snd;
    set_ss_pin(LOW);
    SPI.transfer(addr);
    for(i=0;i<num;i++){
      SPI.transfer(data[i]);    
    }
    set_ss_pin(HIGH);  
}

void if_s_write(char addr,unsigned char data){
  if_write(addr,&data,1);
}

unsigned char if_s_read(char addr){
  
    unsigned char rcv;
    
    set_ss_pin(LOW);    
    SPI.transfer(0x80|addr);
    rcv = SPI.transfer(0x00);
    set_ss_pin(HIGH);  
    return rcv;  
}

void init_825(void) {
   set_rst_pin(LOW);
   delay(1);
   set_rst_pin(HIGH);
   if_s_write( 0x1D, OUTPUT_power );
   if_s_write( 0x02, 0x0E );
   delay(1);
   if_s_write( 0x00, 0x01 );//CLKEN
   if_s_write( 0x01, 0x00 ); //AKRST
   if_s_write( 0x1A, 0xA3 );
   delay(1);
   if_s_write( 0x1A, 0x00 );
   delay(30);
   if_s_write( 0x02, 0x04 );//AP1,AP3
   delay(1);
   if_s_write( 0x02, 0x00 );
   //add
   if_s_write( 0x19, 0xF0 );//MASTER VOL
   if_s_write( 0x1B, 0x3F );//interpolation
   if_s_write( 0x14, 0x00 );//interpolation
   if_s_write( 0x03, 0x01 );//Analog Gain
   
   if_s_write( 0x08, 0xF6 );
   delay(21);
   if_s_write( 0x08, 0x00 );
   if_s_write( 0x09, 0xF8 );
   if_s_write( 0x0A, 0x00 );
   
   if_s_write( 0x17, 0x40 );//MS_S
   if_s_write( 0x18, 0x00 );
}

void set_tone(void){
  unsigned char tone_data[35] ={
    0x81,//header
    //T_ADR 0
    0x01,0x85,
    0x00,0x7F,0xF4,0xBB,0x00,0x10,0x40,
    0x00,0xAF,0xA0,0x0E,0x03,0x10,0x40,
    0x00,0x2F,0xF3,0x9B,0x00,0x20,0x41,
    0x00,0xAF,0xA0,0x0E,0x01,0x10,0x40,
    0x80,0x03,0x81,0x80,
  };
  
   if_s_write( 0x08, 0xF6 );
   delay(1);
   if_s_write( 0x08, 0x00 );
  
   if_write( 0x07, &tone_data[0], 35 );//write to FIFO
}

void set_ch(void){
   if_s_write( 0x0F, 0x30 );// keyon = 0
   if_s_write( 0x10, 0x71 );// chvol
   if_s_write( 0x11, 0x00 );// XVB
   if_s_write( 0x12, 0x08 );// FRAC
   if_s_write( 0x13, 0x00 );// FRAC  
}

void keyon(unsigned char fnumh, unsigned char fnuml){
   if_s_write( 0x0B, 0x00 );//voice num
   if_s_write( 0x0C, 0x54 );//vovol
   if_s_write( 0x0D, fnumh );//fnum
   if_s_write( 0x0E, fnuml );//fnum
   if_s_write( 0x0F, 0x40 );//keyon = 1  
}

void keyoff(void){
   if_s_write( 0x0F, 0x00 );//keyon = 0
}

void setup() {
  // put your setup code here, to run once:
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  set_ss_pin(HIGH);
 
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV8);
  SPI.setDataMode(SPI_MODE0);
  SPI.begin();

  init_825();
  set_tone();
  set_ch();
}

void loop() {
  // put your main code here, to run repeatedly:
  keyon(0x14,0x65);
  delay(500);
  keyoff();
  delay(200);
  keyon(0x1c,0x11);
  delay(500);
  keyoff();
  delay(200);
  keyon(0x1c,0x42);
  delay(500);
  keyoff();
  delay(200);
  keyon(0x1c,0x5d);
  delay(500);
  keyoff();
  delay(200);
  keyon(0x24,0x17);
  delay(500);
  keyoff();
  delay(200);
}

正直、よくわからなかったので早速書込んでみました。

なおスピーカーは、YMF-825のSPに直接繋ぎます。

実際の動作が下記の動画になります。

ド、レ、ミ、フぁ、ソまでをずっと繰り返しているようです。

どうやら、このプログラムの一番下の、void loop内の処理で音階を演奏しているみたいですね。



void loop() {
  // put your main code here, to run repeatedly:
  keyon(0x14,0x65);    //ド
  delay(500);
  keyoff();
  delay(200);
  keyon(0x1c,0x11);    //レ
  delay(500);
  keyoff();
  delay(200);
  keyon(0x1c,0x42);       //ミ
  delay(500);
  keyoff();
  delay(200);
  keyon(0x1c,0x5d);    //ファ
  delay(500);
  keyoff();
  delay(200);
  keyon(0x24,0x17);        //ソ
  delay(500);
  keyoff();
  delay(200);
}

この、keyonの中の16進数の数時(0x14,0x65)が音階を決めているようです。でも、数字に連続性もないし、10進数に変換しても、周波数ではなさそう。

いろいろ調べてみたところ、しくみはよくわかりませんでしたが、EguchiKazuyuki様のQiitaのブログにて、ここに書き込む音階のデータが示されていました。これもデータが必ずしも正確とは限らないそうなので、参照はあくまで自己責任でおねがいします。

YMF825の音階パラメータについてhttps://qiita.com/KazuyukiEguchi/items/8e7192a0114250f8898f

なので、音階は取り合えずここから参照すれば使えそうです。(大変感謝申し上げます)

次に、音色です。

設定次第で、様々な音を出せるようで、ピアノ、ギターなど自由に作れます。

サンプルコード内の、void set_toneの中の、tonedata[35]の配列の数字で決めています。



void set_tone(void){
  unsigned char tone_data[35] ={
    0x81,//header
    //T_ADR 0
    0x01,0x85,
    0x00,0x7F,0xF4,0xBB,0x00,0x10,0x40,
    0x00,0xAF,0xA0,0x0E,0x03,0x10,0x40,
    0x00,0x2F,0xF3,0x9B,0x00,0x20,0x41,
    0x00,0xAF,0xA0,0x0E,0x01,0x10,0x40,
    0x80,0x03,0x81,0x80,
  };
  
   if_s_write( 0x08, 0xF6 );
   delay(1);
   if_s_write( 0x08, 0x00 );
  
   if_write( 0x07, &tone_data[0], 35 );//write to FIFO
}

この配列を変えることで音色を変更できそうです。

音色のサンプルスケッチは、Himagine様のブログを参考にさせていただきました。

ヤマハ提供サンプル(2)https://sites.google.com/site/himagine201206/home/arduino/ymf825/030

下記に転載させていただきます。感謝申し上げます。

変換済 tonedata.txt

/*
// GrandPiano
0x01,0x43,      // modify BO:0 -> BO:1
0x00,0x67,0xFF,0x9D,0x00,0x10,0x40,
0x21,0x33,0xE2,0xA3,0x00,0x50,0x00,
0x10,0x41,0xD3,0x88,0x01,0x10,0x00,
0x21,0x62,0xD4,0x02,0x01,0x10,0x00,
*/

/*
// E.Piano
0x01,0x45,      // modify BO:0 -> BO:1
0x51,0xC4,0xFB,0x8C,0x44,0x70,0x95,
0x10,0x82,0xFF,0x12,0x45,0x10,0x00,
0x11,0xB0,0xF1,0x49,0x44,0x10,0x02,
0x11,0x72,0xFF,0x10,0x41,0x10,0x00,
*/

/*
// TenorSax
0x01,0x45,      // modify BO:0 -> BO:1
0x01,0x03,0x70,0x16,0x44,0x10,0x0B,
0x00,0x92,0x70,0x3C,0x43,0x10,0x40,
0x01,0x03,0x70,0x22,0x44,0x10,0x4B,
*/

/*
// PickBass
0x02,0x43,      // modify BO:0 -> BO:2
0x21,0x37,0xF1,0x4E,0x44,0x10,0x05,
0x41,0x6B,0xC7,0x54,0x44,0x70,0x00,
0x21,0x69,0xF2,0x5E,0x44,0x20,0x00,
*/

/*
// TnklBell
0x01,0x45,      // modify BO:0 -> BO:1
0x30,0x46,0xF5,0x41,0x44,0xE0,0x03,
0x70,0x66,0xCE,0x2E,0x44,0x20,0x00,
0x20,0x26,0xC5,0x78,0x44,0x77,0x08,
0x40,0x55,0xFD,0x04,0x54,0x60,0x00,
*/

/*
// NewAgePd
0x01,0x45,      // modify BO:0 -> BO:1
0x31,0x3F,0xF0,0x98,0x44,0x70,0x0D,
0x40,0x47,0xF0,0x2E,0x44,0x50,0x00,
0x00,0x11,0x60,0x62,0x03,0x17,0x0E,
0x00,0x51,0x81,0x02,0x03,0x10,0x00,
*/

/*
// RimShot
0x00,0x45,
0x59,0x50,0xF0,0x14,0x44,0xC0,0x17,
0x79,0x77,0xF7,0x00,0x44,0xB0,0x00,
0x68,0x6A,0xF8,0x00,0x44,0xC0,0x00,
0x78,0x77,0xF7,0x00,0x44,0x70,0x10,
*/

/*
// Castanet
0x01,0x45,      // modify BO:0 -> BO:1
0x58,0x97,0xFF,0x08,0x44,0x70,0x0E,
0x59,0xF8,0xAF,0x00,0x44,0x50,0x30,
0x68,0x55,0xF0,0x9C,0x44,0x20,0x28,
0x98,0x9A,0xCA,0x50,0x44,0x50,0x00,
*/

ここには、GrandPiano  E.Piano  TenorSax  PickBass  TnklBell  NewAgePd  RimShot  Castanetの八種類の音源があり、これをコピペすることで音色を変えれそうです。

今日は、ここまで。

2021.8.12 YMF-825を使いこなす1

本日の内容

超音波の楽器を作るにあたり、出力する音は、いろんな音が出せる方が良いと思うようになりました。

YMF-825の特徴

ヤマハのFM音源チップYMF825(SD-1)を搭載した音源ボードです。ヤマハ独自のFMシンセサイザを搭載し、数種類のパラメータ指定により豊かなサウンドを再生することが可能です。

ArduinoやRaspberry Pi等のマイコンボードから、SPIを通して直接YMF825のレジスタを制御することで発音させます。スピーカーアンプも搭載しているので、アンプ回路を別途外部に用意する必要がありません。

※3.5 mmのヘッドホンジャックを搭載していますが、iPhone用などの4極CTIA採用のイヤホンはお使いいただけません(OMTPのものはお使いいただけます)。**Switch science様の販売ページより**

仕様

  • 4オペレータのFM音源
  • 最大16音同時に発音可能
  • FMの基本波形29種類内蔵、アルゴリズム8種類
  • SPIによるシリアルインタフェース
  • スピーカアンプ内蔵
  • 3バンドイコライザ内蔵
  • 16 bitモノラルD/Aコンバータ内蔵
  • 動作電圧:5 V
  • 3.3 Vでも改造することで利用可能
**Switch science様より画像引用**

サンプルスケッチがGitHubに上がっていますので参考にしました。

・サンプルスケッチ

どんな波形も生み出せる

サンプルスケッチには、簡単なマニュアルも入っています。

YMF825が生み出せる波形

基本的な、正弦波、三角波、のこぎり波、矩形波、半波整流みたいな波、など様々です。

 

7種類の帰還が掛けれる

エフェクターや、シンセサイザーでおなじみの帰還も、7種類から選ぶことができます。

まだ、くわしく分かってないので今後、紹介させていただければと思います。

SPI通信とは

シリアル・ペリフェラル・インタフェース(Serial Peripheral Interface, SPI)は、コンピュータ内部で使われるデバイス同士を接続する方法であり、比較的低速なデータ転送を行うデバイスに利用される。

SPIは省ピンで接続できるバスとして、モトローラ(現在はNXPセミコンダクターズ)が提唱した規格であり、

信号線は4本で構成され、一つのデバイスを接続する場合はSSを固定することで3本で接続できる。

SCK
Serial Clock

MISO
Master In Slave Out

MOSI
Master Out Slave In

SS
Slave Select

SPI通信の接続(*Wikipediaより引用)

 

 

簡単な動作回路例

次に、接続図です。

YMF-825との接続

YMF-825とArduinoNanoをSPIの形式で通信するだけですので、相互の、電源ライン(+5V,GND)とSPIの端子(SCK,MISO,MOSI,SS,Reset)を接続します。

 

今日はここまで

2021.8.10 ATmega328にプログラムを書込む

本日のトピック

以前のブログで、ATmega328のブートローダを書き込みました。

今回は、この続きとして、ATmega328にArduinoと同様にプロブラムを書き込みます。

まず、プログラムを書き込むのに、PCと接続する必要がありますよね。ですが、ATmega328にはUSBがありません。

さてはまた純正のArduinoを用意するかと思いますが、もっと安いもので代用が出来ます。

それが、USB-シリアル変換器です。

USB-TTL変換器

FTDI社FT232RQを使ったUSBシリアル変換モジュールです.
・WindowsXP~10まで幅広いドライバーが有り対応しています。
・DIPスイッチで5V/3.3Vの信号レベルの変更が可能です。

端子は、+5V、GND、CTS、TXD、RXD 、RTSの六端子です。

TXD,RXDということは、そうですUARTの通信になります。

 

ATmega328との接続

次に、ATmega328との接続方法です。

UARTの通信ですので、変換器のTXD(送信)を,ATmega328のRXD(受信)に、変換器のRXD(受信)をATmega328のTXD(送信)に接続します。あとは、TTL変換器の+5VとGNDを、ATmega328にも供給します。

そして、変換器からリセットの信号を送れるように、RTSとATmega328のResetを、0.1uFのコンデンサを経由して接続します。

あとは、ATmega328のクロックとして、16MHzの水晶発振子を接続します。

Arduino IDEの設定

TTL変換器をUSBに接続すれば、あとは普通のArduinoと同様に書き込むことが出来ます。

ただ、ここで書き込めるのは、ブートローダを書込み済のマイコンに限ります。

ブートローダの書込み方法は下記に示しますので参考にしてください。

・ブートローダ書込み方法

さて、Arduinoと同様に書けるとは言ったものの、ATmega328でも、ATmega328P-PUと、ATmega328Uでは少し、設定が違います。

ATmega328P-PUの書込み設定

ATmega328P-PUは、少し割高ですが、純正品のArduino UNOと同じチップを使っているので、「ツール」を開いた設定画面では、ボード「Arduino Uno」を選び、あとはTTL変換器を繋いでいるCOMポートを選択すれば、これで書き込めてしまいます。

Arduino IDEを開きプログラミング
ATmega328P-PUの設定

ATmega328 U(ATmega328PU)

Arduinoに初期から入っているボードマネージャーでは、ATmega328は書き込めません。

「ツール」→「ボード」→「ボードマネージャー」を開き、MiniCoreと検索し、インストール。

ボードマネージャーを起動
MiniCoreをインストール

Arduinoを再起動して、「ツール」→ボード→「MiniCore」→「ATmega328」を選択します。

ボードはATmega328を選択

あとは、左上の書込みボタンで書き込めます。

学校のチャイムが鳴るLED時計の製作

先日、とあるアウトレットモールのガチャガチャコーナーで見つけた、学校のチャイムが鳴るキーホルダー。

衝動的につい回してしまいました。

詳しくはこちらに載ってました。

・カプセルトイ 学校のチャイム

[オタク向けカプセルトイ情報局]【5月再販】学校のチャイム

**カプセルトイ情報局様HPより画像引用**

だれもが青春時代に聞いていた、あの学校のチャイムを聞くことができるなつかしのカプセルトイです。

今回はこれをいろいろ改造し、以前電子工作マガジンで製作した、自作のLED時計と組み合わせ、家庭で本物のチャイムとして運用できるようにします。

組み合わせる自作LED時計

電子工作マガジン2021年春号 電波新聞社HPより画像引用

以前、電子工作マガジン2021年春号に掲載させていただいた、RTC搭載LED時計に組み合わせます。

詳しい作り方は、ぜひ電子工作マガジン春号をお買い求めください。

・amazon 販売ページ

[Amazon 電子工作マガジン2021年春号]

・電波新聞社HP

[電波新聞社 電子工作マガジン2021年春号]

この時計はArduinoを使用しているため、今回はArduinoのプログラムを少し変えて、時計にプログラムした時間に、チャイムを鳴らす機能を付けます。

学校のチャイムを分解

まずは、学校のチャイムを分解します。さて、どんな仕組みになっているでしょうか。

裏面にネジ穴が4つ開いていたので、まずは精密ドライバーで開封。

中は、こんな感じです。

思ったよりシンプルな構造になっています。

さすがは、300円のカプセルトイ。かなり簡素な設計でコストを抑えています。

中は、回路基板、スピーカー、電池BOX、磁石、だけしかありません。

基板にはほんとに何も載っていません。

写真右側にある黒い部品が、ICチップです。

これはおそらく小メモリのマイコンチップで、学校のチャイムが録音されており、それを再生するだけのシンプルなプログラムが組まれていると思います。

型番は、204HWCZ04と表記されていますがGoogleで検索してもなにもでてこないため、おそらくは中国の半導体メーカーにソフトウェアを特注で作らせているため、客先固有の型番が刻印されているのだと思います。

真ん中の黒い部品がタクトスイッチです。これは、プラスチックケースのボタンの丁度真下に来るように配置されており、ボタンを押すことでチャイムが作動します。

 

基板を展開したのが左図です。

写真左側の電池ボックスから電源を真ん中の回路基板に流します。左側の緑色の部品がスピーカーです。スピーカーの性能は、8Ω0.25Wの低電力向けの格安スピーカーです。おそらく原価は20円程度でしょう。

 

電池は、LR44が二つです。

なので、電源電圧は3Vで動作していることがわかります。

次に、基板を調べて、回路図に起こしました。

バッテリーは3Vで供給。電源に付いているコンデンサCは、パスコンと呼ばれ、電源ラインに乗っかってしまうノイズを除去し、マイコンの誤動作を防ぎます。

今回少し驚いたのが、スイッチがNPN型(押すとGNDに接続)ではなく、PNP型である点です。これは、改造に少し手間がかかりそうです。

また、スピーカーの出力が、片チャンネルではなく、スピーカーの両方の端子がICに直結していることです。

これは、おそらくBTL方式と呼ばれるスピーカーの駆動方式を採用していると思います。詳しくは、今度書こうと思いますが、低い電源電圧でもなるべく大きな音を出したいときによく使われます。この回路も、電源電圧が3Vと非常に低いため、苦肉の策でBTLが使われていると考えます。

 

学校のチャイムの改造

さて、ここからが本題です。

このチャイムを改造します。

やりたいことは、LED時計のArduinoからのデジタル出力で、チャイムを駆動させることです。

今回ややこしいのは、まず学校のチャイムのスイッチがPNP型であること。

そして、LED時計の電源電圧は、USBからの供給で5Vであり、学校のチャイムの電源電圧3Vと違っている点です。

つまり、LED時計のデジタル出力のHIGH電圧が5Vなのに対し、学校のチャイムのHIGH入力は最大3Vであるため、レベルシフトが必要な点です。

まずは、設計した回路図を示します。

今回は、トランジスタを二つ用いて改造します。

まず、チャイムを鳴らすためには、スイッチの両端を電気的にショートさせる必要があります。

そのために、PNPのトランジスタ(2SA1015)を使いました。トランジスタのベース電圧を2V以下にすることで、エミッターコレクタ間がショートし、ボタンを押したのと同様の状態になります。

また、ベース電圧を2V以下(0V)にするため、下側にNPNのトランジスタを入れます。

このNPNトランジスタをArduinoのデジタル出力によってON/OFFします。ArduinoのHIGH出力は5Vです。

そのため、間に1kΩの抵抗を挟みました。

 

学校のチャイムを加工する

まず、ケーブルを通す穴をあけます。

ケーブルを通す穴をあける
ケーブルを通す
トランジスタのリードを曲げる

その後、トランジスタのりードを曲げ、回路図通りに空中配線していきます。

PNPトランジスタを配線
NPN側も配線
LED時計のケーブルをつなぐ箇所
LED時計のプログラムを変更

下記が、変更後のプログラムです。

詳細は割愛します。

#include <DS3232RTC.h>//ライブラリーをインクルード
void setup() {
DDRD = DDRD | B11111100;      //D7 6 5 4 3 2 1 0 の入出力設定(1で出力 0で入力)
DDRB = DDRB | B00111111;      //D * * 13 12 11 10 9 8の入出力設定(1で出力 0で入力)
DDRC = DDRC | B00000000;      //A* * 5 4 3 2 1 0の入出力設定(1で出力 0で入力)
pinMode(A0,INPUT_PULLUP);
pinMode(A1,INPUT_PULLUP);     //SW1タクトスイッチの入力設定(内部プルアップ)
pinMode(A3,OUTPUT); //Alartピンの出力設定
}
boolean Number_Array[10][7]={    //Number_Array[数字の数][セグ数]
{1,0,0,0,0,0,0},//0 {g,f,a,b,e,d,c}で入力。1がOFF,0がON(アノードコモンのため) 
{1,1,1,0,1,1,0},//1
{0,1,0,0,0,0,1},//2
{0,1,0,0,1,0,0},//3
{0,0,1,0,1,1,0},//4
{0,0,0,1,1,0,0},//5
{0,0,0,1,0,0,0},//6
{1,0,0,0,1,1,0},//7
{0,0,0,0,0,0,0},//8
{0,0,0,0,1,0,0} //9
};

//チャイムを慣らす時刻の設定(1日最大10回)
int alart[10]={
  600,
  610,
  700,
  9999,
  1900,
  2130,
  2200,
  9999,
  9999,
  825
};



//LED表示関数を定義
void Number(int x){
  int z[]={10,11,12,13,9,8,7};      //{g,f,a,b,e,d,c}で入力
  for (int seg=0; seg<=6; seg++){
    digitalWrite(z[seg],-Number_Array[x][seg]);
  }
}
void loop(){  
  PORTD |= 0b11111100;      //D7 6 5 4 3 2をHIGH(一旦非表示にする)
  PORTB |= 0b00111111;      //D * * 13 12 11 10 9 8をHIGH(一旦非表示にする)
  int com[]={6,5,3,2};      //COMポートを設定{comA,comB,comC,comD}
  int y[]={0,0,0,0};        //各桁に表示する数字の変数を宣言{時,時,分,分}
  int altime = 0;           //アラート時間であることを判定する時間の変数
  int al;
  
  
  tmElements_t tm;
  RTC.read(tm);
  y[0]= tm.Hour/10;           
  y[1]= tm.Hour%10;
  y[2]= tm.Minute/10;
  y[3]= tm.Minute%10;
  int dots = tm.Second%2;
  digitalWrite(4,dots);
  for(int i=0;i<=3;i++){        //ダイナミック点灯のループ
     digitalWrite(com[i],LOW);   //表示する桁を開ける
     int x=y[i];                 //その桁で表示する数字をxに代入
     Number(x);                  //xの数字を表示する
     delay(3);
     digitalWrite(com[i],HIGH);  //表示した桁を閉じる    
  }
  if(digitalRead(A0)==LOW){
      delay(250);
      if(digitalRead(A0)==LOW){
        setTime(tm.Hour+1, tm.Minute ,0,0,0,0);//時、分、秒、日、月、年の順で入力
        RTC.set(now());//初期設定時間の書き込み
      }
  }
  if(digitalRead(A1)==LOW){
      delay(250);
      if(digitalRead(A1)==LOW){
        setTime(tm.Hour, tm.Minute+1 ,0,0,0,0);//初期設定 時、分、秒、日、月、年の順で入力
        RTC.set(now());//初期設定時間の書き込み
      }
  }
//チャイムを鳴らす判定をするPG

  altime = 1000*y[0]+100*y[1]+10*y[2]+y[3];       //現在時刻を4桁の数字にしている

  
  for(int j=0; j <= 10; j++){
      if(altime==alart[j]){
        digitalWrite(A3,HIGH);
        delay(60000);
      }else{
         digitalWrite(A3,LOW);
      }
      
  } 
}
プログラムを書き込んで完成

実際の動作がこちらです。

2021.8.7 SRF-02の使い方

本日のトピック

今回は、超音波センサSRF-02のコマンドについて調べました。

まず、SRF-02の通信には二つのモードがあり、I2CとUARTがありますが、今回はI2Cに焦点を当てて説明します。

まずは、SRF-02の主な特徴です。

◆主な仕様
・使用マイコン:16F687-I/ML
・測定範囲:16cm~6m.
・電源:5V(消費電流4mA Typ.)
・使用周波数:40KHz.
・アナログゲイン:64段階の自動ゲインコントロール
・接続モード:モード1=I2C、モード2=シリアルバス
・全自動調整機能:電源投入後キャリブレーション不要
・測距タイミング:エコー時間計測、ホストによるタスクコントロール
・測定単位:μS(マイクロ秒)、ミリ、インチ
・サイズ:24mmx20mmx17mm
・入出力端子:5ピン
・重量:4.6グラム

SRF-02の主なコマンド

次に、SRF-02で使用される主なコマンドです。

コマンドの通信方法は、ArduinoのWireライブラリを使って通信します。詳細は、以前のブログを参照してください。

I2Cでの通信方法

SRF02をI2Cモードで使用するには、モードピンをオープンにします。

I2Cの通信では、最大16個まで並列で接続できます。並列でつなぐので、それぞれのSlave(超音波センサ)にアドレスを振り分けます。
SRF02の出荷時のアドレスは0xE0です。アドレスはユーザによって変更することができ、最大16個(E0、E2、E4、E6、E8、EA、EC、EE、F0、F2、F4、F6、F8、FA、FC、FE)のアドレスが使用できます。

 

レジスタ

SRF-02には6種類のレジスタがあります。

ロケーション 読む書く
0 ソフトウェアリビジョンコマンドレジスタ
1未使用(0x80を読み取ります)該当なし 
2測定値 上位バイト該当なし
3測定値 下位バイト該当なし
4オートチューン最小-上位バイト該当なし
5オートチューン最小-下位バイト該当なし
レジスタ

 

6個あるレジスタのうち、Masterから書き込むことができるのは、0番のレジスタのみです。

すべて、0番のレジスタに数値を入れることでSRF-02の様々な設定ができます。

0番から読み出す場合は、ソフトウェアリビジョンを返されます。1番は使用していない空きピンです。

2,3番のレジスタが、測定した数値を返すレジスタです。測定値は最大2byteの容量で返します。レジスタ1個は1byteですので、レジスタが二つ(2,3)必要なわけです。この測定値は、設定の状態によって、インチ、センチ、マイクロ秒などで返します。

4、5番のレジスタは、16ビットの符号なし最小範囲です。これは、ソナーが測定できるおおよその最も近い範囲です。

つまり最初0番で指定をしたら、あとは2,3番のレジスタで測定値を参照すればよいということです。

 

SRF-02のコマンド

下記が、SRF-02の0番に指定するコマンドです。

  2進数    16進数  動作
800x50Real Ranging Mode – Result in inches
810x51Real Ranging Mode – Result in centimeters
820x52Real Ranging Mode – Result in micro-seconds
860x56Fake Ranging Mode – Result in inches
870x57Fake Ranging Mode – Result in centimeters
880x58Fake Ranging Mode – Result in micro-seconds
920x5CTransmit an 8 cycle 40khz burst – no ranging takes place
960x60Force Autotune Restart – same as power-up. You can ignore this command.
1600xA01st in sequence to change I2C address
1650xA53rd in sequence to change I2C address
1700xAA2nd in sequence to change I2C address
コマンド

必要に応じて、上記のコマンドを1番のコマンドレジスタに書き込み、必要な時間待機して結果を読み取ります。エコーバッファは、各レンジングの開始時にクリアされます。レンジングは最大66m秒持続します。この後、測定値を2,3番のレジスタから読み取ります。

SRF-02の命令方法

MasterからSRF-02に命令する場合、どのようにしたらよいでしょうか。

下記が、参考に、測定値をcmにするプログラムです。

Wire.beginTransmission(226); //通信先のアドレス
  Wire.write(0x00);    //レジスタを選ぶ
  Wire.write(0xA0);  //コマンドを選ぶ
  Wire.endTransmission();

順番としては、まず Wire.beginTransmission(226); で、Slaveのアドレス(226)を指定。

次に送信するものは、接続するレジスタになります。なにか設定などをする場合は、

0番のレジスタにアクセスするため、Wire.write(0x00);で0を送ります。

次に、送るものが設定するコマンドです。

例えば、測定値をcmで返す設定をする場合は、コマンド0x51を送ればよいので、

Wire.write(0x51);となります。

設定はこれで終了なので、 Wire.endTransmission(); で今回の通信を終わります。

コマンドの内容にもよりますが、基本は、レジスタを指定→そのレジスタのコマンドを送る、の流れです。

 

SRF-02の測定値を読み出すプログラム

次に、SRF-02から測定値を読み出す方法です。

      Wire.beginTransmission(0xE0); // transmit to device #112
      Wire.write(byte(0x02));      // sets register pointer to echo #1 register (0x02)
      Wire.endTransmission();      // stop transmitting

     
      Wire.requestFrom(0xE0, 2);    // request 2 bytes from slave device #112
    
      if (2 <= Wire.available())   // if two bytes were received
      {
        reading = Wire.read();  // receive high byte (overwrites previous reading)
        reading = reading << 8;    // shift high byte to be high 8 bits
        reading |= Wire.read(); // receive low byte as lower 8 bits
        Serial.print(reading);   // print the reading
        Serial.println("cm");
      }

まず、SRF-02から数値を読み出す場合、2番目のレジスタ0x02にアクセスします。それが、3行目までのプログラムです。

次に、SRF-02からデータを受信する準備をします。それが、 Wire.requestFrom(0xE0, 2); です。

これは、アドレスE0のSlaveから、2byteのデータを受け取りますという意味です。

あとは Wire.read();で、データを受け取ることが出来ます。しかし、2byteあるため、そのまま受け取ると下位ビットが上書きされます。そのため、まず、上位8ビットのデータを受け取り( reading = Wire.read(); )、readingのビットを (reading = reading << 8; )8bit高い位にシフトさせてから、次に飛んでくる数値(下位ビット)を ( reading = Wire.read(); ) で受信します。

Slaveで分割されたデータは、上位ビットから書き込まれる

そのまま下位ビットを書き込むと上書きされてしまう

そこで、最初に書き込まれた上位ビットを8ビット上にシフト

そのあとで下位ビットを書き込めばすべて正しく送れる

 

 

SRF-02のアドレス指定

次に、SRF-02のアドレス指定手順です。方法は簡単で、上記コマンドの0xA0, 0xAA, 0xA5,を順番に送り、最後に新しいアドレスを送ることで、アドレスを指定するモードになります。例えば、もともとのアドレスE0から新しいアドレスF4に帰る場合は下記のプログラムを動かします。とてもシンプルですよね。

  Wire.beginTransmission(0xE0);
  Wire.write(0x00);
  Wire.write(0xA0);               //A0を書き込む
  Wire.endTransmission();

  Wire.beginTransmission(0xE0);
  Wire.write(0x00);
  Wire.write(0xAA);               //AAを書き込む
  Wire.endTransmission();

  Wire.beginTransmission(0xE0);
  Wire.write(0x00);
  Wire.write(0xA5);               //A5を書き込む
  Wire.endTransmission();

  Wire.beginTransmission(0xE0);
  Wire.write(0x00);
  Wire.write(0xF4);               //新しいアドレスF4を書き込む
  Wire.endTransmission();

今日は、ここまで。

 

2021.8.7 ひいらぎ

2021.8.3 ATmega328にブートローダを書き込む

本日のトピック

今回は、市販のAVRマイコンのATmega328を、Arduinoとして使うための処理をします。

ATmega328とは、Arduinoに搭載されているマイコンチップです。

Arduinoは、定価で買うと大体3000円程度。基板も大きいので実装には不向きです。

そこで、ATmega328を単体でArduinoとして使うようにします。

ATmega328は、通販サイトで結構売られています。

ただ、最近は半導体不足によりATmega328の表面実装や、ATmega328P-PUなどは手に入りにくい状況です。

今のところ、まだ在庫はありそうです。

RSコンポーネンツで一つ323円です。つまり、Arduinoの10分の1の価格で小サイズのArduinoが使えるわけです。

RSコンポーネンツ ATmega328-PU 通販ページ

今回は、このICにArduinoとして使うためのブートローダを書き込みます。

そもそも、ブートローダとは何でしょうか。

 

ブートローダとは

ブートとは、コンピュータなどでOSなどの基本ソフトウェアを起動することを意味する俗語。ブートローダとは、このときに、OS本体や「OSをロードするためのソフトウェア」をメモリに読み込むための小さなソフトウェアを言います。このプログラムは、ATmegaマイコンを動かす上の基礎てきなソフトです。初期設定みたいなものなので、一度書き込んでしまえば、ずっと使えますし、ソフトも何回も書き換えれます。

 

ブートローダを書き込む準備

ブートローダを書き込むためには、純正品のArduinoを用意してください。ATmega328とSPI方式で通信する必要があり、そのために純正のArduinoが必要になります。

純正のArduinoは基本的になんでも構いません。私は、ブレットボードに刺せるArduino Nanoを使いました。

Arduino Nano
ATmega328PU

 Arduino NanoとATmega328PUの配線図は下図の通りです。

要するに、ArduinoNanoとATmega328でSPI通信を行いたいため、お互いのMISO、MOSI、SCKと+5V、GNDを接続します。あとは、ArduinoNanoが指定するタイミングで、328のResetをかけるため、NanoのD10と328のResetを接続し、6.8kΩの抵抗でプルアップしています。

あとは、ATmega328もクロック無しでは動かないので、16MHzの水晶発振子と定番のコンデンサ22pFを入れています。

ブートローダを書き込む接続図

実際にブレッドボードで配線しました。

ブレッドボードで配線

ArduinoIDEの設定

次に、Arduinoの書込みソフトの設定をします。

まず、書き込むICが ATmega328P-PUと、ATmega328PU(部品表記;ATMEGA328 U)では、ブートローダの書込み方が違います。これは、ATmel社がMicroChip社に変わってから、廉価版として発売されたATmega328PUは、書き込むバリアントが違うためです。

 

ATmega328P-PUのブートローダを書き込む

まず、ArduinoIDEを起動します。Arduinoのソフトのインストールは下記のリンクから行ってください。

ArduinoIDEのダウンロード

ArduinoIDEが起動したら、「ファイル」→「スケッチ例」→「11.ArduinoISP」→「ArduinoISP」を開きます。

Arduino IDEを起動
Arduino ISPを起動

まず、ArduinoNanoにArduinoISPのソフトを書き込みます。これで、ArduinoNanoを書き込み機として使えます。

その後、「ツール」を押して、ポート「Arduino Uno」、シリアルポート「ArduinoNanoを接続してるCOMポート」、書込装置「Arduino as ISP」を選択し、一番下の「ブートローダを書き込む」を押して、ブートローダを書き込むことが出来ます。

ArduinoNanoにArduinoISPのソフトを書き込む
ブートローダを書き込む

 

ATmega328PUにブートローダを書き込む

上記で、ArduinoISPをArduinoNanoにISPのソフトを書き込むところまでは同じです。

Arduinoに初期から入っているボードマネージャーでは、ATmega328は書き込めません。

「ツール」→「ボード」→「ボードマネージャー」を開き、MiniCoreと検索し、インストール。

ボードマネージャーを起動
MiniCoreをインストール

Arduinoを再起動して、「ツール」→ボード→「MiniCore」→「ATmega328」を選択します。

ボードはATmega328を選択
シリアルポート、書き込み装置を選択

あとは、「ブートローダを書き込む」を押すと書き込まれます。

これでブートローダの書き込みが完了します。

 

今日はここまでです。

2021.7.31 ArduinoのWire関数について

今回は、Arduinoで超音波センサとI2C通信を行います。

そのなかで、とくに便利なのがWire関数です。

まず最初に、I2C通信の概要を説明します。

本日のトピック

I2C通信とは

I2C(Inter-Integrated Circuit)は、フィリップス社が提唱した周辺デバイスとのシリアル通信の方式で、主にEEPROMメモリICなどとの高速通信を実現する方式です。

基本構成は、マスタ側とスレーブ側を明確に分かれており、マスタ側が全ての制御の主導権を持っています。

接続は、マスターは一機だけですが、スレーブは何機も接続することが出来ます。

接続関係

I2Cは、全ての同じ線(SDA,SCL)を並列で接続します。並列なのに個々と通信ができるのは、インターネットのネットワークと同様に、それぞれにアドレスが割り振られているからです。

アドレスは、2進数でも16進数でも10進数でも構いません。例えば16進数で書く場合は、0x70や、0x56などの形で書きます。また、マスターにはアドレスはありません。

通信をする際は、必ず最初にSlaveの宛先(アドレス)を宣言してから、データを送ります。送り先が変わるときも逐次、宛先を言います。人間の生活でも、手紙、宅配便には必ず宛先を書きますよね。それと同じです。当たり前といえば当たり前ですね。

Slaveにはアドレスが割り振られている

Wire.hの主なコマンド

ここでは、細かい説明は、なるべく省き、使い方に特化させます。

なので、まず使えるコマンドを確認しましょう。

#include<Wire.h>

I2Cで通信する際は、最初に宣言する必要になります。これは、「Wireのライブラリを使います」という宣言文で、プログラムの先頭に書きます。

 

Wire.begin();

wireライブラリを初期化します。自身がSlaveの場合は、括弧の中にアドレスを入力します。Masterはアドレスの入力は不要です。

 

Wire.beginTransmission(slave address);

カッコ内に指定したアドレスのSlaveに対して、通信を開始する準備をします。通信を始めるときは必ず宣言します。

 

Wire.write( data );

Wire.beginTransmissionで指定したアドレスに対して、Wire.writeのカッコ内のデータを送信します。基本的にデータは1byte以内です。

 

 Wire.endTransmission();

Slaveに対してのデータの送信処理を完了します。なお、WireライブラリではbeginTransmissionからendTransmissionまでのデータバッファは32byteなので送信データが多い場合は適宜endTransmissionで区切る必要があります。

Wire.requestFrom(address, byte);

MasterがSlaveにデータを要求するとき、最初に宣言します。要求する先のアドレスと、ほしいデータの容量を書きます。

Wire.available()

read()で読み取ることができるバイト数を返します。

Wire.read()

マスタデバイスでは、requestFrom()を実行したあと、スレーブから送られてきたデータを読み取るときに使用します。スレーブがマスタからのデータを受信するときにも使用します。

超音波センサにおけるI2Cのプログラム

以前のブログでお話した、超音波センサのプログラムを示します。

前回のブログでは、あまり触れていなかった通信の部分に焦点をあてます。


   #include <Wire.h>

    void setup()
    {
      Wire.begin();                // join i2c bus (address optional for master)
      Serial.begin(9600);          // start serial communication at 9600bps
      pinMode(11,OUTPUT);
      
    }

    int reading = 0;
    int SPEAKER = 11;
      int TIME=100;
      int m[9]={262,294,330,349,392,440,494,524,0 };
      int melody=0;

    void loop()
    {
     
      
      // step 1: instruct sensor to read echoes

      Wire.beginTransmission(112); // transmit to device #112 (0x70)
      Wire.write(byte(0x00));      // sets register pointer to the command register (0x00)
      Wire.write(byte(0x51));      // command sensor to measure in "centimeters" (0x51)
      Wire.endTransmission();      // stop transmitting

      // step 2: wait for readings to happen
      delay(20);                   // datasheet suggests at least 65 milliseconds

      // step 3: instruct sensor to return a particular echo reading
      Wire.beginTransmission(112); // transmit to device #112
      Wire.write(byte(0x02));      // sets register pointer to echo #1 register (0x02)
      Wire.endTransmission();      // stop transmitting

      // step 4: request reading from sensor
      Wire.requestFrom(112, 2);    // request 2 bytes from slave device #112

      // step 5: receive reading from sensor
      if (2 <= Wire.available())   // if two bytes were received
      {
        reading = Wire.read();  // receive high byte (overwrites previous reading)
        reading = reading << 8;    // shift high byte to be high 8 bits
        reading |= Wire.read(); // receive low byte as lower 8 bits
        Serial.print(reading);   // print the reading
        Serial.println("cm");
        
        if(reading>105){
          
        }else if(reading>95){
          melody=m[7];  
          tone(11,melody) ; 
          delay(TIME);
        }else if(reading>85){
         melody=m[6]; 
         tone(11,melody) ; 
         delay(TIME);       
        }else if(reading>75){
         melody=m[5];   
        tone(11,melody) ; 
         delay(TIME);     
        }else if(reading>65){
          melody=m[4];   
        tone(11,melody) ; 
          delay(TIME);     
        
        }else if(reading>55){
          melody=m[3]; 
        tone(11,melody) ; 
          delay(TIME);       
        
        }else if(reading>45){
          melody=m[2]; 
        tone(11,melody) ; 
          delay(TIME);
          
        }else if(reading>35){
          melody=m[1];  
        tone(11,melody) ; 
          delay(TIME);

        }else if(reading>25){
          melody=m[0];
        tone(11,melody) ; 
          delay(TIME);
          
        }else if(reading>15){
          melody=m[8];
          tone(11,melody) ; 
          delay(TIME);
        }
        tone(11,melody) ; 
 
      }

      delay(5);                  // wait a bit since people have to read the output :)
    }

まず、voidsetup(){ の中に、 #include <Wire.h> と Wire.begin(); が入っています。これはそれぞれ、Wireライブラリの読み出しと、Wireライブラリの初期化の意味があります。



   #include <Wire.h>

    void setup()
    {
      Wire.begin();                // join i2c bus (address optional for master)
      Serial.begin(9600);          // start serial communication at 9600bps
      pinMode(11,OUTPUT);
      
    }

メインのプログラムは、5段構成です。

まず、Wire.beginTransmission(112);で、Slaveデバイスのアドレス(112)を指定します。

次に、Wire.writeで、0x00を送信。超音波センサに通信開始する合図です。

その後、0x51を書き込みます。これは、あとで読み出す、超音波センサの距離を、センチメートルで返す設定をします。

Wire.endTransmissionで送信します。

20ミリ秒待ったのち、0x02を送信。超音波の測定値を送るようにセンサに要求しています。

そして、Wire.requestFormで、受信の準備をします。容量は2byteです。

さいご、Wire.read()で測定値を読み込むという流れになっています。



 // step 1: instruct sensor to read echoes
      Wire.beginTransmission(112); // transmit to device #112 (0x70)
      // the address specified in the datasheet is 224 (0xE0)
      // but i2c adressing uses the high 7 bits so it's 112
      Wire.write(byte(0x00));      // sets register pointer to the command register (0x00)
      Wire.write(byte(0x51));      // command sensor to measure in "centimeters" (0x51)
      // use 0x51 for centimeters
      // use 0x52 for ping microseconds
      Wire.endTransmission();      // stop transmitting


      // step 2: wait for readings to happen
      delay(20);                   // datasheet suggests at least 65 milliseconds


      // step 3: instruct sensor to return a particular echo reading
      Wire.beginTransmission(112); // transmit to device #112
      Wire.write(byte(0x02));      // sets register pointer to echo #1 register (0x02)
      Wire.endTransmission();      // stop transmitting


      // step 4: request reading from sensor
      Wire.requestFrom(112, 2);    // request 2 bytes from slave device #112


      // step 5: receive reading from sensor
      if (2 <= Wire.available())   // if two bytes were received
      {
        reading = Wire.read();  // receive high byte (overwrites previous reading)
        reading = reading << 8;    // shift high byte to be high 8 bits
        reading |= Wire.read(); // receive low byte as lower 8 bits
        Serial.print(reading);   // print the reading
        Serial.println("cm");

きょうはここまで。

2021.7.29 超音波で弾く楽器を作りたい1

本日のまとめ

 

唐突ですが、超音波で弾く楽器をつくりたいです。

設計のイメージは右図のように、超音波センサを上向きで置き、そこに手をかざして演奏します。音階はかざす手の高さによって決まっています。

 

次に、楽器のシステムを考えます。超音波センサは、以前のブログでも紹介したSRF-02を使います。また、マイコンから音を出す回路も前回のブログで書いたスピーカー駆動回路を使います。

右図が簡単なシステム図です。

超音波センサSRF02は、検知した距離をI2Cのシリアル通信またはUARTにて出力します。今回は、配線が簡単なI2Cを使うことにしました。

超音波センサからArduinoには、I2Cを経由して距離が数値で入力されます。

その数値をArduino内で処理し、音階のデータに変換して、スピーカーに出力します。

つぎにプログラムを設計するため、フローチャートを書きました。

プログラムをスタートすると、まず超音波センサの値を読み込みます。

すると、超音波センサは、かざした手までの距離をcm単位で数値を返します。

その距離を、Arduino内では、何層にも重ねたif文で条件を分岐し、各音階の周波数を割り当てます。

次に、if文内の処理について説明します。

まず、高さが105cm以上であるかないかを判別します。高さが105cm以上であれば、プログラムや音階は現状維持となります。つまり、前出した音階を継続します。105cmはかなり高い高さなので、かざしていない場合を想定しています。

次に、105cm以上がNoであった場合、次は95cm以上かどうかを判別します。95cm以上であれば、手は95cm~105cmの間にあるということですから、ドの音階を出力させます。

続いて、85cm以上ならシ、75cm以上ならラ、と分岐していき、最後、15cm以上で、下のドとなります。

それぞれ、音階を出力したら、処理はまた振り出しに戻り、センサの値を読み込むところからやり直します。

これを、プログラムのコードに直すと下記のようになります。

  #include <Wire.h>

    void setup()
    {
      Wire.begin();                // join i2c bus (address optional for master)
      Serial.begin(9600);          // start serial communication at 9600bps
      pinMode(11,OUTPUT);
    }
    int reading = 0;
    int SPEAKER = 11;
    int TIME=100;
    int m[9]={262,294,330,349,392,440,494,524,0 };
    int melody=0;

    void loop()
    { 
      // step 1: instruct sensor to read echoes
      Wire.beginTransmission(112); // transmit to device #112 (0x70)
      // the address specified in the datasheet is 224 (0xE0)
      // but i2c adressing uses the high 7 bits so it's 112
      Wire.write(byte(0x00));      // sets register pointer to the command register (0x00)
      Wire.write(byte(0x51));      // command sensor to measure in "centimeters" (0x51)
      // use 0x51 for centimeters
      // use 0x52 for ping microseconds
      Wire.endTransmission();      // stop transmitting
      // step 2: wait for readings to happen
      delay(20);                   // datasheet suggests at least 65 milliseconds
      // step 3: instruct sensor to return a particular echo reading
      Wire.beginTransmission(112); // transmit to device #112
      Wire.write(byte(0x02));      // sets register pointer to echo #1 register (0x02)
      Wire.endTransmission();      // stop transmitting
      // step 4: request reading from sensor
      Wire.requestFrom(112, 2);    // request 2 bytes from slave device #112
      // step 5: receive reading from sensor
      if (2 <= Wire.available())   // if two bytes were received
      {
        reading = Wire.read();  // receive high byte (overwrites previous reading)
        reading = reading << 8;    // shift high byte to be high 8 bits
        reading |= Wire.read(); // receive low byte as lower 8 bits
        Serial.print(reading);   // print the reading
        Serial.println("cm");
        
        if(reading>105){
        }else if(reading>95){
          melody=m[7];  
          tone(11,melody) ; 
          delay(TIME);
        }else if(reading>85){
         melody=m[6]; 
         tone(11,melody) ; 
         delay(TIME);       
        }else if(reading>75){
         melody=m[5];   
        tone(11,melody) ; 
         delay(TIME);     
        }else if(reading>65){
          melody=m[4];   
        tone(11,melody) ; 
          delay(TIME);     
        
        }else if(reading>55){
          melody=m[3]; 
        tone(11,melody) ; 
          delay(TIME);       
        
        }else if(reading>45){
          melody=m[2]; 
        tone(11,melody) ; 
          delay(TIME);
          
        }else if(reading>35){
          melody=m[1];  
        tone(11,melody) ; 
          delay(TIME);

        }else if(reading>25){
          melody=m[0];
        tone(11,melody) ; 
          delay(TIME);
          
        }else if(reading>15){
          melody=m[8];
          tone(11,melody) ; 
          delay(TIME);
        }
        tone(11,melody) ; 
      }
      delay(5);                  // wait a bit since people have to read the output :)
   }

ここで、新たに登場した関数は、wire関数です。

#include<Wire.h>

Wire.hの関数をincludeで呼び出しています。Wire関数は、I2Cのシリアル通信を行う最に使う関数で、Wire.read();などで、シリアルのデータを読み込むことができるなどします。

私もこの関数は知らなかったのですが、少し奥が深そうなので、後日まとめて掲載できたらと思います。

 

さっそくブレッドボードで配線を組みました。

次回は、これの動作チェックをします。

2021/7/29 ひいらぎ

2021.7.27 tone関数を使いこなす

Arduinoのプログラム[tone関数を使いこなす]

次に、tone関数を用いてArduinoから音を出していきましょう。

tone関数

tone関数のリファレンスは、

tone(pin, 周波数 , 出力時間);

です。なお、出力時間は、省略して書くこともできます。

さっそく、下記のプログラムを作ってみました。

void setup() {
  // put your setup code here, to run once:
pinMode(11,OUTPUT);
}

void loop() {
int TIME=300;
  // put your main code here, to run repeatedly:
tone(11,262,TIME) ; // ド
delay(TIME) ;
tone(11,294,TIME) ; // レ
delay(TIME) ;
tone(11,330,TIME) ; // ミ
delay(TIME) ;
tone(11,349,TIME) ; // ファ
delay(TIME) ;
tone(11,392,TIME) ; // ソ
delay(TIME) ;
tone(11,440,TIME) ; // ラ
delay(TIME) ;
tone(11,494,TIME) ; // シ
delay(TIME) ;
tone(11,523,TIME) ; // ド
delay(TIME) ;
}

 

このプログラムは、ドレミファソラシドを0.3秒ごとに切り替えて、出力するプログラムです。

使っている関数を、いくつか紹介します。

pinMode(pin, OUTPUT);

Arduinoの各入出力ピンが、出力なのか入力なのかを設定します。例題のプログラムでは11番ピンを出力に設定しているので、pinMode(11,OUTPUT);となります。入力に設定する場合は、pinMode(11,INPUT); また、pinMode(11,INPUT_PULLUP);で、入力をプルアップに設定できます。

 

int 変数=数値;

整数の変数を定義するときにint関数を使います。ほかにもfloat , char,doubleなどがありますが、奥が深いので、いつかまた紹介できたらなと思います。

delay(時間);

プログラムを指定した時間だけ遅延させます。単位はミリ秒です。また、マイクロ秒で指定する場合は、

delayMicroseconds(時間);で指示できます。

 

さて、次に音を鳴らす回路です。回路は、前回のブログでも作成した、スピーカーの回路を使います。

 次に、プログラムの内容は同じですが、配列とfor文を使って、短く簡単にまとめたプログラムです。

だいぶ、短いプログラムになりました。

void setup() {
  // put your setup code here, to run once:
pinMode(11,OUTPUT);
}

void loop() {
  int TIME=300;
  int m[8]={262,294,330,349,392,440,494,523};
  
  // put your main code here, to run repeatedly:

  for(int i=0;i<8;i++){
    tone(11,m[i],TIME) ; 
    delay(TIME) ;
  }
}

このプログラムは、先ほどと同じ、ドレミファソラシドを0.3秒ごとに切り替えて、出力するプログラムです。

使っている関数を、いくつか紹介します。

int 変数[データ数] ={数値1,数値2,数値3,・・・};

配列は、大量の数値を同時に宣言するのに便利です。例のプログラムの場合は、ドレミファソラシドの各音階の周波数をまとめて宣言するため、配列を使い、

int m[8]={262,294,330,349,392,440,494,523};

と表現しました。これを使うとき、例えばレの音の周波数を出したければ、2番目の数値を呼び出すので、0,1 で,

m[1]

が、レの変数になります。呼び出すときの数値は、0からスタートする点に注意しましょう。

 

for(初期値 ; 条件式 ; 加算){    };

for文は波カッコに囲まれたブロックを繰り返し実行します。様々な繰り返し処理に活用でき、データやピンの配列と組み合わせて使われることがあります。

例題のプログラムの場合、

for(int i=0;i<8;i++){

tone(11,m[i],TIME) ;

delay(TIME) ;

}

で、加算させる変数 i の初期値を0にし、これが8以下であるうちは、{}内のプログラムを繰り返し実行します。

実行するプログラムは、tone関数で、iの数値に割り当てられた周波数を出力し、TIME㍉秒待機します。

これを、7回、音階を上げながら実行するため、ドレミファソラシドの順に音が鳴るプログラムになります。

 

本日は、ここまでにします。次回は、超音波センサと組み合わせて、音階を鳴らす楽器作りをします。

 

2021/7/27 ひいらぎ

2021.7.25 Arduinoから音を出す(回路編)

さて、次はArduinoのトーン関数を使って、音を出そうと思います。Arduinoのトーン関数は、 

出力するピンと周波数、出力時間を入力するだけで音を出すことができます。

といっても、Arduinoにスピーカーがついているわけではないですから配線をしていかなければなりません。

下図が、Arduinoからスピーカーを駆動する回路です。

さて、まずはこの回路の部品を確認していきましょう。

回路図

スピーカー

スピーカーは、電気信号を音に変換する部品です。基本構成は、コイルでできており、交流信号を流すことで、振動板が前後に触れ、空気を震わせて音が出ます。

トランジスタ

トランジスタは電気の流れをコントロールする部品です。
半導体でできた能動部品の代表と言われるぐらいとても重要な部品で、いろんな電子回路で活躍しています。この回路では、スピーカーに流す電気は大きく、マイコンで直駆動させることは難しいため、トランジスタを間に挟みます。

ArduinoNano

Arduinoは、簡単なC言語のプログラムで、あらゆる出力信号を出すことが出来る。また、アナログ入力を7個積んでいて、分解能255でアナログ値入力できるため、精度の良いセンサーを作ることができる。詳しくは、どこかで説明したい。

スピーカー駆動回路

回路はいたってシンプルです。Arduinoからはデジタル出力の矩形波が出力される。このデジタル信号がトランジスタQ1のベースに入力される。ベースに電流を流すと、コレクタエミッタ間がONとなち、スピーカーに電流が流れる。デジタル信号のHIGH/LOWの周期によって、すぴーかーに電流を流す、流さないが変化する。したがって、デジタル信号の周波数の電子音がスピーカーから発せられる。

R1の抵抗は、デジタル信号の電流が、ベースには高すぎるので、抵抗R1を挟んで電流を小さくしている。

また、R2の抵抗も、スピーカーに流れる直流電流が大きすぎるため、R2の抵抗を挟み電流を小さくしている。

また、D1のダイオードは、スピーカーのコイルを矩形波でON/OFFしてしまうと、スピーカーの電圧が一気に跳ね上がってしまうため、電圧が跳ね上がらないようび、スピーカーのコイルにたまった電流を逃がす回生ダイオードを積んでいる。

次回は、Tone関数を利用して簡単にArduinoから音を出します。

2021/7/25 ひいらぎ

2021.7.24 超音波センサを使いこなす1

先日、八潮の秋月電子で超音波センサを買いました。

今回は、超音波センサSRF-02をがんばって使いこなそうと思います。

超音波センサ(SRF02)

超音波センサ

◆主な仕様
・使用マイコン:16F687-I/ML
・測定範囲:16cm~6m.
・電源:5V(消費電流4mA Typ.)
・使用周波数:40KHz.
・アナログゲイン:64段階の自動ゲインコントロール
・接続モード:モード1=I2C、モード2=シリアルバス
・全自動調整機能:電源投入後キャリブレーション不要
・測距タイミング:エコー時間計測、ホストによるタスクコントロール
・測定単位:μS(マイクロ秒)、ミリ、インチ
・サイズ:24mmx20mmx17mm
・入出力端子:5ピン
・重量:4.6グラム

[秋月電子より引用]

さて、まずは超音波センサの仕組みを確認しましょう。

超音波センサーは、今や自動車の駐車センサや障害物検知など、自動運転などにも欠かせない技術となっています。

まず、超音波とはなんでしょうか。

 

超音波とは

超音波は、広義的に言えば、ただの音です。なぜ、超が付くかと言いますと、それは音の周波数が人間が聞き取れないくらい高いからです。

下図が、音波の分類です。

超音波のスペクトラム

音は、音の高さ(周波数)によって分けられ、20kHzより高い音を超音波と定義しています。

人間が聞き取れるのは、成人では17kHz程度まで聞き取れます。そのため、多くの音楽データでは20kHz以上の音はデータとして記録していません。また、マイクやスピーカーの特性も、20kHz以上の音はほとんど出ない設計であり、その分音波の範囲で最大の性能を発揮できるように作られています。

その、聞き取れない超音波域の音も出すことで、豊かな音になるとうたっているのが「ハイレゾ音源」です。ですが、そもそも人間が聞き取れない音を出すことは、本当に意味があるのか、私もわかりません。

さて、余談が過ぎました。

超音波センサは、空気を伝搬させるため、超音波の中でも比較的低い音で使用します。超音波は、周波数が高いほどまっすぐ進み、密度の濃い媒体の中も良く通ります。そのため、おなかの中を通り抜けなければならないエコー検査装置の超音波は3GHzと高い帯域を使います。

それに対し、障害物センサなどの超音波は、媒体が空気と薄いこと、さらになるべく広い範囲を検知する必要があることから、音波ギリギリの40kHzなどが使われます。

さて、超音波の特徴がわかったところで、つぎは、超音波センサが障害物を検知するしくみを確認します。

 

超音波センサの検知

超音波センサは、超音波を放出するスピーカーと、超音波を受信するマイクからなります。

最近の超音波センサは、スピーカーとマイクが一体型になっているパターンがほとんどです。

超音波の送受信1

センサーから放出した超音波は、音速の速さで進みます。

これが、障害物にあたると、超音波はやまびこのように反射して帰ってきます。この帰ってきた反射波をマイクで拾い、検知します。

もし障害物が無ければ、なにも反射せずに検知できません。

超音波の送受信2

 

また超音波センサは、障害物までの距離も算出することが出来ます。

その仕組みは下図のように、超音波の発信から受信までに要した時間と音速との関係を演算することでセンサから対象物までの距離を算出します。

超音波の送受信3

超音波は、音と同様、音速の速さで進みます。音速は340m/sです。

音速をv 距離をrとし、超音波を放出してから反射波を受信するまでの遅延時間をtとすると、

距離 r = (v× t )/2 で導けます。

例えば、遅延時間が10m秒だった場合、往復距離r は、340×0.01= 3.4m

したがって、障害物までの片道距離は、1.7 mとわかります。

 

超音波センサSRF-02

さて、超音波センサを使いましょう。

秋月のページには、メーカーの製品情報が載っていました。

ここに、詳細な説明とプログラム例のwikiが載っています。

ここに乗っていた、サンプルプログラムを使うことにしました。

接続は、下図の通りです。

Arduinoとセンサの接続図

超音波センサとの通信方法は、二種類選ぶことができ、I2CとUARTから選ぶことが出来ます。

I2CとUARTの特徴は、後程まとめさせていただければと思います。

超音波センサにヘッダピンをはんだ付けして、ブレッドボードに差し込みます。あとは、接続図の通りに配線をして完成。

さっそく、パソコンにUSBをつないで、プログラムを書き込みます。Arduinoの使い方なども後程説明させていただければと思います。

Arduinoのスケッチ

これを書き込むと、センサから障害物までの距離をリアルタイムで見ることができます。

さっそく手をかざしてみます。Arduinoのシリアルモニタを確認すると、センサから手までの距離がリアルタイムで表示されていることがわかります。

 

今日はここまでにします。明日は、超音波センサを使った楽器について構想を練ります。

 

2021/7/24 ひいらぎ

光る試験管立て LA-01C

LA-01C(光るヒノキの試験管立て)
木曽ヒノキを使用した、光る試験管立てを作りました。
コルク付きの試験管にお花のハーバリウムを造れば、優しい色合いの光が幻想的に照らします。
また、コルクを外せば、一輪刺しとしてもお使いいただけます。
試験管をセットする土台は、木曽ヒノキを使用しております。

LA-01C本体1
LA-01C本体2

Creemaにて今後、販売を予定しております。


光るヒノキの試験管立て(木曽ヒノキ)【販売準備中】

型番; LA-01C

価格; 3880円+税

在庫; 0 個


★香りと質感の良い木曽ヒノキを使用
日本三大美林の一つに数えられている木曽ヒノキは、軽軟・肌目は緻密で特有の芳香と美しい光沢をもちます。耐湿、耐水性にも強く長持ちすることから、桧の中でも高級品として人気が高く、寺社建築をはじめ高級建築材としても使われています。また伊勢神宮では、木曽桧が式年遷宮の「御神木」として利用されています。

 

★試験管にお気に入りの花を飾ろう
試験管には何でも入れていただけます。お好きな花やドライフラワーなどを飾る、コルク栓を外して一輪刺しなどに使うこともできます。ガラス管はコルク栓で密閉出来ますので、液体なども可能です。ハーバリウムなどを作るのも良いでしょう。

★試験管はプロ仕様
付属の試験管は、化学実験向けの本格的な試験管を使用。耐久と耐熱に優れています。

★LEDは和風な色合い
本機では和風な色合いをベースに、紅梅色、薄桜色、橙色、女郎花色、青磁色、白藍色、瑠璃色、江戸紫色の計8色が、10秒間隔の自動で変化します。

 

★梱包内容
光る試験管立て本体 x 1 
ガラス試験管x1
試験管用コルク栓×1
USBケーブル 70 cm x 1 
ハーバリウムオイル(45mL) x1
説明書 x1  
**ハーバリウムの造花は付属しておりません**

仕様

項目内容備考    
型番 LA-01C
サイズ [本体];50mm×50mm×50mm(立方体)
[試験管];直径25mm 長さ100mm (平底試験管)
材質 [本体] 木曽ヒノキ(木材)
[試験管] ガラス(硬質1)
主機能 試験管の照光
色種類 紅梅色→薄桜色→橙色→女郎花色→青磁色→白藍色→瑠璃色→江戸紫色
(色は10秒ごとに順番に変化します。)
環境温度範囲 -20℃~40℃(できる限り涼しい環境でお使いください)
電源入力範囲 標準DC5V(USBを使用)
消費電力 最大1W(5.0V 200mA) 
付属ケーブル USB-TypeC 70cm(スイッチ付き)
本体の温度上昇 40℃以下(室温25℃時)
仕様

★購入の際の注意点
✔裏側の黒い回路基板は、最大60℃まで発熱いたしますが安全上問題ありません。

✔ヒノキの質感をお楽しみいただけるよう、本体外側にはコーティングや塗装などは一切しておりません。そのため日焼けや腐食は市販の木製製品より早く進みます。なるべく日陰に置いていただき、湿度の高い環境での使用はお控えください。

✔完全に手作りです。手作りの電子回路基板ですので慎重にご利用ください。

✔試験管はガラス製ですので破損にはくれぐれもご注意ください。

✔試験管立て本体に、水などがかからないようご配慮ください。

✔裏側は、黒い回路基板が露出した構造になっております。

ハンドメイドなため家電メーカーが製造する家電製品ほど、品質を保証しておりません。
なにか不具合等ございましたら下記にご連絡ください。
E-mail ; hiiragikoubou5883.gmail.com

サボテンの骨について調べてみた

先日、東京新木場の木材専門店「もくもく」にいきました。

https://www.mokumoku.co.jp/

国内の貴重な木材(木曽檜、コクタン、神代杉、屋久杉等)から、海外の木材まで、100種類以上を取り扱っています。そのなかで見つけたのがサボテンの骨です。

お店で最初見たときは、「サボテンの木。。。?」と思わず言ってしまってたのですが、完全に失礼でしたね。

「サボテンの骨」ですよ。

サボテンは、砂漠などの過酷な環境で生育しています。サボテンと言えど、砂漠では 雨が降らない日が続くと自然枯死し、緑色の幹は「木」に変化していきます。 そうなったのが、サボテンの骨だそうです。さっそく2本購入しました。ほかの木材との相性も良さそうなので、なにか工作ができそうです。

googleでサボテンの骨を検索すると沢山、飾り方の例が載っています。

そのまま飾る方も多いようですが、穴がたくさん開いているので、どうやら小さい草花を詰めて飾っている方が多いようです。なるほど、、、

 

でも私はこれを、光らせたいなと思います。

サボテンの骨は、中が空洞状になっているため、下からLEDでライトアップしたら、お洒落じゃないかなと思いました。

さっそく実験しました。

サボテンの骨の下から、試験管立て(LA-01)の基板を当てて光らせます。

なかなか良いのではないでしょうか。

本格的に、作ることにしました。

さっそく、3D-CADでサボテンの骨を置く、光る台を設計しました。基板は、試験管立ての基板を流用します。ドーナツ状に開いている穴から、光が出ます。

この台座を右図のように立てます。台座には、檜の切り株を使いました。

  

下図が設計図になります。切り株の裏側から、ホールソーでΦ35の穴をあけ、基板を取り付けるシンプルな構造です。あとは、USB端子を格納するための穴をΦ7.5で開けています。

今日は、設計まで行いました。

次回は、これを加工していきます。

光る試験管立てを設計する[基板編]

前回のつづきになります。

さっそく、kiCadを使って基板を作っていきます。

まず、回路図はこちらです。

試験管ランプの回路図

 

回路図をもとに、部品ライブラリを関連付けます。

部品の関連付け

さて、ここから配線をしていきますが、まずわからなければならないのが、基板サイズです。

 まずは、試験管立てから設計しました。

そこで、3D-CADで設計しました。

表面
裏面

ホームセンターで45mm×45mmの太さの木材を買い、これを100mm感覚で切り出せば簡単に確保できます。

木材は、35mmのホールソーで基板をはめる穴を裏から開けます。表からは、25mmのホールソーで試験管を差し込む穴をあけます。

2Dの図面を下記に示します。

LA-01図面

よって、基板を入れるサイズが直径35mmと決めましたので、基板サイズは直径34mmが丁度いいかなと思っています。

基板サイズがわかったので、さっそく基板設計です。

基板設計の手順は改めてまとめたいと思います。参考にしてのは下記のサイトです。

kicadの教科書

基板は、2層基板で設計しています。

基板の内容を下図に示します。基板の給電はUSB-typeCから行います。

また、電源、色切替、明るさ調節などは、すべて一個のホームボタンに集約しました。

あとは、ソフトを書き込む端子と、今後、同じ製品内で、2,3か所光るポイントが増えたときに、同じ基板を複数連携させて動かしたいので、今後のために、信号の入力端子と出力端子を用意しました。あとは、基板を固定させるためのネジ穴Φ3.2を二か所に開けてあります。

基板の詳細

表面と裏面はこんな感じです。基板の表面の真ん中がポッカリとスペースが開いています。ここに、フルカラーLEDを置きます。

基板(裏面)
基板(表面)

これを、2次元図面にすると下図になります。

基板表面

 

基板裏面

図面が出来たら、現物確認をします。

図面を実寸大で印刷して、実際に部品を上に置いてサイズが合っているかを確認します。

これで、設計完了です。次回は基板を業者に発注します。

光る試験管立てを設計する[回路編]

さっそく、光る試験管立ての設計をしていきます。

製作するものは前回のブログにもしめした、光る試験管立てです。

試験管を光らせたい

まずは、ブロック図を描きました。

ブロック図

試験管を、フルカラーLEDを用いて、カラフルに光らせたいと思います。フルカラーLEDは、Red Green Blueの三原色のLEDの明るさを調節することで、どんな色にも調節することが出来ます。また、光はそこそこ強い光を出したかったので、オプトサプライ社が出している、最大出力1WのハイパワーフルカラーLED(OSTCWBTHC1S)を採用しました。そのため、マイコン直結では電流が足りないため、NchのMOSFETを間に挟みます。

今回は、基板の面積をかなり小さくしなければならないため、極小のマイコン ATtiny202を使用しました。

ATTiny202の仕様を簡単にまとめました。これがなんと一個40円。破格の安さです。

・電源電圧:1.8~5.5V
・コア:tinyAVR
・コアサイズ:8bit
・命令長:16bit
・クロック:20MHz
・プログラムメモリ:2kB
・EEPROM:64B
・RAM:128B
・GPIO:6pin
・ADコンバータ:6Ch
・UART/USART:1Ch
・I2C:1Ch
・SPI:1Ch
・タイマ:2Ch(16bit×2)
・パッケージ:SOP8

マイコンのサイズ(秋月電子HPより)

メモリー容量は、2kBしかありません。テキスト文字だと3000文字程度でしょうか。とても少ない容量なので、書き込めるブログラムも単純なものしかできません。ですが、3色のLEDを光らせる程度であればこれで十分でしょう。

 

つぎに、LEDです。

LEDは、三原色が入ったフルカラーLEDを採用しました。

・標準電流:150mA
消費電力: 1W

・VF
赤…2.5V
青、緑3.3V
・ΦV
赤…22ルーメン
緑…35ルーメン
青…12ルーメン
・λD
赤…624nm
緑…525nm
青…460nm
・2θ1/2:120°

秋月電子HPより引用

 

出力電力は1W 。標準電流は150mAという高輝度。とてもまぶしいです。

まずは、回路図を書いてみました。

LA-01 回路図

今回使用するLEDは、電流値がとても高いため、マイコンの出力端子に直接接続して動作させることは難しいです。

そのため、各LEDにはNチャンネルのMOSFETを接続し、制御できる電流値を増やします。

LEDの明るさはマイコンからのPWM信号によって調整します。

次にLEDの制限抵抗(R5,R8,R11)の抵抗値を計算します。

FETが完全にONになった場合、FETを省略して、回路は抵抗とLEDだけにすることが出来ます。

必要な情報は、LEDの標準電流と電圧です。

IF=150mA  VF:赤…2.5V  青、緑3.3V

電源電圧からLEDのVfを引き算した値が、抵抗の端子間電圧になります。抵抗にも、LEDにも150mAの電流を流すわけですから、制限抵抗の抵抗値は、

青;  R=V/I = 1.7V / 150mA = 11.33[Ω]

緑;  R=V/I = 1.7V / 150mA = 11.33[Ω]

赤;  R=V/I = 2.5V / 150mA = 16.66[Ω]

となります。

しかし、こんなぴったりな抵抗値の抵抗器はありませんから、E24系列に存在する抵抗値で一番近いものは、

青;  11.33[Ω]=10Ω

緑;  11.33[Ω] =10Ω

赤;  16.66[Ω] =15Ω になるでしょうか。

次に、この抵抗値を適用した場合の実電流を計算します。

青;  実電流 If [mA] = V/R = 1.7 / 10 =170 [mA]

緑;  実電流 If [mA] = V/R = 1.7 / 10 =170 [mA]

赤;  実電流 If [mA] = V/R = 2.5 / 15 = 166[mA]

この電流値が、LEDの定格電流以下であることをデータシートから確認します。

LEDのデータシート

LEDの直流定格は、200mAであるため、余裕があります。また、本機はPWMのパルス制御をするため、PluseForward Currentを使用します。すると定格は250mA。抵抗の誤差分を考慮しても十分余裕があるかと思います。

実際は、FETの損失が加わるため、端子間電圧は低めに出るはずです。

次に、抵抗の損失を計算します。

青;  抵抗(青)の損失 Pr [W] = V * If = 1.7 V*170mA = 289 [mW]

緑;  抵抗(緑)の損失 Pr [W] = V * If = 1.7 V*170mA = 289 [mW]

赤;  抵抗(赤)の損失 Pr [W] = V * If = 2.5 V*166mA = 415 [mW]

となります。赤だけ損失が大きいですね、、、。

以上から、選定する抵抗は、0.5W定格以上のものを使用するのが良いかと思います。

次に、FETの選定です。

FETのドレインソース間には、最大で170mAの電流が流れているわけですから、それ以上のドレイン電流を流せる必要があります。金額や性能的に、BSS138を選びました。

BSS138 (秋月より引用)

 

 

・構造:MOSFET
・回路数:1
・チャネル:N
・ドレイン・ソース間電圧:50V
・ゲート・ソース間電圧:±20V
・ドレイン電流(DC):300mA
・ドレイン・ソース間オン抵抗:1.6Ω
・許容損失(25℃):350mW
・パッケージ:SOT-23

次に、FETの損失を求めます。

FETの損失をLTSpiceでシミュレーションしました。本当は、BSS138のSpiceモデルでできればよかったのですが、うまく追加できなかったので、RdsやVdsが近い値のFETでシミュレーションしました。

シミュレーション結果

ここから、IdsとVdsを掛け算した、電力のジュール積分値は、44.49uJ

PWMのパルスは500Hzなので、500*44.49u = 22.24 mW

このFETの熱抵抗θjcは、350℃/Wです。

周囲温度25℃の場合のジャンクション温度は、Tj = 25+(350 ×0.02224) = 32.78 ℃。

最大電流でも、+7.78℃の温度上昇なので、あまり影響がないと考えます。

回路図

よって、この回路図で決定します。次は、これをもとに基板を設計します。ではまた。

試験管を光らせたい

先週、東京の清澄白河にある、コルク瓶の仕入れ元、「リカシツ」のお店に行ってきました。

[https://rurubu.jp/andmore/article/7921]

リカシツは、理化医療用ガラスの卸業の関谷理化株式会社が運営する、「理化学+インテリア」を目指したアンテナショップです。実際に研究室でプロが使用している理化学製品そのモノと理化学ガラス職人が加工したオリジナルなモノを販売しています。

昨今では少子化で学校・研究所の統合などで理化学ガラス職人の仕事も減っている中、一般の方に使ってもらいアイデアを貰うことで理化学ガラス職人の技術が活かせる「新たな仕事つくり」ができると考え、アンテナショップができたそうです。(リカシツHPより要約)

実際に行きましたが、とても洒落な空間が広がっていました。

理科の実験って、こんな映えるんだなあと。新しい価値観にびっくりします。

リカシツで衝動買いしたのが、木でできた試験管立てです。

もう、お店で見た瞬間から、光らせたくてたまらないです。

そこで、試験管立てには、裏から穴をあけ、試験管には造花を詰めてみました。

いろんな色のLEDを下から入れて光らせました。かなり、いい感じじゃないですか。

もう、これは基板化決定です。フルカラーLEDと小さなマイコンでカラフルに光らせる基板を作ろうと思います。

さっそく回路設計

コルク瓶フラワーデジタル時計を作る2

前回のブログの続きになります。

さて、発注した基板が届きました!

基板はメイン基板が10枚、サブ基板が40枚です。

このように、ちゃんとパック詰めで届きます。

結構しっかりできています。

このように部品をはんだづけしていきます。

はんだが予め印刷されているのでとてもつけやすくなっています。

LEDをはんだづけしたら、かなりそれっぽくなりました。

基板を瓶に詰めて造花でアレンジするとこんな感じになりました。

悪くないんじゃないかなという感じです。

暗闇でもそれはそれで味が出ています。

今回の工作はかなり満足です。初めて基板発注してみて、案外簡単にできたので、これからは基板は作らずに発注します。

また、基板があと9枚、余ってしまったので、これは近々、完成品をハンドメイドサイトで販売しようと思います。

5月初旬には準備しますのでよろしくお願いします。