初心者歓迎!Arduinoで初めるC言語プログラミング(文法編)‐サンプルプログラムあり!

知識勉強

導入編ではArduinoの準備が整いました。まだの方は導入編へ

この記事は、こういった声をサポートしていきます!
Arduino初心者歓迎シリーズ:機器導入文法編(今ここ)、実践①実践②実践③実践④

・Arduinoやってみたいけど、よくわかんないや!

・順番に手取り足取り教えてほしい!

続いてはC言語のプログラム事例を交えながら
コードの書き方、実際にボードに書き込んで動かしながら説明していきます。

Arduino公式のスタートガイドもあります。最近は翻訳ソフトも優秀ですから、興味のある方はこちらもよいかもしれませんが、初心者の方にはハードル高めかと思います。

ぜひ、このページでは、丁寧に進めていきますので、一緒に体験していきましょう!

全部をまるっと覚える必要はありません。
最初は調べながら作ってみて動いたら、それを保存しておきましょう。自分の辞書になっていきます。また使う機会があれば、それを参考にしたりコピペして流用したり、もう一度ネットを参考にすれば良いのですから。

専門のプログラマーになりたいなら、仕事の効率を上げるのに覚えてないと話にならないでしょうが。。。

ぜひ導入編で準備したPCとArduinoボードを使って、この文法編を進めていってください。
一度、Arduinoにプログラムを書き込んでしまえば、電源さえPC以外から供給してあげれば
PCがなくても、勝手に動いてくれます。

PCとつないでデータをAruduinoから、もらうこともできます。そんな用途もありますが、
パソコンなくても、自分がいなくても勝手に動いて欲しいのが、マイコンにやってほしいことですよね。

それでは、ゆっくりやっていきましょう

基本的な文法と、それにまつわる話

変数ってなに?

変数は、値を格納するためのメモリ領域です。
変数は、いったんデータを預けておくところと思ってください。どんなデータの種類を、どれだけの量を、いつまで預かってくれるかを指示してあげる必要があります。
Arduinoでは、C言語と同様に、変数を下記のように宣言して使用します。以下は、整数型の変数を宣言する例です。

int ledPin = 13; // 整数型の変数ledPinを宣言し、13を代入する
  • int :型(種類が色々ありますので後述します)
  • ledPin :変数の名前(英名やローマ字でコード中に出てきたとき分かるように)
  • =13 :変数に13を代入(数学では左右は等しいの意味ですが右を左に代入するです)
  •  ; :セミコロン。文の終わりを示します
  •  // :スラッシュの後はコメント(メモ書き)で、命令からは外れます

Arduinoで使用できる変数の型は、以下のようになります。
どれを使っていいか、最初分からないかと思いますが、まずは範囲の小さいものを選びましょう。

なぜ小さいものにするか、マイコンのメモリは、PCほど大きくありません。
節約が必要となります。
整数扱うなら、とりあえずint型、文字ならわかりやすくchar型、小数点扱うならfloat型でしょうか。
ぼちぼちやっていきましょう。

  • int: 符号付きの整数値を格納するための型。
    -32768~32767までの範囲の値を格納できます。
  • unsigned int: 符号なしの整数値を格納するための型。
    0~65535までの範囲の値を格納できます。
  • long: 符号付きの長整数値を格納するための型。
    -2147483648~2147483647までの範囲の値を格納できます。
  • unsigned long: 符号なしの長整数値を格納するための型。
    0~4294967295までの範囲の値を格納できます。
  • char: 文字列や文字を格納するための型。
    1文字を格納することができます。
  • boolean: 真偽値を格納するための型。
    trueまたはfalseを格納することができます。
  • float: 浮動小数点数を格納するための型。精度は10進数で約6桁までです。
    -3.4028235E+38~3.4028235E+38
  • double: 浮動小数点数を格納するための型。float型よりも精度が高く、約15桁までの精度があります。 
    ※C言語的には高精度ですが、Arduino都合でfloatと同じになります

以上が、Arduinoで使用できる変数の型の一覧です。変数の型は、格納する値の範囲や精度に応じて適切なものを選ぶ必要があります。
範囲の小さいものに(int型)に、long型で扱うような大きい数値(32768)を入れるとオーバーフローといわれる用意した変数に収まりきらなくなってしまいます。
意図しない結果となり、バグの原因です

【詳しく知りたい人】
Arduino UNOではint型の変数に32768を代入すると、ATmega328Pといわれるマイコンが使われていまして、オーバーフローした場合には最下位ビットからの2の補数表現といわれることが行われ下限値に戻ります。そのため、32768は1はみ出る下限の‐32768と解釈され、int型の変数に代入されます。32769は-32767となります。

関数ってなに?

関数は、プログラム内で繰り返し使用される処理をまとめて、ひとまとめにしたものです。関数を使用することで、同じ処理を何度も書く必要がなくなり、プログラムの可読性が向上します。

Arduinoでは、デフォルトでsetup関数とloop関数が用意されています。以下は、LEDを点灯させるプログラムの例です。

void setup() {
  pinMode(ledPin, OUTPUT); // LEDピンを出力に設定する
}
void loop() {
  digitalWrite(ledPin, HIGH); // LEDを点灯
  delay(1000); // 1秒待機
  digitalWrite(ledPin, LOW); // LEDを消灯
  delay(1000); // 1秒待機
}

pinMode()、digitalWrite()、delay()も関数です。Arduinoを使いやすいように標準で用意されているもので、本体は別のところで定義してあります。関数名の英単語で何やっているかなんとなくわかるかと思います。用意された関数いっぱいあるので、こんなの作りたいなーとネットで検索してコピペして、そのまま使ってみましょう。

// 自作関数の定義
int add(int x, int y) {
  int sum = x + y;
  return sum;
}
// setup関数
void setup() {
  // シリアル通信の開始
  Serial.begin(9600);
}
// loop関数
void loop() {
  int a = 3;
  int b = 4;
  int c = add(a, b);
  Serial.print("a + b = ");
  Serial.println(c);
  delay(1000);
}

自分で関数を作ることもできます。コピペしてArduinoに書き込んでみてください
そのあとに、右上の虫メガネのアイコンをクリックしてみてください。

シリアルモニタを開く

この場合、変数cには、aとbを足した値である7が出力されます。
PCが計算しているわけではないですよ。Aruduinoが計算した値を、PCに送ってきてくれています。

戻り値の型 関数名(引数の型 引数1, 引数の型 引数2, ...) {
  // 処理内容を記述
  return 戻り値;
}

関数には、以下の要素が含まれます。

  • 戻り値の型: 関数が返す値の型を指定します。戻り値がない場合は、voidと指定します。
  • 関数名: 関数の名前を指定します。
  • 引数の型: 関数に渡す引数の型を指定します。引数がない場合は、空のカッコを指定します。
  • 引数: 関数に渡す引数を指定します。複数の引数がある場合は、カンマで区切ります。
  • 処理内容: 関数が行う処理を記述します。
  • 戻り値: 関数が返す値を指定します。戻り値がない場合は、return文を省略します。
戻り値の型 変数名 = 関数名(引数1, 引数2, ...);


プログラムの中で、何回も2つの値を合計しなきゃならないことがあったとすると、一回だけ関数作ってしまえば、int c = add(a, b);で使いまわすことができます。
2つの値が定数なので意味ないですが、実際つかうなら、2つの値が常に変化するようなときに便利になってきます。

条件分岐

条件分岐は、プログラムの流れを制御するために使用されます。Arduinoでは、if文を使用して条件分岐を実現します。以下は、ボタンが押されたかどうかを判定する例です。

if (digitalRead(buttonPin) == HIGH) { // ボタンが押されたかどうかを判定
  digitalWrite(ledPin, HIGH); // LEDを点灯
} else {
  digitalWrite(ledPin, LOW); // LEDを消灯
}

条件分岐をつかうことで、通り一辺倒だったプログラムに、動きを持たせることができます。
何かセンサの出力を条件にしたり、今回のようにボタンによって何かさせたりすることができます。

ループ

ループは、同じ処理を繰り返し実行するために使用されます。Arduinoでは、whileループやforループを使用してループ処理を実現します。以下は、while文でループしたLEDの点滅と、For文を使用したプログラムの例です。

1回だけ動けば終了することもあるとは思いますが、だいたいは、スイッチもう一度押したら動いて欲しいですし、待機状態にしておきたい場合が大概だと思います。

void setup() {
  pinMode(LED_BUILTIN, OUTPUT); // LEDピンを出力に設定する
}
void loop() {
  int i = 0;
  while (i < 10) { //10回ループ
    digitalWrite(LED_BUILTIN, HIGH); // LEDを点灯
    delay(1000); // 1秒待機
    digitalWrite(LED_BUILTIN, LOW); // LEDを消灯
    delay(1000); // 1秒待機
    i++;  //i = i +1 と同じことです
  }
}

一度、書き込んだプログラムはPCとの接続を切っても、Arduinoが覚えていてくれています。
モバイルバッテリーとかUSB充電器につないであげてください。
電源さえあれば、PCがなくても、LEDが点滅してくれます。

今は、LEDが点滅するだけですけど、皆さんが作ったプログラムが、勝手に仕事をしてくれるようになります。

続いてはこちら。

// setup関数
void setup() {
  // シリアル通信の開始
  Serial.begin(9600);
}
// loop関数
void loop() {
  int i;
  int sum = 0;
  // iが0から10未満の間、1ずつ増加しながら繰り返す
  for (i = 0; i < 10; i++) {
    sum += i;  // sum = sum + i と同じことです
  }
  Serial.print("sum = ");
  Serial.println(sum);
  delay(1000);
}

ループ(For文)の方は、Arduinoに書き込んだら、画面右上のシリアルモニタ(虫メガネアイコン)を起動してみてください。下記のように、1秒ごとに計算結果が表示されているかと思います。

プログラムの下記の2行のところを、別の場所に書き移して、
下記のように計算結果の途中がでるように動くように考えてみてください

Serial.print("sum = ");
Serial.println(sum);

下の方に答えがあります。

// setup関数
void setup() {
  // シリアル通信の開始
  Serial.begin(9600);
}
// loop関数
void loop() {
  int i;
  int sum = 0;
  // iが0から10未満の間、1ずつ増加しながら繰り返す
  for (i = 0; i < 10; i++) {
    sum += i;  // sum = sum + i と同じことです
    Serial.print("sum = ");
    Serial.println(sum);
  }
  delay(1000);
}

このように、ネットで見つけたプログラムも、もし自分の思ったやつと違っても、少し変えてあげたら望み通りになる場合もあります。

まとめ

いかがだったでしょうか。
知識面のところが多く、大変だったかと思います。ここで、すべて覚えなくても大丈夫です。
ネットで検索、コピー&ペーストができれば、問題なくやっていけるようになりますので
安心してください。

少しずつなれていけばプログラムの編集もできるようになってきます。
じっくりやっていきましょう。

それではお疲れ様でした。

この記事を書いた人
ユカタキ

私、気になります!
自分でやってみたくなる性格の私は、電子工作、プログラム、3Dプリンター関連の事などの情報を発信しています。
社会人から電子工作を始め14年、電験3種一発合格、2021年から3DプリンタをDIYに活用。
そんな私が、まだまだ調べながらではありますが、ほかのDIYユーザー皆さんのためになるようなことを心がけています

ユカタキをフォローする
知識勉強
ユカタキをフォローする

コメント