imini リペアセラム

 

■Arduino シリアル通信でLチカを試す

Arduino とパソコンをシリアル通信でつないでみましょう。

 

パソコンの OS は ubuntu 18.04 LTS です。python でシリアル通信を行うためには「pyserial」というパッケージが必要です。そいつをインストールするには「pip」というパッケージをインストールするユーティリティが必要になります。

 

とゆーことで、まず「pip」のインストールです。

 

$ sudo apt install python3-pip

 

ちなみにこれでインストールされるのは「pip3」です。「pip」というのもありますが、python3 を使うのでこれで良いようです。「pip」も必要なら、

 

$ sudo apt install python-pip python3-pip

 

で両方インストールされます。

 

次に「pyserial」をインストールします。

 

$ sudo pip3 install pyserial

 

特権ユーザーでインストールすると /usr/local/lib にインストールされます。一般ユーザーでインストールすると ~/.local にインストールされ、他のユーザーに影響を与えずに追加・削除ができるとか。自分のパソコンなので特権ユーザーで良しです。

ちなみに、パッケージ名は「pyserial」ですが、使うときは「import serial」と書きます。

 

以上、シリアル通信のための準備作業。

 

下図のような LED を点灯させるための回路を作っておきます。基本的にね、出力ポートに直接 LED つなぐなんてのはやめときましょうね。


画像キャプション

 

Arduino のスケッチです。

シリアルから二桁の数字を受け取ります。10の位は制御する LED 、1の位は 0 で消灯、1 で点灯します。たとえば「11」と入力すると 2番目の LED が点灯します。「a」を受け取るとすべて消灯させます。

まぁシリアル通信のデータの受け渡しがまだよく理解できていないので、なんだかこれで動いたよってレベルなので笑ってやってください。

 

// シリアル入力 2桁の数字
// 10位:PIN番号 0:PIN1 1:PIN2 2:PIN3 3:PIN4
//  1位:制御 0:消灯 1:点灯
// 「a」を受信したら全消灯

 

int pin[4] = {3,5,6,9};
int input[3];

 

void setup() {
    Serial.begin(115200);

    for(int i=0; i<4; i++) {
        pinMode(pin[i], OUTPUT);
    }
}

 

void loop() {
    if(Serial.available()) {
        for(int i=0; i<3; i++) {
            input[i] = Serial.read();    // input[2]は'¥n'
        delay(10);
        }

 

    if(input[0] != 'a') {
        digitalWrite(pin[input[0]-48], input[1]&1);
        } else {
        for(int i=0; i<4; i++) {
            digitalWrite(pin[i], 0);
      }
    }
  }
}

 

シリアルモニタから送信して、期待どおりに動くことを確認しておきます。

 

さて、パソコン側の python のソースです。こちらも同様に、笑ってやってください。エラー処理とかまったくやっていません。

起動すると入力待ちになるので、たとえば「21」と入力すると 3番めの LED が点灯し「20」とすると消灯します。「a」を入力するとすべて消灯し、プログラムが終了します。

# シリアル通信でArduinoへLED制御コードを送る
# 10位:PIN番号 0:PIN1 1:PIN2 2:PIN3 3:PIN4
#  1位:制御 0:消灯 1:点灯

 

import serial

 

def main():
    with serial.Serial('/dev/ttyACM0',115200,timeout=1) as ser:

        while True:
            flag = bytes(input(),'utf-8')
            ser.write(flag)
            if(flag == bytes('a','utf-8')):
                break;

        ser.close()

 

if __name__ == "__main__":
    main()

 

パソコン側で「01」と入力します。すると変数 flag に代入されますが、シリアル通信のためには bytes 型にしなければいけませんので、flag=bytes(input(), 'utf-8') としています。入力する文字は utf-8 です。このとき flag の値は「b'01'」、つまり文字列「01」をバイナリコードにしたものです。

「a」を入力すると、while True: のループを抜けて終了します。Arduino へは「b'a'」が送られます。

 

Arduino 側では serial.read() を 3回繰り返しています。1回目は10の位、2回目は 1の位、3回目は終端の ¥n などを受け取ります。ただし受け取るデータは文字の「'0'」や「'1'」ですので、その値は「48」( b'0') や「49」(b'1') という数値になっています。

そこで、input[0] ( 10 の位) から 48 を引いて出力する PIN 番号を決めています。

input[1] ( 1 の位) も同様にしても良かったのですが、こちらは &1 で最後の 1 ビットを取り出して、そのまま PIN の出力を制御させています。1 の位に 2 以上の値がきたときの動きが変わりますが、そこらあたりはエラー処理で考えることになるんだろうと思います。

 

そんなわけで、パソコンからデータを送ること、それを Arduino で受け取ること、それらのデータの型や処理の仕方などなど、いろいろわからないことだらけの中でもなんとか形ができたので、またいろいろ応用していけるかなぁと思っています。

 

参考:PC-Arduino間 Python経由 シリアル通信備忘録 - Qiita

 


■Arduino デコーダでLチカを試す

4つの LED ぐらいなら問題はありませんが、数が多くなるとデコーダが必要になります。ということで、簡単なデコーダ回路を作って L チカしてみました。

 

Arduino の出力は、よくわからんのですが、電源が落ちたときなど中途半端な電圧になるようなのでプルアップしています。U7、U8 はバッファにすべきですが、NAND ゲートが余っていたので利用しました。


ロジック回路図

 

PIN 9 と 10 を利用し、それぞれの出力が下表のようになると対応した LED が点灯します。

 

点灯 PIN 9 PIN10
L1 0 0
L2 1 0
L3 0 1
L4 1 1

 

 

回路図です。余計にわかりにくいですね (^_^;)


回路図

 

スケッチです。

PIN 9、10 にビットを順次出力するだけなので簡素です。ビット操作がちょっと難しいのですが、数値を 1 と AND 演算すると 1ビット目が取り出せます。

int a = i&1;

右にシフトして同様に AND 演算すると 2 ビット目が取り出せます。

int b = (i>>1)&1;

それぞれを PIN 9、10 に出力しています。

 

void setup() {
  pinMode( 9,OUTPUT);
  pinMode(10,OUTPUT);

}

void loop() {
  for (int i=0; i<4; i++) {
    int a = i&1;
    int b = (i>>1)&1;

    digitalWrite( 9, a);
    digitalWrite(10, b);
    delay(125);
  }

}

 

ブレッドボードです。IC でのロジック回路はジャンプワイヤーだらけになってしまいます (^_^;) でも、もちろんトランジスタで組むより断然簡単です。


ブレッドボード

 


■Arduino Lチカを試す

正月休みもブレッドボードで遊んでいる meyon さんであります (^_^;)

 

さて、初めての Arduino Uno を動かしてみしょう。

基本は Lチカとのことなのですが単純に LED を点灯させるだけじゃつまらないので 、ダーリントンドライバが 4回路入ったTD62308BP1G がありますから 4個の LED を順番に点灯させてみることにしました。

 

回路図です。

電源は 12V AC アダプタとそれをレギュレーターで降圧した 5V (*) を使用します。Arduino へも Vin へ 12V を供給します。

(*)「+5V電源回路とLED駆動回路を作る

 


回路図

 

スケッチです。C 言語も初めてなので、出来の悪さはご容赦ください。

int pin[5]={0,6,9,10,11}; // 出力pin 0はダミー
int seq[4]={4,3,2,1};     // 出力する順番

int ptn[][5]={            // 点灯パターンと時間
  {1,0,0,0,100},
  {1,1,0,0,50},
  {0,1,0,0,100},
  {0,1,1,0,50},
  {0,0,1,0,100},
  {0,0,1,1,50},
  {0,0,0,1,100},
  {1,0,0,1,50}
};

 

void setup() {
  pinMode(pin[1], OUTPUT);
  pinMode(pin[2], OUTPUT);
  pinMode(pin[3], OUTPUT);
  pinMode(pin[4], OUTPUT);
}

 

void loop() {
  for (int i=0; i<sizeof(ptn)/sizeof(ptn[0]); i++) {
    digitalWrite(pin[seq[0]],ptn[i][0]^1);
    digitalWrite(pin[seq[1]],ptn[i][1]^1);
    digitalWrite(pin[seq[2]],ptn[i][2]^1);
    digitalWrite(pin[seq[3]],ptn[i][3]^1);
    delay(ptn[i][4]);
  }
}

 

pin[ ] は出力する pin 番号です。最初の「0」はダミーですので、必ず書いておきます。

seq[ ] は出力する順番です。既定は LED4 、LED3 、LED2 、LED1 の順になっています。

ptn[ ][ ] は点灯パターンと時間を指定します。「1」は点灯、「0」は消灯。5番目の数字は点灯時間 (ms) です。既定のパターンは、ひとつの LED を 100ms 点灯し、次の LED を点灯して 50ms 待ってから前の LED を消灯しています。これは、点灯の切り替えを滑らかにするためです。

 

loop() の中で「ptn[i][0]^1」というのがありますが、ドライバが LOW で LED 点灯のため、点灯パターンの「1」と「0」を反転させるために XOR 演算する部分です。論理演算すると、ビットごとの比較になりますから、例えば 4bit ならば下表のようになります。

 

ptn

1 XOR (ptn)
0000 0001 0001
0001 0001 0000

 

じつはこの部分、最初は NOT と考えたのですが、プログラマの息子から「 NOT だと他のビットが 1 になってしまう」とダメ出しをもらいました。つまり、

 

ptn NOT (ptn)
0000 1111
0001 1110

 

ってことですね。難しい… (^_^;)

 

 

Arduino とブレッドボードです。


ブレッドボード

 

ドライバ IC は上から見ると反時計回りに 1 、2 、3 、4 となっていますので、LED を時計回りに点灯させるために seq[ ] を逆順にしています。まぁ順番なんてつなぎ方でどうにでもなるんですけどね。

Arduino の電源はブレッドボードの 12V からとっています。ちなみに、AC アダプタのコネクタを DIP 化したので、電源部分がすっきりできました。

 


■排他的論理和(XOR)回路

最後に排他的論理和 (XOR) 回路を作ってみます。

NOR と同様に NAND を 4段利用しますが、結線が異なります。

スイッチで入力を HIGH またはLOW に切り替えると、出力が HIGH ならば LED が点灯します。


排他的論理和_XOR_回路図

XORゲート

fXOR( A , B ) = fNAND( fNAND( A , fNAND( A , B ) ) , fNAND( fNAND( A , B ) , B ) )

      = ( A * B ) + ( A * B ) = ( A + B ) * (A + B )

この式は XOR が NAND の組み合わせでできる、ってことを表しています。

 

真理値表

Input A Input B Output
0 0 0
0 1 1
1 0 1
1 1 0

 

参考: ブール代数と論理演算 (コンピュータと情報数理) (2) - 中川雅央(滋賀大学)

 

 

ブレッドボードです。

ますます混雑してしまいました。パーツの足を長いまま組んでいるので、ショートしないように注意が必要です。もっと大きいブレッドボードで組んだほうが良いですね (^_^;)


ブレッドボード

 

左側のスライドスイッチで入力を操作します。出力が HIGH になると右下の LED が点灯します。

 


■否定論理和(NOR)回路

NAND を 4段にして否定論理和 (OR) 回路をつくります。

OR の出力を否定することで NOR になります。

スイッチで入力を HIGH またはLOW に切り替えると、出力が HIGH ならば LED が点灯します。


否定論理和_NOR_回路図

NORゲート

fNOR( A , B ) = fNOT( fNAND( fNOT( A ) , fNOT( B ) ) )

式をすべて NAND で表現しようとするとかなり長くなるので fNOT( ) はそのままにしてありますが、NOT は NAND でできますから、NOR も NAND で作れるということです。

 

真理値表

Input A Input B Output
0 0 1
0 1 0
1 0 0
1 1 0

 

参考: ブール代数と論理演算 (コンピュータと情報数理) (2) - 中川雅央(滋賀大学)

 

 

ブレッドボードです。

NAND 回路が 4つになり、かなり混雑してきましたね (^_^;)


ブレッドボード

 

左側のスライドスイッチで入力を操作します。出力が HIGH になると右下の LED が点灯します。

 


■論理和(OR)回路

更に NAND を 1段増やして論理和 (OR) 回路をつくります。

入力 A 、B をそれぞれ否定して NAND へ入力することで OR になります。

スイッチで入力を HIGH またはLOW に切り替えると、出力が HIGH ならば LED が点灯します。


論理和_OR_回路図

ORゲート

fOR( A , B ) = fNAND( fNOT( A ) , fNOT( B ) ) = fNAND( fNAND ( A , A ) , fNAND( B , B ) )

この式は、OR が NAND の組み合わせでできる、ってことを表しています。

 

真理値表

Input A Input B Output
0 0 0
0 1 1
1 0 1
1 1 1

 

参考: ブール代数と論理演算 (コンピュータと情報数理) (2) - 中川雅央(滋賀大学)

 

 

ブレッドボードです。

NAND 回路が 3つになりました。


ブレッドボード

 

左側のスライドスイッチで入力を操作します。出力が HIGH になると右下の LED が点灯します。

 


■論理積(AND)回路

NAND 回路をもう一段追加して、論理積 (AND) 回路を作ってみます。

1段目は NAND で、2段目は入力 A 、B をまとめて NOT として使用します。

スイッチで入力を HIGH またはLOW に切り替えると、出力が HIGH ならば LED が点灯します。


論理積_AND_回路図

ANDゲート

fNOT( A ) = fNAND( A , A )

fAND( A , B ) = fNOT( fNAND( A , B ) ) = fNAND( fNAND( A , B ) , fNAND( A , B ) )

この式は、AND が NAND の組み合わせでできる、ってことを表しています。

 

真理値表

Input A Input B Output
0 0 0
0 1 0
1 0 0
1 1 1

 

参考: ブール代数と論理演算 (コンピュータと情報数理) (2) - 中川雅央(滋賀大学)

 

 

ブレッドボードです。NAND 回路が追加されています。


ブレッドボード

 

左側のスライドスイッチで入力を操作します。出力が HIGH になると右下の LED が点灯します。

 


■否定論理積(NAND)回路

珍しくもありませんが (^_^;) 否定論理積 (NAND) 回路です。

スイッチで入力を HIGH またはLOW に切り替えると、出力が HIGH ならば LED が点灯します。


否定論理積_NAND_回路図

NANDゲート

fNAND( A , B ) = A*B = A + B

 

真理値表

Input A Input B Output
0 0 1
0 1 1
1 0 1
1 1 0

 

参考: ブール代数と論理演算 (コンピュータと情報数理) (2) - 中川雅央(滋賀大学)

 

実験に使ったブレッドボードです。


ブレッドボード

 

左側のスライドスイッチで入力を操作します。出力が HIGH になると右下の LED が点灯します。

 


■マルチバイブレーターを作る (3)

非安定マルチバイブレータ−というか LED 駆動回路というか、とにかくなんだかハマってます (^_^;)

発振に影響を与えないようにパルスを取り出して LED を駆動するために、PNP トランジスタを 1段入れて、こんな回路にしてみました。Q3 を単純なスイッチング回路にしても良かったのですが、できるだけベース電流を小さくしたかったので、エミッタ側に抵抗を入れました。これはベース接地ってことでいいのかな。

 


マルチバイブレータ−回路図

 

Q2 がオンのときの各部の電圧です。

電源電圧 5.08V

Q2 コレクタ電圧

0.08V

Q3 ベース電圧

1.06V

Q3 エミッタ電圧

1.72V

Q4 ベース電圧

0.75V

R8 両端電圧

2.53V

 

Q3 のエミッタ電流は 0.67mA (*注) 、ベース電流は 4.5μA 、増幅率は 150 ぐらいになっています。

Q4 のベース電流が 0.59mA 、コレクタ電流は 16.9mAですので増幅率は約 29 。この LED は電流を増やしてもこれ以上は明るくならないようです。

 

(*注) 4.7KΩ の抵抗が手元になかったので、10KΩ を 2個並列にしています。

 

代わり映えしませんが (^_^;) ブレッドボードです。


ブレッドボード

 

左側から +5V電源回路、非安定マルチバイブレーター、右側が PNP トランジスタを追加した LED 駆動回路です。

 

 


■マルチバイブレータ−を作る (2)

非安定マルチバイブレーターの出力を取り出すとき、発振に影響を与えるようではうまくありません。影響を与えずにパルスを取り出すには、まぁ要するに入力インピーダンスを高くすりゃいいわけで、FET を使うとかね。

簡単な方法では、ツェナーダイオードをベースに入れて前段のコレクタ電圧が低くならないようにするとか。

 

それよりも入力を PNP トランジスタにすることで吸い出しにして、Q2 のコレクタが High のときに電流が流れないようにすればいいんじゃね? つまりこんな感じ。抵抗値とかちゃんと考えてないんで無視してください。

 


非安定マルチバイブレータ−

 

そんなことを考えながらブレッドボードを触っていたら、なにやら焦げ臭いにおいが… 。はい、トランジスタがお亡くなりになりました (^_^;) どうも、ベースに電源ぶっこんでしまったらしい… まぁよくある話で (^_^;)

 

なにか使えるものはなかったかなと探してみたら、ありました、先日ジャンク基板で見つけた TD62308 ってのが。出力が 80V 1.5A × 4ch と大きいですが、使えるでしょう。入力が Low で出力 Low のまさに上の回路のような仕様です。実際の入力電流はテスターで -6μA を示していました。

これを使って LED を駆動したのが次の回路図です。

 


非安定マルチバイブレータ−

 

これでしっかり 点灯時間 = 消灯時間 になりました。周期も実測で約 0.5 秒、計算通りです。

こいつはリレーとか大きいやつでも平気で駆動できますよ。

 

ブレッドボードです。


ブレッドボード

 

左側は +5V 電源回路、その右がマルチバイブレーター回路で、IC とその下部分が LED 駆動回路です。

 


<< | 2/3PAGES | >>

■calendar

S M T W T F S
     12
3456789
10111213141516
17181920212223
24252627282930
31      
<< March 2019 >>

■search this site.

■recommend

毎日貯まるポイントサイト ECナビ

■recommend

■Twitter

■recommend

■recommend

■selected entries

■categories

■archives

■recent comment

■recent trackback

■links

■profile

■others

■mobile

qrcode

■powered

無料ブログ作成サービス JUGEM