(農業)情報工学・課題 (2020/01/08))

 Arduino入門(2)

前回、Arduinoのセットアップを行ったが、今回の講義では実際にArduinoを用いて、その使い方を体験する。
なおPCラボ設置のPCには、ArduinoIDEとUSBドライバのインストールを行ったので、どのPCを利用してもArduinoUNOが動作する事を確認している。
本日は、このArduinoの入力機能と出力機能を活用する方法を体験する。
来週に向けては、このArduinoUNOを用いて何かの「作品」を作成し、その作品の概要を全員の前で「プレゼンテーション」してもらう予定である。(2020年1月16日の予定)
なお、前回「Lチカ」が出来なかったグループは、まず「Lチカ」を行ってみること。→前回
ArduinoIDEの起動:PCのデスクトップ画面にArduinoのアイコンがあるので、それをクリックすると起動する。
Lチカのバリエーション

Lチカでは、点滅の周期を変更させることができた。この点滅の周期を工夫すると、人間の目には明るさが変化したように見える制御も可能である。点灯時間を5ms、消灯時間を15msにすると、約半分の明るさに見える筈である。また、点灯時間を1ms、消灯時間を19msにすると更に暗くなる筈である。→時間のある人は、やってみよう
Arduinoでは、この方式をマイコン上でパルス制御として組み込んである。それがPWM(Pulse Width Modulation)機能である。ただ、このPWM機能を用いる事の出来る出力ピンは、3,5,6,9,10,11である。(ピン番号の横に~(チルダ)が表示されている。プログラム的には次の様になる。(この例では、11番ピンでLED出力をしている。)

const int LED_PIN=11; // No 11 を出力ピン
const int DUTY = 250; // Duty は、出力強度(0−255) 

void setup() {
  pinMode(LED_PIN, OUTPUT);
}

void loop() {
  analogWrite(LED_PIN, DUTY);
}
このPWMを応用すると、例えば次の様に、徐々にLEDを明るくするといった点灯も可能になる。
  
const int LED_PIN = 11;
const int WAITTIME = 100; // 徐々に明るくなる制御の待ち時間を100msに
const int STEP = 5; // 明るくなるタイミングを5ステップずつ増やす。

void setup(){
    pinMode( LED_PIN, OUTPUT ); // 11番ピンを出力に指定
}

void loop(){
    int i;
    i = 0;
    while ( i <= 255 ){
        analogWrite( LED_PIN, i );
        delay( WAITTIME );
        i = i + STEP;
    }
    delay(1000); // 1秒間そのままで
}

スイッチを使う
電子回路でよく利用されるスイッチに「タクトスイッチ」がある。これはスイッチのボタンを押している時に回路がつながり、離すと切れるスイッチである。
電子回路においては基本的に端子の電圧はH(High)またはL(LOW)の状態が期待されている。スイッチの取り扱いでも、そのどちらかの状態を保つことが期待されるため、スイッチが切れた状態でも、電圧が不安定にならないようにスイッチの片側には電圧を保障するための「プルアップ抵抗」(または「プルダウン抵抗」)を置くことが基本である。
Arduinoに置いては、そのプルアップ抵抗が回路に内蔵されているので、その回路を用いてスイッチの制御を行う事とする。実際のスケッチは次の様になる。
スイッチの接続としては、タクトスイッチの左側にArduinoUNOのGND信号線を、右側に7番ピンの信号線を接続する。

    const int DIN_PIN = 7; // スイッチの接続ピン
    const int LED_PIN = 12; // LEDの接続ポート
    
    void setup(){
        pinMode( DIN_PIN, INPUT_PULLUP );  // スイッチにプルアップ設定
        pinMode( LED_PIN, OUTPUT );
    }
    
    void loop(){
        int value;  // スイッチの状態
        
        value = digitalRead( DIN_PIN ); // スイッチ状態の確認
    
        if ( value == HIGH ){     // 押されていれば、HIGH
            digitalWrite( LED_PIN, LOW ); // LEDはLOWで点灯
        }
        else{
            digitalWrite( LED_PIN, HIGH );
        }
    
        delay( 100 ); // スイッチのチャタリング防止
    }
  
データの読込:温湿度センサ
今度は、温湿度センサを接続して、その数値を読み取ってみる。今回接続するセンサはDHT11である。 このセンサを利用するには、ライブラリの利用が簡単である。以下の手順でArduinoIDEにライブラリをインストールする。
「ツール」⇒「ライブラリを管理…」からインストールする。※下記2つともインストールが必要である。
1.タイプで「推奨」を選択、「DHT sensor library」でフィルタリング
2.タイプで「推奨」を選択「Adafruit Unified Sensor」でフィルタリング
接続方法とスケッチ例:
今回のDHT11モジュールは、既にプルアップ抵抗が組み込まれている。そのため電源線(GNDと5Vの2本)と信号線(1本のみ)の合計3本をArduinoUNOに接続する。電源線はArduinoUNOのGNDと5V、信号線は、今回、8番ポートを利用する。

  //温湿度センサモジュールを使って温度、湿度を測定するスケッチ
  //(https://omoroya.com/arduino-lesson11/ から引用)
  //
  #include "DHT.h" //ライブラリインクルード
  
  #define DHT_Pin 8 //DHT11のDATAピンを定義
  #define DHT_Type DHT11 //センサの型番定義 DHT11,DHT22など
  
  DHT dht(DHT_Pin, DHT_Type); //センサ初期化
  
  /* 計測値設定 */
  float humidity = 0.0f; //湿度(実数値)
  float tempC = 0.0f; //摂氏温度(実数値)
  
  void setup() {
  Serial.begin(9600); //シリアル通信のデータ転送レートを9600bpsで指定。bpsはビット/秒。
  Serial.println("DHT11 読み取り結果"); //画面に表示
  dht.begin(); //温湿度センサー開始
  }
  
  void loop() {
  delay(2000); //2秒待つ データの読み出し周期1秒以上必要。
  
  humidity = dht.readHumidity(); //湿度の読み出し
  tempC = dht.readTemperature(); //温度の読み出し 摂氏
  
  /* 読み取れたかどうかのチェック */
  if (isnan(humidity) || isnan(tempC)) {
  Serial.println("読み取り失敗!");
  return;
  }
  
  /* 以下読み取り値の表示 */
  Serial.print("湿度: ");
  Serial.print(humidity);
  Serial.println("[%]");
  Serial.print("温度: "); 
  Serial.print(tempC);
  Serial.println("[℃]");
  }
このスケッチを転送して、ArduinoIDEの「ツール」から「シリアルモニタ」を開くと、現在の気温と湿度が読み取れる。
DHT11 読み取り結果
湿度: 47.00[%]
温度: 19.50[℃]
湿度: 47.00[%]
温度: 19.40[℃]
湿度: 47.00[%]
温度: 19.40[℃]
.....

光センサでLEDの制御
ここでは、光センサ(CdSセル)を利用したLEDの点灯制御を行う。CdSセルは照度が低いと抵抗値が大きくなり、高いと抵抗値が小さくなる。その抵抗値の違いを利用して、LEDの点灯制御を行ってみる。

Arduinoのアナログポートで計測可能なのは電圧である。そのためCdSセル(Rc)と既存の抵抗(Ra)を直列に接続して5Vを接続し、明るさに応じてCdSに印可される電圧を測定することによって、照度を測定することが出来る。
スケッチは次の様になる。

        // CdSセンサでLEDの制御(明るさを4段階で制御)
        int val=0; //入力される値を格納する為の変数(0 - 1023)
        int ledVal = 0; //LEDに出力する値の変数 (0 - 255)
        int Level1 = 100;  //周囲の明るさレベル1
        int Level2 = 120;  //周囲の明るさレベル2
        int Level3 = 130;  //周囲の明るさレベル3
        int Level4 = 150;  //周囲の明るさレベル4
        void setup() {
        Serial.begin(9600); //モニターに出力するための設定
        }
        
        void loop() {
        val=analogRead(0);//ANALOG INの0番ピンからデータを受け付ける
        ledVal = val/4; //LED出力用の値を変数に格納
        Serial.println(ledVal); //入力された値をモニターに出力
        //明るさを4段階に設定する
          if(ledVal < Level1){ // 入力値がLevel1以下
            analogWrite(3,0); //出力は0
          }
          else if(ledVal < Level2){ // Level1 - Level2
            analogWrite(3,100); //出力は100
          }
          else if(ledVal < Level3){  // Level2 - Level3
            analogWrite(3,150); //出力は150
          }
          else if(ledVal < Level4){ // Level3 - Level4
            analogWrite(3,200); //出力は200
          }
          else{ // > Level4
            analogWrite(3,255); //出力は255 
          }
          delay(100); // 回路の安定化
        }
      
このスケッチを実行する際に、「ツール」から「シリアルモニタ」を確認すると、CdSの測定値を見ることが出来る。アナログ出力は(0-1023)の10ビットであるが、ここでは4で割った(0-255)の8ビットにしている。CdSセルに手をかざして、数値の変化を見ると、理解が出来ると思う。その数値に応じて、LEDのレベルを変えるスケッチを組んでみて欲しい。
音の出力
Arduinoからの音の出力も可能である。音は圧電素子(スピーカー)を決まった周期で発振させる事によって出力できる。
Arduinoには音の関数があるので、それを利用すると簡単にビープ音を出すことができる。なおこの機能で出力される波形は矩形波なので音質はあまり良くない(耳障り)なので、実施する際には気を付けること。
接続は、圧電素子の一方にGNDを、一方にデジタルポートを接続するのみである。なお、tone関数の実行中は、PWMの3番ポートと11番ポートは利用できない。また音の停止は、
noTone(ポート番号);
である。

    // https://novicengineering.com/ を参照した。
    // ドレミを順番に出力するスケッチ。
    // 音を出さなくするには、noTone(PIN); 

    #define BEATTIME 300  // 音の持続時間を300msにしている。
    #define PIN 12 // 12番ピンに出力。
    
    #define DO 262  // ドの周波数は262Hz
    #define RE 294
    #define MI 330
    #define FA 349
    #define SO 392
    #define RA 440
    #define SI 494
    #define HDO 523
    
    void setup() {
    }
    
    void loop() {
      tone(PIN,DO,BEATTIME) ; // ド
      delay(BEATTIME) ;
      tone(PIN,RE,BEATTIME) ; // レ
      delay(BEATTIME) ;
      tone(PIN,MI,BEATTIME) ; // ミ
      delay(BEATTIME) ;
      tone(PIN,FA,BEATTIME) ; // ファ
      delay(BEATTIME) ;
      tone(PIN,SO,BEATTIME) ; // ソ
      delay(BEATTIME) ;
      tone(PIN,RA,BEATTIME) ; // ラ
      delay(BEATTIME) ;
      tone(PIN,SI,BEATTIME) ; // シ
      delay(BEATTIME) ;
      tone(PIN,HDO,BEATTIME) ; // ド
      delay(BEATTIME) ;
    }
  

今回の課題

今回は、とにかくArduinoを使って、いろいろな回路を試して欲しい。キットの中に入っているLCDや水分センサについては、説明していないが、リンクから辿ると利用が出来る。余裕のある班はLCDへの表示などを試みて欲しい。

リンク集