はじめに
博士です。こんにちは。
前回は全文検索のミドルウェアとしてApache Solrの記事を書きましたが、今回はハードウェアに挑戦です。
パトランプを回すために、電子回路の設計と電子部品の選定,マイコンプログラムの作成を行っていきます。
構成を考えてみる
なにかと連動してパトランプを回せるようにしたいですよね。
なので、PCと接続できる方が面白そうです。ざっくり、以下のような構成でしょうか。
今回用意したパトランプは、下の図のものにしました。車用のもので、シガーソケットに接続して12Vを得るタイプです。
制御回路の部分は悩むところです。
Arduinoやkonashiといったものを使えば、素早く構築できそうですが、
高機能故にお値段もそれなりにしてしまいます。
なので今回は、素のマイコン+αでパトランプを制御することにします。
部品選びと回路の設計
マイコン
まず、PCとパトランプの橋渡しをする装置として、マイコンを選びます。
そもそも、マイコンとは、マイクロコンピュータの略で、役割的には普通のパソコンのCPUとだいたい同じです。
違う点は、パソコンだとCPUの他にもメモりやらなにやらいろいろ載せないと動かないのに対して、マイコンは動作に必要なものがこれ一つに入っているところでしょうか。
そういえば、炊飯器とかについてますね。あれは、マイコンを使ってお米を炊く際に調節を行っているのが特徴だから「マイコン式」と呼ばれています。
使うのはAtmel社のAVRです。小さすぎず大きすぎず、もしかしたらほかにもセンサーとかつけるかも…!という感じで、ATtiny2313Aを使うことにします。150円。
※ちなみに、今回の場合だと、ATtiny13Aという、さらに小さいサイズでも問題なさそうです。
マイコンとPCの接続
ただ、マイコンは直接PCと接続することはできません。なので、PCとマイコンをRS232という規格で接続します。RS232は、一番シンプルな構成だと、お互いの持つTxとRxという信号線をクロスして、Tx-Rxとなるように接続することでお互いにデータを送り合うことができます。(LANのクロスケーブルのような感じです。)
ちょっと前のPCにはCOMポート(シリアルポートとも呼ばれる)というものがついており、そこを利用できたのですが、最近のPCにはもうほとんどついていないと思います。
その代わりに、USBを仮想のCOMポートとして利用できるUSBシリアル変換モジュールというものがあります。 この手のモジュールは種類がいくつかあるのですが、今回は秋月電子で売られているFT232RL USBシリアル変換モジュール(下の図)を使います。950円。
※RS232という通信規格は、BluetoothやZigBeeなどの無線でも使えるようなモジュールが既にあるため、USBシリアル変換モジュールのかわりに置き換えて無線化することが可能ですが、結構お高いです。
パトランプを回す電源
さて、12Vのパトランプを回したいのですが、USBからは5Vしか取り出せません。電圧を5Vから12Vへと変換する昇圧回路というものもあるのですが、電圧を高くすると流せる電流が減ってしまうため、豆電球を光らせる+モータを回せるかどうか、不安です。なので、パトランプ用に別の電源を用意した方が良さそうです。
今回は、12V-1Aのスイッチング電源と、それを接続する際に使う便利なモノを使うことにします(下の図は、その便利なもの。)。650円+100円。
電子的なスイッチ
あとは、マイコンでパトランプをON/OFFできるようにすれば、制御回路的には十分そうです。
電子回路でON/OFFする代名詞と言えば、トランジスタでしょうか。ざっくり説明すると、電流を流すとつながるスイッチと考えてください。
今回は、2SC1815という定番のNPN型トランジスタ使いました。8円。
電源の異なる回路を物理的に分離
今回、ここで気をつけなければいけないのが、電源が別、ということです。
USB(=PC)から5Vを、パトランプ用の電源から12Vを取っている場合、それぞれのGNDは共通ではありません。
なので、トランジスタで直接パトランプをON/OFFせず、回路を分離します。
分離にはいくつか使えるものがあるのですが、今回はリードリレーのSS1A05Dを使います。
これも、役割的にはトランジスタと同じで、電流を流すとつながるスイッチになります。
ただ、トランジスタと違う点は、電気的に絶縁できる(=回路を分離できる)ことと、流せる電流が多かったり、モノによってはより高電圧にも耐えられる、といった利点があります。
欠点は、トランジスタに比べて物理的に動く部品があるため、遅い、というところです。リレーは、電流をコイルに流した際に起きる磁界を利用して中にある金属を引き寄せる(または、引き離す)ことで、スイッチをON/OFFします。70円。
※分離するという役割には、フォトカプラというものも使えます。こちらは、磁界ではなく光を使ってスイッチをON/OFFします。
回っているモータは電源
最後に、回っているモータに流す電気を止めたときに発生する電気を逃がすためのダイオードを追加します。
モータは電気で回りますが、電気を与えずにモータを回すと電気を生み出します。回転するエネルギーと電気エネルギーを変換する、発電機ですね。ところが、電気には方向があって、生まれる電気の向きが与えていた電気と逆になります。そのため、電池を逆に繋いだのと同じ状態になり、最悪、機器が壊れてしまいます。それを防ぐために、ダイオードを使って、逆向きの電気が生まれたときだけつながる回路を作っておきます。
ダイオードときくと、なんとなく光りそうなものですが、こちらは整流ダイオードといって、電流を一方通行で流すためのものです。35円。
ざっくり書いた手書きの回路図
さて、上記で紹介した部品を使うと、以下のような感じの回路になりそうです。
一部、簡単に説明します。
トランジスタは、この部分になります。
マイコンとトランジスタのベース端子を、抵抗を介してつなげてあります。ベースに電流が流れると、コレクタ端子からエミッタ端子に電流が流れます。
リレーは、この部分になります。
左側が、先ほどのトランジスタとつながっており、トランジスタのON/OFFによってこのリレーのスイッチもON/OFFされるようになっています。
SS1A05Dには、ここで示した回路が一つになって入っているため、とても便利です。
最後に、パトランプはこれです。
パトランプは、構成的には豆電球とモータです。
そして、逆起電力用にダイオードを入れてあります。リレーのスイッチが切れた際に、モータが電源となり、ダイオードを通る回路を形成します。瞬間的に結構な高電圧が逆方向に加わってしまうためほかの素子を守るための対策です。
ブレッドボードで動作確認
さて、電子回路と言えば半田付け…の前に、この回路で本当に動くのかどうかを確かめたいと思います。
たくさん穴の開いたブレッドボードというもの(下の図参照)を使います。250円x2。
ちなみに、半田付けをしてしまうと、回路の手直しをしたい場合に結構苦労します。
ブレッドボードに部品を全て差し込み、配線まですませたのが、以下の図です。
回路完成!
マイコンプログラミング
さて、回路ができたので、次はマイコンのプログラミングです。
開発に必要なモノ
今回使うAVRマイコン用のコンパイラはいくつかあるのですが、C言語で開発したいので、今回はavr用にクロスコンパイルされたgccとavr-libcを使います。
Macの場合、公式ではないですが、homebrewでいくつかFormulaeが公開されているので、avr-gccなどで調べてインストールすると手軽だと思います。
Windowsの場合、同じgccベースのWinAVRがよいと思います。
プログラム作成
コンパイラの準備が整ったら、プログラムを作ります。
必要な処理としては、シリアル通信を行う処理と、シリアル通信で受信したパケットによってマイコンの出力を変更する処理になります。
通常のCのプログラムと同様に、main関数からプログラムはスタートします。
ioinit関数内で、マイコンのPCとの通信速度(Baudrate)の設定や、入出力ポートの設定を行っています。
その後、PCからのシリアル通信のデータを受信するのを待っています(uart_getchar関数内loop_until_bit_is_set関数で受信を待っています。)。
シリアル通信で、0xfe 0x01を送ると、リレーにつながるトランジスタをONにし、それに伴ってリレーがONになり、パトランプが回り始めます。
0xfe 0x02を送ると、0x01とは逆に、リレーにつながるトランジスタをOFFにし、それに伴ってリレーがOFFになり、パトランプが止まります。
#include <avr/io.h> #define F_CPU 8000000UL #define BAUD 19200 #include <util/setbaud.h> //ATtiny2313 では PD0:RxD PD1:TxD #define UART_RX 0 #define UART_TX 1 #define OUT_RELAY 0 #define sbi(PORT,BIT) PORT|=_BV(BIT) #define cbi(PORT,BIT) PORT&=~_BV(BIT) /** * * PB0: リレーのON/OFF信号を出す。 * PD0: UARTのRX * PD1: UARTのTX * */ void ioinit(void) { sbi(DDRB, OUT_RELAY); sbi(DDRD, UART_TX); cbi(DDRD, UART_RX); UBRRH = UBRRH_VALUE; UBRRL = UBRRL_VALUE; #if USE_2X sbi(UCSRA, U2X); #else cbi(UCSRA, U2X); #endif // UART受信 sbi(UCSRB, RXEN); sbi(UCSRB, TXEN); UCSRC = 0b00000110; } void uart_putchar(unsigned char c) { loop_until_bit_is_set(UCSRA, UDRE); UDR = c; } unsigned char uart_getchar(void) { loop_until_bit_is_set(UCSRA, RXC); return UDR; } int main(void) { ioinit(); for(;;) { unsigned char c = uart_getchar(); uart_putchar(c); switch(c) { case 0xfe: c = uart_getchar(); switch(c) { case 0x01: sbi(PORTB, OUT_RELAY); uart_putchar(0x11); break; case 0x02: cbi(PORTB, OUT_RELAY); uart_putchar(0x11); break; default: uart_putchar(0xee); } break; default: uart_putchar(0xee); } } return 0; }
これを、以下のMakefileでコンパイルします。(ファイル名はmain.cを想定)
OBJS=main.o TARGET=avr-patlamp CC=avr-gcc OBJCOPY=avr-objcopy MCU=attiny2313 CFLAGS=-mmcu=$(MCU) -std=c99 -Os all: $(TARGET).hex $(TARGET).elf: $(OBJS) $(CC) -o $@ $(OBJS) $(TARGET).hex: $(TARGET).elf $(OBJCOPY) -I elf32-avr -O ihex $(TARGET).elf $@ clean: rm $(TARGET).hex $(TARGET).elf $(OBJS)
コンパイルしてできた.hexファイルを、マイコンに書き込みます。
マイコンにプログラムを書き込む
書き込むためのデバイスと、ソフトを用意しなければなりません。
我が家に眠るPololu社のUSB AVRプログラマを、ここで活用します。
ちなみに、国内だとスイッチサイエンスさんで2400円前後で購入可能です。ほかにも、ISP mkIIなど、書き込むためのデバイスはいくつかあります。
また、卵が先か鶏が先かになりますが、自作もできます。
書き込むためのソフトも複数あるのですが、僕はavrdudeを使っています。
便利なことに、Macだとhomebrewで入れられます。
また、WindowsでもavrdudeとそのGUIフロントエンドが入手可能です。
先ほどのデバイスとマイコンを、プログラムを書き込む為に接続します。
書き込む前に、一つ、忘れていました。
#define F_CPU 8000000UL
この記述は、マイコンの動作周波数を定義しています。このソースでは8MHzを想定しているのですが、このマイコンは購入時のデフォルトでは1MHzで動作するようになっています。
そこで、8MHzで動作するように動作するようにマイコンの設定を変えます。
これは、ヒューズビットと呼ばれるマイコン自体の設定ができる領域を持っているのですが、その中のCLKDIV8(内部発振回路の周波数を1/8にして使う)というフラグをOFFにしてあげることで、簡単に出来ます。
※ヒューズビットの計算は、このサイトが便利です。
> avrdude -P /dev/tty.usbmodem00041081 -c avrispv2 -p attiny2313 -u -U lfuse:0xe4:m -U hfuse:0xdf:m -U efuse:0xff:m
また、もらったマイコンだと、この辺りの設定が変わっていることがあるので、一度確認した方がよいと思います。
気を取り直して、以下に示すのは、Macでavrdudeをターミナル上から動かして、書き込みを行った際のログになります。 Windowsだと、/dev/tty.usbmodem00041081の部分がCOMになります。
> avrdude -P /dev/tty.usbmodem00041081 -c avrispv2 -p attiny2313 -e -U flash:w:avr-patlamp.hex avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.07s avrdude: Device signature = 0x1e910a avrdude: erasing chip avrdude: reading input file "avr-patlamp.hex" avrdude: input file avr-patlamp.hex auto detected as Intel Hex avrdude: writing flash (406 bytes): Writing | ################################################## | 100% 9.66s avrdude: 406 bytes of flash written avrdude: verifying flash memory against avr-patlamp.hex: avrdude: load data flash data from input file avr-patlamp.hex: avrdude: input file avr-patlamp.hex auto detected as Intel Hex avrdude: input file avr-patlamp.hex contains 406 bytes avrdude: reading on-chip flash data: Reading | ################################################## | 100% 9.09s avrdude: verifying ... avrdude: 406 bytes of flash verified avrdude: safemode: Fuses OK (E:FF, H:DF, L:E4) avrdude done. Thank you.
書き込みが終わったら、ライタを外します。
これで、シリアル通信で命令を送れば、パトランプが回るようになります。
今回のプログラムでは、マイコンと接続するにはBaudrate 19200bps, 8bit, パリティ無し, ストップワードが1の設定でつながります。
接続する際の設定をそれにあわせてください。フロー制御も必要ありません。
パトランプを回す
これで、完成です。
動画では、fe 01をマイコンに送ってパトランプを回転させ、fe 02を送ってパトランプを停止させています。
[video width="640" height="360" flv="http://technica.speee.jp/wp-content/uploads/2014/09/patlamp.flv"][/video]
まとめ
今回は、PCから操作できるパトランプを作りました。
ちなみに、たとえば、Raspberry PIを使うのであれば、GPIOを使って直接トランジスタに電流を流せるため、マイコンやUSBシリアル変換が不要になります。また、同様にRS-232Cでの接続にも対応しているため、USBシリアル変換が無くてもマイコンと接続できます。
本当は、動作確認後にユニバーサル基盤を使って半田付けまでしたいのですが、一旦、動いたので良しとしましょう!うんうん。
あと、これは余談なんですが、マイコンを逆にしたまま電源をつなぐと、ブレッドボードが熱で変形するぐらい、指で触ると水ぶくれができるぐらい発熱します。
そのまま気づかずにいると多分燃えるので、本当に気をつけてください。熱かったです。
最後までお付き合いいただきありがとうございました。