勉強会用

processingやopenframeworksで自分が作っていったものの過程など

勉強会_FET実習

FETでファンを動かしてみよう

やること

  1. FETを用いた回路図の説明
  2. 配置決定
  3. はんだ付けについて
  4. ファンを動かしてみる
  5. その他コツ

1. FETを用いた回路図 

FETとは

https://www.google.co.jp/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=FET%E3%81%A8%E3%81%AF


簡単にいうと大きな電流や電圧のものを
増幅やスイッチングしてくれるもの。

今回はArduino単体では動かせない
12Vだったり電流が20mAを超えるような
ファンを動かす実習。

電池Ver.
 

f:id:yuitoshi:20161221183646j:plain  f:id:yuitoshi:20161221191522j:plain

 

DCジャックVer.
電池がDCジャックになっただけ。

f:id:yuitoshi:20170608001015p:plain

今回はこれをユニバーサル基板に実装していく。
回路のモータ部分に入れたい負荷を入れる。

 

■ 材料

 

では、簡単な説明...

○FETのゲート・ソース・ドレイン

f:id:yuitoshi:20161222011952p:plain

基本的にはゲートに電圧を与えるとドレインとソースがつながると思えばいい。

  • ゲートにarduinoからの信号でON/OFFの調整 (PWMなど)
  • ドレイン側に負荷のマイナス側
  • ソース側にGND

 

○FETのゲート部分

FETのゲートに対してスイッチングをする信号を与える。
そこにかませる抵抗は1kΩでもOK。
トランジスタとは違い、抵抗の細かい値はそこまで気にしないみたい。

信号は負荷の強さを変えることができるPWMを使う。
 (ArduinoのI/O pin の”~”マークがついてるピンがPWM)
このpinからFETのゲートに信号が入った時のみ、負荷に電流が流れる。

今回使うFETである2sk2232は応答性が悪いので、
しっかりとしたPWMをやりたい方は
FET IC?というものを使うといいらしい。

 

ダイオードをかませる理由

上の回路を見ると、負荷に対して並列にダイオードを入れている。

理由としては
モータから発生する逆電流を防止するため。
電流が逆に流れた時、負荷には流れないように
ダイオードで道を作ってあげている。

逆電流が発生しないだろうと思われるものや、
また元々、逆電流防止のダイオード
入っているファンなどでは必要はない。

 

○アダプター

負荷の電圧や電流が比較的高くArduino単体では動かせないものを想定している場合
電源は外部から供給する必要がある。
そういう時はアダプターを使う。

 

f:id:yuitoshi:20161221194821p:plain

AC/DCアダプターにもアンペア数の制限はある。

今回用いる負荷がどの程度のアンペア数に耐えるかを見てアダプターを選ぶ。
今回上にあげたファンは1Aが定格なので、1.5Aや2Aのアダプターを用いる。

 

また、今回用いるDCプラグですが、基本的には真ん中が ➕ ,外側が ➖ である。
しかし、面倒なことに  と  が逆の場合もある。
壊れる原因になるのでどちらが  か判断をしてから使うのがよい。

 

http://akizukidenshi.com/download/img/dc-jack-polarity.png

 

DIP化キット

アダプターを使いDCプラグから基板へと電源を受け渡すため、
DCジャック DIP化キットを用いる。

f:id:yuitoshi:20161221201511p:plain

これはブレッドボードにも挿せるのでジャックからの電源を
2.54mmピッチの回路に直したいときはこれを使うのがよい。

 

2. 配置決定 

先ほどの回路をユニバーサル基板に実装していく。

今回は下の基板を用いる。

片面ユニバーサル基板 Dタイプ(47x36mm) ガラスコンポジット: パーツ一般 秋月電子通商 電子部品 ネット通販

こちらのデータシートにある基板の図を用いて
今から実装する回路がちゃんと入るのか、
どう配線するのか設計していく。

 

渡されたプリントに直接書いてみてください。

 

今後使うには、どこにヘッダを使えばいいかも含めて考えてみよう。
(基本的には壊れる可能性のあるものは、取り替え可能な設計にしておくのがベスト)
FETが壊れやすい場合はそれもソケットなどを用いておいて
取り替えられるような回路にしておく。
(ex 水やバブルがつきやすい回路とか...)

 

解答例として下の画像を参考に。自分なりに設計をしてみよう。

f:id:yuitoshi:20170608002644p:plain

 

3.はんだ付け

次の動画を見てはんだ付けを覚えよう。
細かいコツは実習を通して見ていく。
僕が見た中での良記事はこれ

sandersonia-elec.com

 

○他には下の2つの記事も参照に

ハンダ付けのコツ::まほろば

はんだづけの方法・コツ | 作り方をサポート!DIYレシピ DIY FACTORY オンラインショップ

 

○1点アース
GNDの半田付けはできる限り一点にまとめるとよい。
やらなくてもそんなに問題はないけども。

http://www.picfun.com/partgnd.html


今回, 人数が多くはんだごてが足りない(と思う)ので2班に分かれて作っていく。
はんだ実習ができない班はFritzingで回路を作る実習。

Fritzing Fritzing

 

4.動かそう

回路ができたらあとは自由に動かしてみる。
ArduinoのExampleのBasicにあるfadeを使ったり
余裕がある人はprocessingやらOFやらでスライダーでPWMを変えられるようにしてみよう。

 

5.その他コツ系Q&A

Q1. 引っ張るとよくケーブルが取れるけどどうすれば良い?
A. テンションがかからない工夫をする。
 グルーガンで止めておいたり、少しケーブルの途中で余裕を持たせ、s字で止めておく。
 またコネクタを使うと楽。僕はxhコネクタを使う。正直使いやすいコネクタならなんでもok.

Arduino工作の圧着コネクタ(QI)について


Q2. ケーブルがバラバラで邪魔なんだけど...
A. 結ぶ、リボンコードのようなものを使う,熱伸縮チューブでまとめる

 

Q3.はんだ付けしたくない。

 ->圧着でコネクタとつなぐ方法
 ->圧着+ネジで止める

はんだ付けしない電子工作教室 by てきーらサンドム

 ->絶縁テープでとめるなど
現場に絶縁テープがあると何かと便利です。半田付けしなくて済むかも

「はんだ」を使わない電子工作 - 実践で習得!電子回路

 

Q4. Arduinoからジャンプワイヤー通して基板と対応付けるのが面倒or一体化させたい
->シールド基板 

Arduinoで自作シールドが便利で楽しい。 - のぼゆエンジニアリング

->もしくは基板にArduinoマイコンをのせる
->ネジやスペーサでうまくArduinoと回路をつなぐ

Q5.モータードライバとか回路つくるのが結構めんどい
->実はすでに実装されてるシールド基板とかもあるので買っちゃうのもあり。

http://akizukidenshi.com/catalog/c/carduino2/

 

Q6.基板がショートしない工夫は?
->グルーガンで止める
->エナメル線を使う
->絶縁テープを使う
->ちゃんと動線をくるくる巻く
->熱伸縮チューブ
->うまく回路の設計をして、距離を最小限にとどめる


Q7.小さくまとめたい

->表面実装の基板にチャレンジ
->発注してみるとか

コネクタ使ったり、RCAとかDCプラグとか使うと取り外しが楽になっていいよ。



 

 

xBee (APIモード) ×processing×arduino シリアル通信で。

 

xBeeで1対複数の通信をするためにまず1対1のAPIでの無線通信を試みた。
ATモードについては以前挙げた記事を見れば分かると思う。

APIモードについては以下の記事がよい。
http://airshipnewsjapan.blogspot.jp/2014/07/xbeearduinoxbeemac.html

ただ、この記事にある通りやってもprocessing側のコードが動かなかった(ライブラリーがなぜかうまく動かなかった)
のと
自分が行いたいのはコーディネーター側からルーター側への通信、つまり1対複数でいう親から複数の子機への通信。
上のURLを含めよく記事になっているのはセンサーの値をコーディネーター側へ送るものばかりであったので、自分で作ってみた。

忘備録ということでその方法を書いていく。

■作るもの
processingのスケッチで4分割された部分のどこかをクリックすると対応されたLEDが光るというものを作る。

■流れ
processing -> xBee(coordinator) -> xBee(router) -> arduino
serial通信を用いる。

xBeeの設定
http://airshipnewsjapan.blogspot.jp/2014/07/xbeearduinoxbeemac.html
の記事と同じ。
xBee(Coordinator API) AP-API Enable 2に設定。
xBee(Router API) AP-API Enable 2に設定。
同じPAN IDを設定

■processing側のコード
後々自分はこれをラジコンのように扱うつもりであったので
送るデータが
・data1
・data2
・data3
になっているが気にしない。この場合使うのは一つのデータだけ。
dataを増やしたいor減らしたい場合はchecksumの計算のときの合計値の部分とFrame lengthを変える。あとこのコードの場合は関数の引数とかも変えないといけない。

またxBeeルーター側の64ビットアドレスを記す部分があるのでtoSerialNumの部分を対応するものに変える。
portNameも変える。
/**/でくくっているところを消すと複数台の制御が出来る。その場合もそれぞれ対応するxBeeの64ビットアドレスを書き換える。

import processing.serial.*;

Serial myPort;

//ここを変える。
int toSerialNum1 = {0x00, 0x13, 0xA2, 0x00, 0x??, 0x??, 0x??, 0x??};
int SerNum1Sum = 0;
/*int
toSerialNum2 = {0x00, 0x13, 0xA2, 0x00, 0x??, 0x??, 0x??, 0x??};
int SerNum2Sum = 0;
int toSerialNum3 = {0x00, 0x13, 0xA2, 0x00, 0x??, 0x??, 0x??, 0x??};
int SerNum3Sum = 0;
int
toSerialNum4 = {0x00, 0x13, 0xA2, 0x00, 0x??, 0x??, 0x??, 0x??};
int SerNum4Sum = 0;*/

void setup()
{
size(500, 500);
String portName = Serial.list()[0];
println(portName);
//ここも変える。
myPort = new Serial(this, "/dev/tty.usbserial-????????", 9600);

for(int i = 0; i < toSerialNum1.length; i++){
SerNum1Sum += toSerialNum1[i];
}
/*for(int i = 0; i < toSerialNum2.length; i++){
SerNum2Sum += toSerialNum2[i];
}
for(int i = 0; i < toSerialNum3.length; i++){
SerNum3Sum += toSerialNum3[i];
}
for(int i = 0; i < toSerialNum4.length; i++){
SerNum4Sum += toSerialNum4[i];
}*/

}

void draw()
{
background(255);
fill(255,255,0,100);
rect(0,0,width/4,height);
fill(255,0,255,100);
rect(width/4,0,width/4,height);
fill(0,0,255,100);
rect(width/2,0,width/4,height);
fill(0,255,255,100);
rect(width-width/4,0,width/4,height);
line(width/4,0,width/4,height);
line(width/2,0,width/2,height);
line(width-width/4,0,width-width/4,height);
}

void mousePressed(){
if(mouseX<width/4){
setRemoteState(toSerialNum1, SerNum1Sum, 1, 255, 255);
/*setRemoteState(toSerialNum2, SerNum2Sum, 1, 255, 255);
setRemoteState(toSerialNum3, SerNum3Sum, 1, 255, 255);
setRemoteState(toSerialNum4, SerNum4Sum, 1, 255, 255);*/
fill(255,255,0);
rect(0,0,width/4,height);
println("mode=1");
}else if(mouseX<width/2){
setRemoteState(toSerialNum1, SerNum1Sum, 2, 255, 255);
/*setRemoteState(toSerialNum2, SerNum2Sum, 2, 255, 255);
setRemoteState(toSerialNum3, SerNum3Sum, 2, 255, 255);
setRemoteState(toSerialNum4, SerNum4Sum, 2, 255, 255);*/
fill(255,0,255);
rect(width/4,0,width/4,height);
println("mode=2");
}else if(mouseX<width-width/4){
setRemoteState(toSerialNum1, SerNum1Sum, 3, 255, 255);
/*setRemoteState(toSerialNum2, SerNum2Sum, 3, 255, 255);
setRemoteState(toSerialNum3, SerNum3Sum, 3, 255, 255);
setRemoteState(toSerialNum4, SerNum4Sum, 3, 255, 255);*/
fill(0,0,255);
rect(width/2,0,width/4,height);
println("mode=3");
}else{
setRemoteState(toSerialNum1, SerNum1Sum, 4, 255, 255);
/*setRemoteState(toSerialNum2, SerNum2Sum, 4, 255, 255);
setRemoteState(toSerialNum3, SerNum3Sum, 4, 255, 255);
setRemoteState(toSerialNum4, SerNum4Sum, 4, 255, 255);*/
fill(0,255,255);
rect(width-width/4,0,width/4,height);
println("mode=4");
}
}


void setRemoteState(int[] toSer,int serSum, int data1, int data2,int data3){
//start byte
myPort.write(0x7E);
//frame length
myPort.write(0x00);
myPort.write(0x11);
//frame type
myPort.write(0x10);
//frame ID
myPort.write(0x01);


//64bit address
//Bload cast 0x000000000000FFFF
myPort.write(toSer[0]);
// esc mode(API=2): は0x13 -> 0x7D, 0x33に変わるらしい
myPort.write(toSer[1]);
myPort.write(toSer[2]);
myPort.write(toSer[3]);
//router ID
myPort.write(toSer[4]);
myPort.write(toSer[5]);
myPort.write(toSer[6]);
myPort.write(toSer[7]);

//16bit address
//bload cast 0xFFFE
myPort.write(0xFF);
myPort.write(0xFE);

//set maximum hop num
myPort.write(0x00);

//option
myPort.write(0x00);

// RFdata1
if(data1 == 1){
myPort.write(0x01);
}else if(data1 == 2){
myPort.write(0x02);
}else if(data1 == 3){
myPort.write(0x03);
}else if(data1 == 4){
myPort.write(0x04);
}else{
myPort.write(0x00);
}

// RFdata2
myPort.write(byte(data2));

// RFdata3
myPort.write(byte(data3));


long sum = 0x10 + 0x01 + serSum + 0xFF + 0xFE + data1 + data2 + data3;
long sum2 = 0xFF - (sum & 0xFF);
myPort.write(byte(sum2));

delay(10);
}

■arduino側
arduinoの2,3,4,5ピンのLEDが光るようにする。(1ピンはTXに使っていた。)
そのためそれぞれLEDを繋いでおく。
また通信されているかの確認のため13番ピンを使う。
arduinoに書き込むときはxBeeシールドを外すか、xBeeシールドのSERIAL SELECTをMICROではなくUSB側にスイッチを切り替えてから書き込む。
xBEEで通信するときはMICRO側に戻す。

int debugLED = 13;

void setup(){
 pinMode(debugLED, OUTPUT);
 pinMode(2, OUTPUT);
 pinMode(3, OUTPUT);
 pinMode(4, OUTPUT);
 pinMode(5, OUTPUT);
 Serial.begin(9600);
}

void loop() {
if(Serial.available() > 19){  if(Serial.read() == 0x7E){
   digitalWrite(debugLED, HIGH);
   delay(10);
   digitalWrite(debugLED, LOW);
   for(int i = 0; i < 15; i++){
   byte discard = Serial.read();
   }
    int mode = Serial.read();
   if(mode<5 && mode>0){
     digitalWrite(mode+1, HIGH);
     delay(10);
   digitalWrite(mode+1, LOW);
   }
   int spd = Serial.read();
   int fan = Serial.read();
   Serial.print(mode);
 }}}

■やり方
arduinoのコードをarduinoへ書き込んだらxBeeシールド,xBeeを取り付ける。
その後シールドはMICRO側へスイッチを切っておく。
またarduinoに電源を取り付ける。USB供給でも良い。

その後processingで先ほどのコードをRUNする。
もしポートがbusyだよ、と言われたらx-ctuのポート検索をしてみる。それでもしxBeeが見つかったらもう一度processingをRUNしてみるとよい。
x-ctuで見つからなかったら一度USBを抜いてみる。

スケッチが開けたら、どこか押してみる。それに対応してLEDも光るはず。

■説明
APIモードだと2byteづつ送って通信するみたい。またそのプロトコルもちゃんとあるから確認しておくと良い。
今回はフレームタイプ0x10を用いた。
送るデータは
7E 00 11 10 01 00 13 A2 00 40 C1 C0 DD FF FE 00 00 Mode speed FanStr checksum
という感じ。Modeは(0x01~0x04)で今回は意味ないデータだがspeed(0x00~0xFF)、FanStr(0x00~0xFF) である。
(checksum)=FF-(はじめの3つを除いた数値の合計の下2桁(16進数))である。
ちゃんとデータが壊れていないか確かめるためのもの。

7E -> 開始デリミタ (開始の合図)
00 11->フレーム長 フレーム長からチェックサムに挟まれたbyte数
10 -> フレームタイプ
01 -> フレームID ACK(確認応答)と関連づけるためのID。いつ送ったモノかが分かる
00 13 A2 40 C1 C0 DD -> 宛先64bitアドレス
FF FE-> 16bit宛先アドレス。これはブロードキャスト
00 -> ブロードキャスト半径 00だと最大に設定
00 -> option 特に設定しない。
Mode  speed FanStr->
Modeが01だと2pin, 02だと3pin 03だと4pin 04だと5pinがHIGHになりLEDが光る。後の二つは冗長。
checksum -> チェックサム フレームタイプ10からこの一つ前までの8ビット和をFFからひいたもの。

大体この感じ。ちゃんと意味を知りたい場合は、「xbeeで作るワイヤレスセンサーネットワーク」の5章を読むと良い。arudinoのコードの意味もココに書いてあるものがほとんど。

補足
もし送るデータ(7E 00 …とかそういうもの)が具体的にどういうものか分からない場合はX-ctuのモニターマークを選択し下の部分の+マークで作る事が出来る。+を押した後、create frame using “Frame generator” tool…を選択。そして上のframe typeを希望の項目に変える。今回は0x10を選択。そして値を入れていけば簡単に送りたいものを作る事が出来る。ただEnable APIを2にしているためescモードになっている。そのため0x13が別の意味をもっているため0x7D 0x33に変わったりする。 0x7Dがescのもの。まぁ気にしなくてもprocessingからは0x13で送れる。0x13を0x7D 0x33に変えても送れる。ただチェックサムは0x13の方で計算する。
okをおしてaddFrameをおして作り終えたら、左上にあるプラグ?みたいなのをおして繋がる状態にする。その前に左上(プラグよりも)cordinatorの×の下の青い○を選択してルータを探しておいた方が良いかも。そしてスタートボタン見たいなsend select frameをおすとルーターにデータを送れる。これでもLEDを光らせる事は出来ると思うのでprocessingがうまくいかなかったらこっちで作っても良いかもしれない

以上!

XBeeの導入

XBeeには
AT通信
API通信
があり、今回は比較的簡単なAT通信を行った。

AT通信は比較的

まず、必要なものや手順は
http://mag.switch-science.com/2012/08/01/startup_xbee_zb/
で確認。

(ただこの記事での説明はwindows用なので、
macの人は上の記事に合わせて下のような違う記事を見ながら行うとよい。
http://bino98.hatenablog.jp/entry/2013/12/27/035609
http://hikone.info/blog/?p=106
二つ目の方はAPI通信なので、この二つの記事を見比べながらAT通信を行うと良いと思う。

補足:
x-ctuを入れたら ? マークのcheck updateを選択してまず更新.
あとusbアダプターのドライバも入れておく。http://www.ftdichip.com/Drivers/VCP.htmこれをし忘れて色々めんどくさかった。
もし"APIモードを一回xbeeにいれたんだけれども途中で失敗してしまった..."ということがあったらレンチマークをおしてのXBee recoveryを選択してみるといい。


また上の記事のこの設定が終わったら、もとのswitch-scienceの記事にもどり二つx-ctuを起動する所を無視してその先のarduinoへの書き込みを行うと通信できているかが確認できる。また、x-ctu上でのちょっとした確認がしたい場合は下の記事のようにモニターアイコンを押してみてみるといい。
ただしこちらはAPI通信で確認はまだしていない。
http://hikone.info/blog/?p=173
)


これらができたらx-ctuのモニターである文字を打ったら光る、音が出るというものを作っても良いかもしれない。

下はx-ctuでHとうったらルーター側のArduinoの13番ピンが光るコード。別のキーをうつと消える。
13番ピンはledささなくても元々ledがついてるから楽で良い。
これでも通信しているかが分かる。ご参考まで。

————————————————————-
int led = 13;
void setup(){
 pinMode(led, OUTPUT);
 Serial.begin(9600);
}
void loop(){
 if(Serial.available() > 0)
 if(Serial.read() == ‘H’){
   digitalWrite(led,HIGH);
   delay(10);
 }else{
   digitalWrite(led,LOW);
   delay(10);
 }
}
—————————————————————-

加えてコーディネータ側のxbeearduinoと繋げて、そのarduinoにこのコードを入れて2番ピンにボタンでも付けてみる。(arduinoやシールド等がもう一つ必要になる)

http://www.geocities.jp/zattouka/GarageHouse/micon/Arduino/SWtoLED/SWtoLED.htm
そしてどちらも電池に繋げてみてPCを使わずに通信してみるものいい。
下のコードはボタンを押したときだけ光る。

————————————————————
int BUTTON = 2;
void setup(){
 pinMode(BUTTON, INPUT);
 Serial.begin(9600);
}
void loop(){
 if(digitalRead(BUTTON) == HIGH){
   Serial.print(‘H’);
   delay(10);
 }else{
   Serial.print(‘L’);
   delay(10);
 }
}
————————————————————-


このようにSerial.print()とSerial.read()で大体のやり取りはできるはず。片方でreadやprintを行ってフィードバックしてあげるもよし。
基本processingとarduinoのシリアル通信と同じはずなのでxbee用のコードがあまり無ければそちらも参考にするのもありだろう。