簡単C++/C言語

はじめに

まずはC/C++言語で記述されたArduino用プログラム(プログラムのことをArduinoではスケッチと呼びます)の例をもとに、C/C++言語のプログラムがどのようなものかを簡単に見ていきます。

例題として、Arduinoソフトウェアについてくる例題の中からButtonを取り上げます。

Button

以下にスケッチを示します。このスケッチは、Arduinoソフトウェアで、「ファイル > スケッチの例 > 02.Digital > Button」と選んでいくと表示されます。

このスケッチは、2番ピンに接続されたボタンを押すと、13番ピンに接続されたLEDが点灯するというスケッチです。ボタンがなくても、2番をGNDにつなげたり、+5Vにつなげたりすることで、ボタンと同等の動きをさせることができます。

 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
44
45
46
47
48
49
50
51
/*
  Button

  Turns on and off a light emitting diode(LED) connected to digital pin 13,
  when pressing a pushbutton attached to pin 2.

  The circuit:
  - LED attached from pin 13 to ground
  - pushbutton attached to pin 2 from +5V
  - 10K resistor attached to pin 2 from ground

  - Note: on most Arduinos there is already an LED on the board
    attached to pin 13.

  created 2005
  by DojoDave <http://www.0j0.org>
  modified 30 Aug 2011
  by Tom Igoe

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/Button
*/

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
}

void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    // turn LED on:
    digitalWrite(ledPin, HIGH);
  } else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
}

コメント

1行目から28行目まではコメント行です。コメントは自由に記述することができる文字列で、プログラムの実行には影響は与えません。コメントを適切に書いておくと後からプログラムを見たときや、他人がプログラムを見たときにどのような意図でそのプログラムを書いたのかが簡単に理解できます。一方、間違えたコメントを書いておくと…

C++/Cのコメントには2種類あります。一つ目のコメントは「/*」で始まり「*/」で終わります。2つ目のコメントは「//」で始まり行末で終わります。どちらの形式のコメントを使うかはプログラムを書く人の好みです。長い行にわたってのコメントを書くときは「/* */」を、短い行にコメントを書くときや、20行目のように行の後半にコメントを書く場合は「//」を使うことが多いようです。

変数

25
26
27
28
29
30
// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;  

26行目と27行目はint型の変数buttonPinとledPinを定義し、それぞれ、2と13を代入しています。30行目はbuttonStateというint型の変数を定義して、初期値として0を代入しています。変数は値を格納するメモリ上の領域に名前を付けたものです。変数は利用する前に定義しておく必要があります。

Arduinoで用いるC++/C言語では変数に入れるもの、例えば整数なのか文字なのか、によって変数の「型」を適切に定義する必要があります。今回は、buttonPinやledPin、buttonStateという変数をint型の変数として定義しています。int型はArduino Unoの場合は、-32768から32767までの整数を格納可能な型です。Arduino Dueの場合は、 -2147483648 から2147483647までの整数を格納可能です。

29行目と30行目では先頭に「const」というキーワードがついています。33行目ではこのキーワードはありません。「const」は値を後で変更できなくするためのキーワードです。上記の例では、constキーワード付きで定義されているのでbuttonPinやledPinはこの後変更することはできません。また、変数を定義した時点で値を設定する必要があります。const宣言した変数を後で変更したり、初期化を忘れたりするとコンパイラがエラーを出してくれます。一方、buttonStateは後で変更することができます。constを適切に利用することでプログラムの意図が明確になるとともに、ミスを削減することができます。

関数

32
33
34
35
36
37
void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
}

32行目から37行目では、setup()という関数を定義しています。setup()という関数はArduinoを用いる際に定義する必要のある関数の一つで、スケッチの開始直後に一回呼び出される関数です。

関数とは一連の処理(命令)をまとめたものです。例えば、意味のある処理の塊を定義するときや、同一の処理を繰り返し実行する必要があるとき、他のスケッチでも再利用したい場合などに定義します。関数化により処理の詳細を隠すこともできます。例えば、pinMode()という関数は内部でCPUのレジスタの操作等を実施していますが、関数がどのように実装されているのかを知ることなしに、関数を利用することができます。

C++/C言語では通常main()という関数が一番最初に呼ばれます。その後、種々の関数を呼び出すことでプログラムが実行されていきます。Arduinoでは、main()関数はArduinoソフトウェアが定義しているので、利用者は定義する必要はありません。Arduinoソフトウェアのmain()関数は、その中でsetup()と いう関数を一度呼び出した後、loop()という関数を無限回呼び出す構造になっています。

関数には、avr-gcc/avr-libcなどの言語系が用意している関数とArduinoソフトウェアが用意 している関数(Arduinoソフトウェアに付属しているもの)、Arduino利用者が作成して公開されている関数(Web等で公開されていて自分の環境にダウンロードして利用するもの)、Arduino利用者が自分で書く関数の、大きく4種類が存在します。

34行目ではledPin(13番ピン)を出力(OUTPUT)モードに、36行目ではbuttonPin(2番ピン)を入力(INPUT)モードに設定します。

39
40
41
42
43
44
45
46
47
48
49
50
51
void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    // turn LED on:
    digitalWrite(ledPin, HIGH);
  } else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
}

39行目からはloop()を定義しています。

41行目では、30行目で定義した変数buttonStateにdigitalRead(buttonPin)を呼び出した結果得られる値を代入しています。digitalRead()は指定した番号のデジタルピンの値を読み取る関数です。C++/Cの関数は一つの値を返すように定義することもできます。今までに出てきたpinMode()digitalWrite()は値を返さない関数ですが、digitalRead()int型の値を返す関数です(ただし、実際に返すのはHIGHかLOWの2種類です)。これにより、buttonPin(2番ピン)の値がbuttonStateに代入されます。代入を行うためには、基本的には左辺と右辺の型が同じである必要があります。今回は両方ともint型なのでうまく代入できます。

条件分岐

43
44
45
46
47
48
49
50
  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    // turn LED on:
    digitalWrite(ledPin, HIGH);
  } else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }

44行目では、if文を使ってbuttonStateがHIGHと等しいかどうかを検査しています。等しいかどうかを検査する演算子は「==」であり、「=」ではないことに注意してください。「=」を使っても文法上は問題がない場合はエラーにはなりません。注意しないと意図したとおりにプログラムが動作せず、かつ、思い込みによってバグの発見が難しくなります。条件が満たされた場合は、if文の直後の「{}」の中に書かれているプログラムが実行されます。条件が満たされない場合は、その後の「else」の直後の「{}」の中に書かれているプログラムが実行されます。今回は{}の中には一つの命令し書かれていませんが、複数の命令を書くこともできます。

buttonStateがHIGHであれば、50行目のdigitalWrite(ledPin, HIGH)が実行され、LEDが点灯します。HIGHでなければ54行目のdigitalWrite(ledPin, LOW)が実行され、LEDが消灯します。

最終更新日

February 11, 2021

inserted by FC2 system