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月初旬には準備しますのでよろしくお願いします。

コルク瓶フラワーデジタル時計を作る1

以前、瓶詰めのLED時計を製作しました。実際に作ってみてすごくテンションが上がったので、

今回は、それをもっと本格的に製作したと思います。

前回作った時計を下記に置いておきます。

https://hiiragikoubou.com/index.php/2021/01/28/bottleled/

さて、本格的に作るとは具体的には、プリント基板を発注するということです。

先日、基板を発注してみたい とブログを挙げましたがこれを、瓶詰め時計でやってみようと思います。

ということでまずは、時計の基板を設計していきます。

基板を作るための手順は以下の通りです。

  • 基板CADで基板を設計する
  • 基板を発注するデータを作成する(ガーバーデータを作る)
  • 基板を発注する(Fusion PCB)
  • 基板がとどく(10日くらい)

といった手順になります。

基板CADで基板を設計する

私が使っている基板設計CADは、KiCadです。

このCadを使っている理由は、フリーソフトであることと、初めて学んだCADが、KiCadだったからです。

他のCadとしては、Eagle CADが有名です。これもフリーソフトでライブラリが充実しています。

また、一昔前はあったフリー版のEagleではサイズ制限(100*80mm)があったので制限のないKiCadが有利だったのですが、今は無いようです。

KiCadでの基板設計手順は下記です。

  • Eeschema(回路図作成エディター)で回路図をつくる
  • CvPCB (フットプリントの関連付け)で回路図の部品と基板の部品データ(フットプリント)を関連付ける
  • Pcbnew(基板設計エディター)で基板の配線をデザインする

Eeschema(回路図作成エディター)で回路図をつくる

まずは、回路図を作成してください。これが基板CADの大きな特徴です。回路図が先にできていれば、部品の接続関係がわかることになります。あとは、各回路記号に部品を当てはめておくことで基板を楽にデザインすることが出来ます。

エディターの画面はこんな感じです。

ほんとうにA4の紙に回路を描いていく感じになります。

詳細な使い方は、時間があれば今後ブログを書きたいかなと思います。

参考として、使い方のわかりやすいページを貼っておきます。

[KiCadことはじめ]

http://kicad.jp/translate/getting_started_in_kicad.pdf

回路記号でも部品のライブラリは豊富です。例えば、ATmega328と検索をかけると、

10種類程度の種類がでます。これは、QFPパッケージやDIP形など様々そろっています。

こうして、たくさん配線していって、

最終的にこのような配線になりました。

省略記号を多用していて、一見わかりづらいですが、基板を設計するという目的にはとても合理的な書き方だと個人的に思っています。ジャンパを省略することで、接続関係をすぐわかることが出来ます。よくある全部線でつながれた回路図だとたどるのが大変で接続関係のチェックが大変だと思います。

CvPCB (フットプリントの関連付け)

回路図が出来たら、次にフットプリントの関連付をします。これは書いた回路図と実際の部品データ(フットプリント)を関連付けます。

画面はこんな感じです。

画面は3列構成です。一番左が選ぶフットプリントの分類。真ん中が、回路図に置かれた部品のリスト。右が関連付けるフットプリントです。

このKicadのすごいところは、3Dデータが充実してることです。

右が関連付けるフットプリント。左が3Dデータです。1608サイズのチップコンデンサですが、結構リアルに作られています。

これらを参考にしながらフットプリントを1個ずつ関連付けます。とくにここで気をつけたいのがピンの配置です。フットプリントには必ず番号が振られており、回路図のピンにも番号があります。電子工作をある程度したことある人ならわかると思いますが、部品によってピンの配置が異なります。トランジスタ一つとっても、ECBと並ぶものやBECと並ぶものなど様々なので、最終的にはデータシートと照合してください。

基板設計で一番ミスしやすいのはこのフットプリントの関連付けです。

Pcbnew(基板設計エディター)

次に、基板をデザインしていきます。

基板デザインは、書き出すときりがないので別でまとめようと思います。

さっき関連付けたフットプリントが置かれ、回路図に従ってラッツネットという白い線が入ります。

このラッツネットを参考に線をつないでいけば、配線が完了します。

もちろん、3Dで見ることもできますし、3Dで出力して他の3DCADで開くこともできます。

基板を発注するデータを作成する

次に、基板を発注するデータ(ガーバーデータ)を作ります。

製造ファイル出力を選ぶと、下記のような画面で出力できます。詳しくは、発注先の基板メーカーのやり方に従ってください。

主に出力するのは下記の10個です。

  • F.Cu    表面の配線
  • B.Cu    裏面の配線
  • F.paste   表面のフットプリント
  • B.paste   裏面のフットプリント
  • F.silk    表面のシルク印刷
  • B.silk    裏面のシルク印刷
  • F.mask   表面のレジスト(絶縁)
  • B.mask   裏面のレジスト(絶縁)
  • Edge.Cuts  基板外形カット
  • ドリルデータ 部品穴のデータ

上記のデータが最低限必要になります。

ドリルデータの生成

あとは、この出力したデータを基板メーカーに送るのみです。

基板を発注する(Fusion PCB)

基板は、FusionPCB(seedstudio)に発注します。

【FusionPCB】

https://www.fusionpcb.jp/fusion_pcb.html

ここで先ほどの基板のガーバーデータをアップロードし、条件や個数を入力すると、

これで見積もりをかけると。

17$、およそ2000円で作ることができます。中国なので、日本への送料はおよそ12$程度。総額で3500円程度で作ることができます。

つい、一昨日注文したばかりなので届いたらまたレビューしようと思います。

基板を発注してみたい

2021年3月17日 柊工房

突然ですが、基板を基板メーカーに発注して本格的な基板を作ってみたいです。

家電や製品で当たり前に使われている回路基板、

こんなのを自分で本格的に作ってみたいなと思いました。

今まで、エッチングを使って基板を作ることはしてきましたが、見た目がこんな感じ

これもこれで味があっていいのですが、やっぱり、レジストがしっかり貼られていて、シルク印刷がある

本格的な基板を作りたいと思いました。

さっそく基板メーカーを比較。

まず日本メーカーだと、P板ドットコムが最大手かと思います。

10cm×10cm 2層基板 10枚の場合の見積もりが、

なんと、35530円。結構お値段貼りますね。そりゃそうですよね。企業の開発からしたらものすごく安いと思いますけども。個人では厳しいですね。

ほぼ同条件でunicraftでもweb見積もり。28640円

やはり、日本メーカーは三万円前後が相場のようです。

海外メーカーではどうでしょうか。

中国のSeed Fusion PCBでは、

ほぼ同条件で、$4.90 約550円。 輸送コスト含めて約3000円ってところでしょうか。

圧倒的な安さです。たとえ、歩留まりが悪かったとしても、大量に注文しても対応できそうです。

まず、本格的な基板にするのは、瓶詰めLED時計にしようと思います。

樽型Bluetoothスピーカーの製作

前回の記事にて、樽型の電源装置を製作しました。今回はその、樽シリーズの第二弾!。樽型のBluetoothスピーカーに挑戦してみました.

今回も、思い付きから作りはじめ、その日の内に完成させました。今回も、電子工作要素はほとんどありません。実は、スピーカーこそ大きいですが、それ以外の回路部分はすべて市販品から持ってきました。

使った市販品が、ダイソーのbluetoothスピーカーです。600円と大変安いですがちゃんと接続することができ、思った以上に大きい音量と、問題ない音質です。

 写真2 ダイソーのBluetoothスピーカー


  

  • ダイソーのBluetoothを分解

まずは、ダイソースピーカーを分解します。

写真3 卵型のデザイン

ダイソースピーカーは、防滴のため、シリコンカバーでおおわれています。このカバーは、簡単にこじ開けることができます。

シリコンカバーを外すと、下側に4つのネジ穴があるので、ドライバーを回してあけます。すると写真3のような基板が出てきます。

写真4 ダイソースピーカーを分解

                                        

    写真5 ダイソーBTスピーカー基板の主な回路

                              

これを、ユニバーサル基板に組み付けます。

まず、リチウムイオン電池をホットボンドで基板に貼りつけてしまいます。

 基板には、樽と固定するためのL字のナットをはんだ付けしておきます。

スピーカーは、もっと大きくて音質の良いものに変えてみました。

また、樽にもぴったりサイズです。

樽は、味のある色にするため、百均のニスを塗っておきました。

また、樽の下には、USB端子の穴や、ネジ穴をあけておきます。

 基板を写真のように差し込み、ネジ留めします。

 さいごに、スピーカーをはめてネジで止めれば、完成です。

樽型電源装置の製作

最近、実験装置を見て思うことがあります。

それは、「実験用の装置(電源装置とか、FGとか、オシロとか)って、なんでこんなに見た目がダサいのか」と。

そんな思いから、見てくれを優先した電源装置を二日で作ってみました。

以下、作り方を紹介します。

写真1 これが樽型電源装置だ 

部材について

樽は、カインズホームセンタで最近話題のおしゃれなDIY用品「kumimoku」シリーズのコーヒー樽大です。

写真2 カインズでみつけた樽

この樽に、蛇口のようなものを付け、蛇口をひねるように電圧を調節できたらと思いました。

次に回路面での検討です。

今回は、あくまでデザイン優先。短期間で製作したかったため、細かい回路設計はしたくありませんでした。そこで、主要な回路はある程度モジュールとしてまとまっており、コンデンサや端子などを外付けするだけの回路にしました。写真3が使用する部品です。

写真3 使用する部品

詳細な部品表を下記にpdfでも示します。

TR-01 の部品表

PDFはここからお願いします。

DCDCコンバータモジュールについて

電圧変換として、新電元製の可変定電圧レギュレターを使用しました。これは、出力電圧のフィードバック量を可変抵抗で調節することで、出力電圧を任意の値に調節することができます。

回路図

回路図を下記に示します。ほとんどが電源ICにまとまっているので、とてもシンプルです。スイッチングノイズ除去用の電解コンデンサ(C1,C4,C5)と発振止め用のコンデンサ(C2,C3)をとりつけ、フィードバック電圧を変える可変抵抗と補助の抵抗を付けるだけです。P1の端子には、可変抵抗の三端子をそのまま接続します。

TR-01の回路図

作ってみよう

それでは、さっそく作っていきます。

まずは、回路図通りに基板に部品をはんだ付けします。ユニバーサル基板の配線方法や、回路図の読み方を近々、下記に掲載しますので、こちらをご参考下さい。

写真5 電源基板
写真6 基板裏の配線

次に、樽のフロントパネルを作ります。フロントパネルには、加工が容易な点からコルクシートを使いました。

写真7 コルクの板を切ります
写真8 丸く切る

真ん中に、26mm口径の穴と、電圧計用の穴をカッターで開けましょう。

外郭は、ある程度適当でも大丈夫です。樽にはめるときに、その隙間がうまります。

次に、蛇口を作ります。

写真9 塩ビ管をカットする

塩ビ管を写真9のようにカットします。長さは大体で良いです。

写真10 可変抵抗を入れる穴をあける

電動ドライバーで、写真10の位置に直径8mm程度の穴をあけます。

スイッチ付きの可変抵抗にケーブルをはんだ付けします。写真の場合、黄色がスイッチ、赤茶黒が可変抵抗の線です。

写真11 可変抵抗にケーブルをはんだ付けしておく

次に、可変抵抗を塩ビ管の出口からいれます。そして、あとで出力端子につなぐ赤黒のケーブルを通しておきます。

写真12 可変抵抗を押しこむ

可変抵抗のノブの部分は、頭の穴からだし、ケーブルは、可変抵抗につながる所は、管の長い方から出します。

写真13 蛇口の配線

通しておいた、赤黒のケーブルに出力端子をはんだ付けしておきます。

写真14 出力端子をはんだづけ

このままでは、可変抵抗も端子もグラグラしてしまうので、モールドをします。

モールドに使うのは、ダイソーで売られている、グルーガンとグルースティックです。

管の隙間から注入し、最後は、写真17のようにすべて埋めてしまいます。

写真15 グルーガンとグルースティック
写真16 隙間から注入
写真17 すめてモールドで埋める

そして、樽も塩ビ管もこの色のままではダサいので、樽は、水性ニス、塩ビ管はブラウンの塗料で塗ります。

写真18 塗料で塗る
写真19 ツマミを付けると一気にそれっぽくなります

次に、コルク板にパイプを差し込み、基板と配線をします。

写真20 配管を差し込む
写真21 基板と接続

DCジャックとヒューズは、裏面につけました。

写真22 DCジャックとヒューズ

最後に、フロントパネルを樽に押し込めば完成です。

写真23 完成

どんなものも思い通りに作れるのが電子工作の楽しみと言えます。樽型電源装置を、ぜひ作ってみてください。

ドキュメント[試験管を光らせる LA-01]

試験管を光らせる LA-01

ドキュメント    内容           リリース日付
①回路図本品の電気回路の配線を図式で表します。LA-01_1X circuit.pdf2021.6.4
②基板図(表面)回路基板表面の図面、実寸大をA4示します。LA-01_1XTOP.pdf 2021.6.4
③基板図(裏面) 回路基板裏面の図面, 実寸大をA4示します。 LA-01_1XBOTTOM.pdf 2021.6.4
④ガーバーデータ基板発注時の基板データを示します。
⑤部品表使用している部品の型番、価格、仕入先を示します。LA-01-1X-part.pdf 2021.6.4
⑥プログラムコード本品に書き込まれているプログラムを示します。
⑦構造図面本体の構造を二次元図面で示します。 2021.6.4
⑧設計書回路設計過程を示します。
ドキュメント一覧

①回路図 [設計版]

本品の電気回路の配線を図式で表します。

 

②基板図(表面)

回路基板表面の図面を示します。

 

③基板図(裏面)

回路基板裏面の図面を示します。

 

④ガーバーデータ

基板発注時の基板データを示します。

⑤部品表

使用している部品の型番、価格、仕入先を示します。

⑥プログラムコード

本品に書き込まれているプログラムを示します

⑦構造図面

本体の構造を二次元図面で示します。

 

⑧設計書

回路設計過程を示します。