プログラミング演習Ⅱプ グラミング演習Ⅱ
フィジカルコンピューティング
第2回 アナログ入出力とシリアル通信第2回 アナログ入出力とシリアル通信
担当:橋本担当:橋本
アナログ出力アナログ出力
おけるデジタ 出力 か か ( )Arduinoにおけるデジタル出力: LOW か HIGH か (0V or 5V)Arduinoにおけるアナログ出力: PWM信号(256段階)
PWM Pulse Width Modulation (パルス幅変調)PWM = Pulse Width Modulation (パルス幅変調)
– ON・OFFを高速に切り替える手法
– ON時間とOFF時間の比(デューティ比)を変えてコントロール
パルス幅
5V
パルス幅
0VON OFF ON OFF ON OFF
2周期
アナログ出力の命令アナログ出力の命令
• analogWrite( ピン番号,出力値 )指定したピンに対してPWM出力する– 指定したピンに対してPWM出力する
– 出力値には 0 ~ 255を指定する
– PWM出力できるのは3,5,6,9,10,11ピン
3
PWMでLEDの明るさを制御する回路PWMでLEDの明るさを制御する回路
「 」マ クがついた端子がPWM出力できる端子• 「~」マークがついた端子がPWM出力できる端子
• 抵抗は 330Ω ※前回と違うのはより明るくするため
短い脚GND
長い脚
抵抗 330Ω (橙橙茶金)
9
抵抗 330Ω (橙橙茶金)
4
LEDの明るさが滑らかに変化するプログラム
void setup() {pinMode( 9, OUTPUT );
}9番ピンを出力に設定
}
id l () {void loop() {for ( int i=0; i<=255; i++ ) {analogWrite( 9 i )
0から255まで1ずつカウントアップ
analogWrite( 9, i );delay(10);}
9番ピンでアナログ出力
}for ( int i=255; i>=0; i‐‐ ) {analogWrite( 9 i );
255から0まで1ずつカウントダウン
ピ グanalogWrite( 9, i );delay(10);}
9番ピンでアナログ出力
5
}}
アナログ入力アナログ入力
Arduinoにおけるデジタル入力: LOW か HIGH か (0V or 5V)Arduinoにおけるアナログ入力: 0V~5Vを多段階で刻んだ値Arduinoにおけるアナ グ入力: 0V 5Vを多段階で刻んだ値
入力には ナ グ入力端子 を使う• 入力にはアナログ入力端子 A0~A5 を使う• 電圧の変化を1024段階で読み取れる電圧の変化を1024段階で読み取れる
• 5V/1024 = 4.9mV刻み
6
アナログ入力の命令アナログ入力の命令
• analogRead( ピン番号 )指定 たピ 力電 を読 る– 指定したピンの入力電圧を読み取る
– ピン番号は 0~5を指定 (A0~A5に対応)ピン番号は 0 5 を指定 (A0 A5に対応)
– int値(0~1023)を返す
7
光の強さをセンシングする回路光の強さをセンシングする回路GND 9GND
短い脚
長い脚
抵抗330Ω (橙橙茶金)A0
CdSセル5V
8GND抵抗10kΩ (茶黒橙金)
光センサ (CdSセル)光センサ (CdSセル)
• あたる光が強くなると電気抵抗が低下する素子
硫化カドミウム(CdS)の性質を利用• 硫化カドミウム(CdS)の性質を利用
• フォトレジスタ、光伝導セルとも呼ぶ
抵抗値の変化は、電気回路では抵抗値の変化は、電気回路では
電圧値の変化として読み取る!
9
周囲の明るさでLEDの点滅周期が変化するプログラム
void setup() {pinMode( 9, OUTPUT ); 9番ピンを出力に設定p ( , );
}番 を 設定
アナログ入力端子(A0)についてはpinMode()不要
void loop() {int value analogRead(0);
てはp ()不要
アナ グの 番ピンを読み取るint value = analogRead(0); アナログの0番ピンを読み取る
digitalWrite( 9, HIGH );delay( value ); アナログ入力の値に応じて
LEDを点滅させる
digitalWrite( 9, LOW );delay( value );
アナ グ入力の値に応じて待ち時間を設定
delay( value );}
シリアル通信シリアル通信
• 10010110011…のようなデータ信号を1ビットずつ送る通信方式送る通信方式
• ArduinoとPCを接続して、互いに数値や文字列のデータをやりとりできるデ タをやりとりできる
• Arduinoで計測したセンサ情報をPCに送ったり、PCからのコマンド送信によってLEDやモータを制御しら ン 送信 よ や タを制御たりできる
11
シリアル通信に挑戦シリアル通信に挑戦
• 回路はさっきの光センシングの回路そのまま
【データの送信】 (Arduino→PC)【データの送信】 (Arduino→PC)– 光センサの入力値をPCに送信してモニタリング
【デ タ 受信】【データの受信】 (PC→Aruidno)– PCからコマンドを送ってLEDをコントロール– PCからコマンドを送ってLEDをコントロ ル
12
【データの送信】光センサの入力値を
PCに送信するプログラムPCに送信するプログラム
void setup() {Serial.begin( 9600 ); シリアル通信を開始する
(通信速度 b )Serial.begin( 9600 );
}(通信速度:9600bps)
void loop() {i t l l R d(0) アナ グの 番ピンを読み取るint value = analogRead(0);Serial.println(value);
アナログの0番ピンを読み取る
データをPCに送信する
}
13
命令の意味命令の意味
• Serial.begin(通信速度 )シリアル通信を開始する 通信速度は以下のいずれか– シリアル通信を開始する。通信速度は以下のいずれか
300bps, 1200bps, 2400bps, 4800bps, 9600bps, 19200bps, 600b 200b57600bps, 115200bps
単位: bps = bits per second (1秒間に送るビット数)
• Serial print(デ タ ) 改行なし• Serial.print( データ ) … 改行なし
Serial.println( データ ) … 改行ありp ( ) 改 あ
– 数値や文字列を送れる
A d i では「 」による文字列の結合はできないので注意– Arduinoでは「+」による文字列の結合はできないので注意14
S i l i t()による文字の出力Serial.print()による文字の出力
• Serial.print(78) ‐ “78”が出力される
が• Serial.print(1.23456) ‐ “1.23”が出力される
• Serial print(‘N’) “N”が出力される• Serial.print( N ) ‐ N が出力される
• Serial.print(“Hello world.”) ‐ “Hello world.”とp ( )出力される
15
デ タのモニタリングデータのモニタリング
• ウィンドウ右上にある「シリアルモニタ」というボタンをクリックをクリック
• シリアルモニタが起動してデータが流れてくる
16
曲げセンサ曲げセンサ
• 曲げ量に応じて抵抗値が変化するセンサ
• 光センサを取り外して曲げセンサで置き換えて• 光センサを取り外して曲げセンサで置き換えてみよう(根元が折れやすいので注意!)
曲げに応じ 値はど ように変化するだろうか• 曲げに応じて値はどのように変化するだろうか
17
【データの受信】 コマンドでLED制御void setup() {Serial.begin( 9600 ); シリアル通信を開始するg ( );pinMode( 9, OUTPUT );
}9番ピンを出力に設定
}
void loop() {if ( Serial.available() > 0 ) {int data = Serial.read(); データを1バイト読み込む
データがきているかチェック
if ( data == 'a' ) {digitalWrite( 9, HIGH ); データが 「a」だったら
を にする}else if ( data == 'b' ) {
( )
LEDをONにする
digitalWrite( 9, LOW );}}
データが 「b」だったらLEDをOFFにする
}}
命令の意味命令の意味
• Serial.available()受信 たデ タ バ 数を返す– 受信したデータのバイト数を返す
– 1以上の値を返せばデータが着ていることになる1以上の値を返せばデ タが着ていることになる
– Arduinoは一度に128バイトまで保持する
• Serial read()• Serial.read()– 受信したデータの 初の1バイトを返す
– 戻り値は int型
19
PCからのデ タの送信PCからのデータの送信
• シリアルモニタを起動する
• 入力欄にコマンド(「a」または「b」)を入力して• 入力欄にコマンド(「a」または「b」)を入力して送信ボタンを押す(もしくはエンターキー)
「 を送 た時に が になり 「 を送• 「a」を送った時にLEDがONになり、「b」を送った時にLEDがOFFになるた時にLEDがOFFになる
20
(補足)文字「 」を送るということ(補足)文字「a」を送るということ
• 文字にはそれぞれ「文字コード」と呼ばれる識別番号が割り当てられている号が割り当てられている。
(例) 「a」は97、「A」は65、「1」は49参考: http://www9.plala.or.jp/sgwr‐t/c_sub/ascii.html
• 「a」の文字コード(97)を2進数で表すと「01100001」
• この1/0の並びをON/OFFの電気信号に置き換えてこの1/0の並びをON/OFFの電気信号に置き換えて伝送している。
21
(補足) i t型での受信デ タの判定(補足) int型での受信データの判定
• Serial.read()は受信データをint型で返す
• 文字を受信したときは?文字 ドが受信される– 文字コードが受信される
すなわち 「 という文字がきた時は という 型– すなわち、「a」という文字がきた時は、97というint型の値を受け取っている
– なので、このように判定することもできる
int data = Serial.read();判定することもできる(’a’ は 97 と置換可能)
if ( data == 97 ) {digitalWrite( 9, HIGH );}
22}
練習問題1練習問題1
ド入力によ 以 反応を返すプ• コマンド入力によって以下の反応を返すプログラムにしてみようグラ してみよう
– 「a」という文字を送信したら、LEDが点灯してa」という文字を送信したら、LEDが点灯して
「LED: turn on」という文字列を返す
– 「b」という文字を送信したら、LEDが消灯して
「LED: turn off」という文字列を返す
– 「c」という文字を送信したら、光センサの値を
「sensor input = ???」 という形式で返す
23
練習問題2練習問題2光センサに手をかざしたときだけLEDが点灯• 光センサに手をかざしたときだけLEDが点灯するプログラムを作ってみよう
【ヒント1】 if文によって 「センサの値がいくつ以– 【ヒント1】 if文によって、「センサの値がいくつ以上のときに点灯(or消灯)する」という分岐を作ってみようてみよう。
– 【ヒント2】 シリアル通信を使って、手をかざしているときに、センサの入力値がどのくらいになってる き 、 サ 入力値 く ないるかチェックして閾値(しきいち)を決めよう。
24