Arduinoのソフトウェア(mugbot_arduino)のコード解説

Arduinoのソースコード(mugbot_arduino)の解説です。
このソースコードはArduino専用の言語で書かれており、拡張子は「ino」になっています。
server(mugbot_server)から送られてきたコマンドを読み取って、そのコマンドを実行します。LEDやサーボが動くのはこのソースコードの働きです。

Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <Servo.h>
//Mugbot Project Tokyo City University Koike Lab. 2014
//Mugbot System ver. 1.0.0.
Servoeye_servo;
Servohead_servo;
staticintpos=0;//Arduinoのサーボの回転角度
staticintg=0;//Webのスライダーの位置
charch=0;
intl_mouse=7;//口LED左部(正面から見て)
intm_mouse=8;//口中央LED(正面から見て)
intr_mouse=9;//口LED右部(正面から見て)
intl_eye=11;//左目(正面から見て)
intr_eye=13;//右目(正面から見て)
inteye_default=90;//目の正面位置を設定
inteye_min=75;//目の最小位置を設定
inteye_max=105;//目の最大位置を設定
inthead_default=90;//首の正面位置を設定
inthead_min=0;//首の最小角度を設定
inthead_max=180;//首の最大角度を設定
inteye_light_default=50;//目の明るさの通常値を設定

それぞれのLEDとサーボの初期設定をしています。
例えば、「int l_mouse=7;」は「l_mouse」を「7」と設定するということです。ソースコード上で「l_mouse」と入力されているところは7という値を代入することを定義しています。
また、同じように「int eye_default=90;」は目のサーボの正面位置を90に設定し、ソースコード上で「eye_default」と入力されているところは90という値を代入することを定義しています。

Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
voidsetup()
{
Serial.begin(9600);
eye_servo.attach(2);//サーボ 目の上下
head_servo.attach(4);//サーボ 首の左右
//目、首、目の明るさの初期設定
pinMode(l_eye,OUTPUT);
pinMode(r_eye,OUTPUT);
pinMode(l_mouse,OUTPUT);
pinMode(m_mouse,OUTPUT);
pinMode(r_mouse,OUTPUT);
analogWrite(l_eye,eye_light_default);
analogWrite(r_eye,eye_light_default);
digitalWrite(l_mouse,LOW);
digitalWrite(m_mouse,LOW);
digitalWrite(r_mouse,LOW);
eye_servo.write(eye_default);
head_servo.write(head_default);
}

setup( )はスケッチがスタートしたときに1度だけ呼び出される部分で、ピンモードやライブラリの初期化などを行っています。

「attach」というのは、「サーボ名.attach(ピン番号)」でサーボを割り当てるピンを設定しています。
(例 eye_servo.attach(2)というのは、eye_servoは2番ピンに接続されているということです。)

「pinMode」というのは、「pinMode(ピン番号, 入力もしくは出力)」で、そのピンが入力ピンなのか出力ピンなのかを設定しています。
(例 pinMode(l_eye, OUTPUT)というのは、l_eye(上で定義したように11)ピンはOUTPUT(出力)に設定するということです。)

「analogWrite」というのは、「analogWrite(ピン番号,値)」で、そのピンに接続されているLEDをどのくらいの明るさにするのかを設定しています。
(例 analogWrite(l_eye,eye_light_default)というのは、l_eye(上で定義したように11)ピンをeye_light_default(上で定義したように50)の明るさに設定するということです。)

「digitalWrite」というのは、「digitalWrite(ピン番号,HIGHまたはLOW)」で、そのピンに接続されているLEDを5Vにするのか0Vにするのかを設定しています。
(例 digitalWrite(l_mouse, LOW)というのは、l_mouse(上で定義したように7)ピンをLOW(0V=光らせない)に設定するということです。)

「write」というのは、「サーボ名.write(角度)」で、サーボをどの角度にするのか設定しています。
(例 eye_servo.write(eye_default)というのは、eye_servoをeye_default(上で定義したように90)に向けるということです。)

Arduino
1
2
3
4
5
6
7
8
9
10
11
voidloop(){
if(Serial.available()>0){
ch=Serial.read();
switch(ch){
case'0'...'9':
g=g*10+ch-'0';
//例えば100Xの文字がRaspberry Piから来ると1文字ずつ読み込む
//1、0、0を順に読み込んで数字の100にして変数に格納する。
break;

loop( )には実行したいプログラムを書きます。その名のとおり、この部分に書かれた内容は繰り返し実行されます。
「if(serial.available( )>0)」というのは、もしも受信データがあるならば以下の内容を実行するという意味です。
「ch = serial.read();」で受信したデータを読み込み、その値を「ch」に代入します。
「switch文」で「ch」の値がそれぞれの「caseの値」だった場合、その「case」の内容を実行します。(例 「ch」の中身が0〜9の数字だった場合、その数字を順番に読み込んで、「1・0・0」というぶつ切りの数字ではなく、「100」のようにひとつの数字に変換して「g」に代入する。)breakまでいくとswitch文を抜けて、ループに戻ります。

Arduino
1
2
3
4
5
6
7
case'x'://Rasberry Piからxを受け取ると首を左右に運動。
head_servo.write(g);
//次にxを読み込むと変数gに入った100でサーボの角度を変える。
delay(15);
g=0;
//gを0にして初期化
break;

もしも「x」を受け取った場合は、サーボを 「g」の値の角度に向け、少し待った後に「g」を0に初期化してループに戻ります。
「delay」というのはその時間の分だけ待つということです。

Arduino
1
2
3
4
5
case'y'://Rasberry Piからyを受け取ると目を上下に運動。
eye_servo.write(g);
delay(15);
g=0;
break;

もしも「y」を受け取った場合は、サーボを 「g」の値の角度に向け、少し待った後に「g」を0に初期化してループに戻ります。

Arduino
1
2
3
4
5
6
case'z'://Rasberry Piからzを受け取ると目の明るさを変調。
analogWrite(l_eye,g);
analogWrite(r_eye,g);
delay(15);
g=0;
break;

もしも「z」を受け取った場合は、LEDの明かりを 「g」の値にし、少し待った後に「g」を0に初期化してループに戻ります。

「発話」の動作

Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
case't'://Rasberry Piからtを受け取ると口が点滅し、発話時の動作を行う。
delay(2000);
digitalWrite(l_mouse,HIGH);
digitalWrite(m_mouse,HIGH);
digitalWrite(r_mouse,HIGH);
for(pos=eye_default;pos<110;pos+=1){
eye_servo.write(pos);
delay(15);
};
for(pos=110;pos>80;pos-=1){
eye_servo.write(pos);
delay(15);
};
for(pos=80;pos<eye_default;pos+=1){
eye_servo.write(pos);
delay(15);
};
break;

もしも「t」を受け取った場合は、口のLEDを点灯させ、目を上下に動かします。
「for ( pos = eye_default; pos < 110; pos += 1)」というのは初期値がeye_default(90)で、その90に数字を1ずつ足していき、posの値が110を超えるまで{ }の中の内容を実行するということなので、posが110になるまで、eye_servoの角度をposの値にするということです。
他のfor文も値は違いますが同じことをしています。
ただし、pos -= 1の場合は数字を1ずつ足していくのではなく、減らしていきます。

「初期値に戻る」の動作

Arduino
1
2
3
4
5
6
7
8
9
10
case'n'://Rasberry Piからnを受け取ると首、目の標準位置に戻す。
analogWrite(l_eye,eye_light_default);
analogWrite(r_eye,eye_light_default);
digitalWrite(r_mouse,LOW);
digitalWrite(l_mouse,LOW);
digitalWrite(m_mouse,LOW);
eye_servo.write(eye_default);
head_servo.write(head_default);
break;

もしも「n」を受け取った場合は、全ての値を初期設定値に戻します。

「笑う」の動作

Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
case'l'://Rasberry Piからlを受け取ると「笑う」のアクションを行う。
analogWrite(l_eye,eye_light_default);
analogWrite(r_eye,eye_light_default);
digitalWrite(l_mouse,HIGH);
digitalWrite(m_mouse,HIGH);
digitalWrite(r_mouse,HIGH);
eye_servo.write(120);
delay(100);
eye_servo.write(100);
delay(100);
eye_servo.write(120);
delay(100);
eye_servo.write(100);
delay(100);
eye_servo.write(120);
delay(100);
eye_servo.write(100);
delay(100);
eye_servo.write(120);
delay(100);
eye_servo.write(100);
delay(100);
eye_servo.write(120);
delay(100);
eye_servo.write(100);
delay(100);
eye_servo.write(120);
delay(100);
eye_servo.write(100);
delay(100);
eye_servo.write(120);
delay(100);
eye_servo.write(100);
delay(100);
eye_servo.write(120);
delay(100);
eye_servo.write(eye_default);
delay(100);
digitalWrite(r_mouse,LOW);
digitalWrite(l_mouse,LOW);
digitalWrite(m_mouse,LOW);
break;

もしも「l」を受け取った場合は、口を点灯させ、目を上下運動させます。上下運動が終わったら、口の点灯を止めます。

「悲しい」の動作

Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
case's'://Rasberry Piからsを受け取ると「悲しい」のアクションを行う。
for(pos=eye_default;pos>70;pos-=1){
eye_servo.write(pos);
delay(15);
};
for(pos=eye_light_default;pos>20;pos-=1){
analogWrite(l_eye,pos);
analogWrite(r_eye,pos);
delay(10);
};
eye_servo.write(eye_default);
head_servo.write(head_default);
analogWrite(l_eye,eye_light_default);
analogWrite(r_eye,eye_light_default);
digitalWrite(r_mouse,LOW);
digitalWrite(l_mouse,LOW);
digitalWrite(m_mouse,LOW);
break;

もしも「s」を受け取った場合は、目を下げ、目の明るさを小さくしていきます。終わると元の状態に戻ります。

「はい」の動作

Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
case'h'://Rasberry Piからhを受け取ると「はい」のアクションを行う。
analogWrite(l_eye,eye_light_default);
analogWrite(r_eye,eye_light_default);
for(pos=eye_default;pos>70;pos-=1){
eye_servo.write(pos);
delay(15);
};
for(pos=70;pos<eye_default;pos+=1){
eye_servo.write(pos);
delay(15);
eye_servo.write(pos);
delay(15);
};
for(pos=eye_default;pos>70;pos-=1){
eye_servo.write(pos);
delay(15);
};
for(pos=70;pos<eye_default;pos+=1){
eye_servo.write(pos);
delay(15);
eye_servo.write(pos);
delay(15);
};
break;

もしも「h」を受け取った場合は、目を上下に動かします。

「いいえ」の動作

Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
case'f'://Rasberry Piからfを受け取ると「いいえ」のアクションを行う。
analogWrite(l_eye,eye_light_default);
analogWrite(r_eye,eye_light_default);
for(pos=85;pos<135;pos+=1){
head_servo.write(pos);
delay(15);
};
for(pos=135;pos>55;pos-=1){
head_servo.write(pos);
delay(15);
};
for(pos=55;pos<85;pos+=1){
head_servo.write(pos);
delay(15);
};
break;

もしも「f」を受け取った場合は、首を左右に動かします。

「ウィンク」の動作

Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
case'w'://Rasberry Piからwを受け取ると「ウインク」 のアクションを行う。
analogWrite(l_eye,eye_light_default);
digitalWrite(r_eye,LOW);
delay(500);
analogWrite(l_eye,eye_light_default);
analogWrite(r_eye,eye_light_default);
delay(500);
digitalWrite(l_eye,LOW);
analogWrite(r_eye,eye_light_default);
delay(500);
analogWrite(l_eye,eye_light_default);
analogWrite(r_eye,eye_light_default);
break;

もしも「w」を受け取った場合は、目を交互に点灯させます。

「びっくり」の動作

Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
case'b'://Rasberry Piからwを受け取ると「びっくり」のアクションを行う。
for(pos=eye_default;pos<105;pos+=1){
eye_servo.write(pos);
delay(15);
};
analogWrite(l_eye,250);
analogWrite(r_eye,250);
delay(350);
analogWrite(l_eye,eye_light_default);
analogWrite(r_eye,eye_light_default);
delay(100);
eye_servo.write(eye_default);
delay(100);
break;

もしも「b」を受け取った場合は、目を上げ、目の光を大きくします。終わると元の状態に戻ります。

「ハイテンション」の動作

Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
case'e'://Rasberry Piからeを受け取ると「ハイテンション」のアクションを行う。
for(ch=0;ch<5;ch+=1){
digitalWrite(l_mouse,HIGH);
digitalWrite(m_mouse,HIGH);
digitalWrite(r_mouse,HIGH);
analogWrite(l_eye,eye_light_default);
digitalWrite(r_eye,LOW);
delay(100);
digitalWrite(l_eye,LOW);
analogWrite(r_eye,eye_light_default);
delay(100);
eye_servo.write(random(eye_default,110));
head_servo.write(random(25,135));
delay(100);
analogWrite(l_eye,eye_light_default);
analogWrite(r_eye,eye_light_default);
delay(100);
digitalWrite(l_mouse,LOW);
digitalWrite(m_mouse,LOW);
digitalWrite(r_mouse,LOW);
delay(100);
}
eye_servo.write(eye_default);
head_servo.write(head_default);
analogWrite(l_eye,eye_light_default);
analogWrite(r_eye,eye_light_default);
digitalWrite(r_mouse,LOW);
digitalWrite(l_mouse,LOW);
digitalWrite(m_mouse,LOW);
break;

もしも「e」を受け取った場合は、口を点灯させ、目を交互に点灯させ、首を上下左右に動かします。終わると元の状態に戻ります。

「上記以外のコマンドが入力された時」の動作

Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
default:
eye_servo.write(eye_default);
head_servo.write(head_default);
analogWrite(l_eye,eye_light_default);
analogWrite(r_eye,eye_light_default);
digitalWrite(r_mouse,LOW);
digitalWrite(l_mouse,LOW);
digitalWrite(m_mouse,LOW);
break;
}
}
}

上記以外を受け取った場合は、初期設定値のままにします。

以上でArduinoのソースコード(mugbot_arduino)の解説を終了します。