Skip to content

マイクロコントローラプログラミングコース第一週

1. day1: Arduino-UNO-R4-WiFiの基礎

1.1 Arduino UNO R4 WiFiの概要

Arduino UNO R4 WiFiは、従来のArduino UNOの機能を大幅に拡張した最新のマイコンボードです。Renesas RA4M1マイコンを搭載し、WiFi機能を内蔵しているのが特徴です。

主な特徴

  • 処理能力:100MHz 32ビットARM Cortex-M4コア
  • メモリ:256KB Flash、32KB SRAM
  • 内蔵WiFi:ESP32-S3モジュール搭載
  • デジタルI/Oピン:14本(うち6本がPWM出力可能)
  • アナログ入力ピン:6本
  • 動作電圧:5V(ロジック電圧は3.3V)

Arduino UNO R4 WiFiのブロック図

graph TD
    A[Arduino UNO R4 WiFi] --> B[Renesas RA4M1 MCU]
    A --> C[ESP32-S3 WiFiモジュール]
    B --> D[デジタルI/O]
    B --> E[アナログ入力]
    B --> F[PWM出力]
    C --> G[WiFi 2.4GHz]
    C --> H[Bluetooth LE]
CPUのデータシート

ここからデータシートをダウンロードできます

RENESAS HP

Note

ゆとりがあればデータシートを見てみましょう

1.2 開発環境のセットアップ

Arduino UNO R4 WiFiの開発には、Arduino IDE 2.xを使用します。

Arduino IDEのインストール手順

  1. Arduino公式サイト(https://www.arduino.cc/en/software)からArduino IDE 2.xをダウンロード
  2. ダウンロードしたインストーラを実行
  3. インストールウィザードの指示に従ってインストール
  4. インストール完了後、Arduino IDEを起動

ボードマネージャの設定手順を図で表すと

sequenceDiagram
    participant User
    participant ArduinoIDE
    participant BoardManager
    User->>ArduinoIDE: 起動
    User->>ArduinoIDE: ツール > ボード > ボードマネージャを選択
    ArduinoIDE->>BoardManager: ボードマネージャを開く
    User->>BoardManager: "Arduino UNO R4"で検索
    BoardManager->>User: Arduino UNO R4ボードパッケージを表示
    User->>BoardManager: インストールボタンをクリック
    BoardManager->>ArduinoIDE: ボードパッケージをインストール
    ArduinoIDE->>User: インストール完了を通知

TODO デジタル回路の講習も検討する?

1.3 基本的な入出力操作

デジタル出力: LEDの点滅

const int ledPin = 13;  // オンボードLEDはピン13に接続されています

void setup() {
  pinMode(ledPin, OUTPUT);  // LEDピンを出力モードに設定
}

void loop() {
  digitalWrite(ledPin, HIGH);  // LEDをオン
  delay(1000);                 // 1秒待機
  digitalWrite(ledPin, LOW);   // LEDをオフ
  delay(1000);                 // 1秒待機
}

デジタル入力: プッシュボタンの読み取り

graph LR
    A[5V] --> B[10kΩ抵抗]
    B --> C[プッシュボタン]
    C --> D[デジタルピン2]
    C --> E[GND]
    F[デジタルピン13] --> G[LED]
    G --> H[220Ω抵抗]
    H --> I[GND]
const int buttonPin = 2;  // プッシュボタンは2番ピンに接続
const int ledPin = 13;    // LEDは13番ピンに接続

int buttonState = 0;      // ボタンの状態を格納する変数

void setup() {
  pinMode(ledPin, OUTPUT);      // LEDピンを出力として設定
  pinMode(buttonPin, INPUT);    // ボタンピンを入力として設定
}

void loop() {
  buttonState = digitalRead(buttonPin);  // ボタンの状態を読み取る

  if (buttonState == HIGH) {    // ボタンが押されている場合
    digitalWrite(ledPin, HIGH); // LEDをオン
  } else {                      // ボタンが押されていない場合
    digitalWrite(ledPin, LOW);  // LEDをオフ
  }
}

1.4 シリアル通信

Arduino UNO R4 WiFiはUSB経由でシリアル通信を行うことができます。

シリアルモニタの使用

1
2
3
4
5
6
7
8
void setup() {
  Serial.begin(9600);  // シリアル通信を9600bpsで初期化
}

void loop() {
  Serial.println("Hello, Arduino UNO R4 WiFi!");  // メッセージを送信
  delay(1000);  // 1秒待機
}

シリアル通信のフローチャート

graph TD
    A[開始] --> B[シリアル通信初期化]
    B --> C{1秒経過?}
    C -->|Yes| D[メッセージ送信]
    D --> C
    C -->|No| C

Day 2: センサーとアクチュエータの制御

2.1 アナログ入力: 光センサーの読み取り

graph LR
    A[5V] --> B[フォトレジスタ]
    B --> C[アナログピンA0]
    B --> D[10kΩ抵抗]
    D --> E[GND]
const int photoPin = A0;  // フォトレジスタをA0ピンに接続

void setup() {
  Serial.begin(9600);
}

void loop() {
  int lightLevel = analogRead(photoPin);  // 光レベルを読み取る(0-1023)
  Serial.print("Light level: ");
  Serial.println(lightLevel);
  delay(1000);
}

2.2 PWM出力: LEDの輝度制御

const int ledPin = 9;  // PWM対応のピン9にLEDを接続

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

void loop() {
  for (int brightness = 0; brightness <= 255; brightness++) {
    analogWrite(ledPin, brightness);
    delay(10);
  }
  for (int brightness = 255; brightness >= 0; brightness--) {
    analogWrite(ledPin, brightness);
    delay(10);
  }
}

2.3 サーボモーターの制御

graph LR
    A[5V] --> B[サーボモーター]
    B --> C[デジタルピン9]
    B --> D[GND]
#include <Servo.h>

Servo myservo;  // サーボオブジェクトを作成
int pos = 0;    // サーボの位置を格納する変数

void setup() {
  myservo.attach(9);  // サーボをピン9に接続
}

void loop() {
  for (pos = 0; pos <= 180; pos += 1) {
    myservo.write(pos);  // サーボを指定した角度に移動
    delay(15);           // 動作完了を待つ
  }
  for (pos = 180; pos >= 0; pos -= 1) {
    myservo.write(pos);
    delay(15);
  }
}

Day 3: 割り込みとタイマー

3.1 外部割り込み

const int interruptPin = 2;  // 割り込みピンは2または3を使用
volatile int interruptCounter = 0;

void setup() {
  Serial.begin(9600);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, FALLING);
}

void loop() {
  Serial.print("Interrupts: ");
  Serial.println(interruptCounter);
  delay(1000);
}

void handleInterrupt() {
  interruptCounter++;
}

3.2 タイマー割り込み

#include <TimerOne.h>

const int ledPin = 13;
volatile int ledState = LOW;

void setup() {
  pinMode(ledPin, OUTPUT);
  Timer1.initialize(1000000);  // 1秒ごとに割り込み
  Timer1.attachInterrupt(blinkLED);
}

void loop() {
  // メインループは空
}

void blinkLED() {
  ledState = !ledState;
  digitalWrite(ledPin, ledState);
}

3.3 割り込みを使用したデバウンス

graph TD
    A[開始] --> B[ボタン状態変化]
    B --> C{デバウンス時間経過?}
    C -->|Yes| D[状態更新]
    C -->|No| E[無視]
    D --> F[動作実行]
    E --> B
    F --> B
const int buttonPin = 2;
volatile unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;  // デバウンス時間(ミリ秒)
volatile int buttonState = HIGH;
volatile int lastButtonState = HIGH;

void setup() {
  Serial.begin(9600);
  pinMode(buttonPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(buttonPin), handleInterrupt, CHANGE);
}

void loop() {
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (buttonState != lastButtonState) {
      lastButtonState = buttonState;
      if (lastButtonState == LOW) {
        Serial.println("Button Pressed!");
      }
    }
  }
}

void handleInterrupt() {
  lastDebounceTime = millis();
  buttonState = digitalRead(buttonPin);
}

Day 4: WiFi通信の基礎

4.1 WiFi接続の設定

#include <WiFiS3.h>

char ssid[] = "YourNetworkSSID";
char pass[] = "YourNetworkPassword";
int status = WL_IDLE_STATUS;

void setup() {
  Serial.begin(9600);
  while (!Serial);

  // WiFiモジュールの確認
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    while (true);
  }

  // WiFiネットワークへの接続
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, pass);
    delay(10000);
  }

  Serial.println("You're connected to the network");
}

void loop() {
  // ここにメインのコードを記述
}

4.2 HTTPクライアントの実装

sequenceDiagram
    participant Arduino
    participant WiFi
    participant Server
    Arduino->>WiFi: 接続
    WiFi->>Server: HTTPリクエスト送信
    Server->>WiFi: レスポンス送信
    WiFi->>Arduino: データ受信
    Arduino->>Arduino: データ処理
#include <WiFiS3.h>
#include <ArduinoHttpClient.h>

char ssid[] = "YourNetworkSSID";
char pass[] = "YourNetworkPassword";
char serverAddress[] = "example.com";  // サーバーのアドレス
int port = 80;

WiFiClient wifi;
HttpClient client = HttpClient(wifi, serverAddress, port);

void setup() {
  Serial.begin(9600);
  while (!Serial);

  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to WiFi");
}

void loop() {
  Serial.println("Making GET request");
  client.get("/");

  int statusCode = client.responseStatusCode();
  String response = client.responseBody();

  Serial.print("Status code: ");
  Serial.println(statusCode);
  Serial.print("Response: ");
  Serial.println(response);

  delay(5000);
}

4.3 MQTT通信の基礎

#include <WiFiS3.h>
#include <ArduinoMqttClient.h>

char ssid[] = "YourNetworkSSID";
char pass[] = "YourNetworkPassword";

WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);

const char broker[] = "test.mosquitto.org";
int        port     = 1883;
const char topic[]  = "arduino/test";

void setup() {
  Serial.begin(9600);
  while (!Serial);

  // WiFi接続
  Serial.print("Attempting to connect to WPA SSID: ");
  Serial.println(ssid);
  while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
    Serial.print(".");
    delay(5000);
  }

  Serial.println("You're connected to the network");

  // MQTTブローカーへの接続
  Serial.print("Attempting to connect to the MQTT broker: ");
  Serial.println(broker);

  if (!mqttClient.connect(broker, port)) {
    Serial.print("MQTT connection failed! Error code = ");
    Serial.println(mqttClient.connectError());
    while (1);
  }

  Serial.println("You're connected to the MQTT broker!");
}

void loop() {
  // メッセージの送信
  Serial.print("Sending message to topic: ");
  Serial.println(topic);

  mqttClient.beginMessage(topic);
  mqttClient.print("Hello from Arduino UNO R4 WiFi!");
  mqttClient.endMessage();

  Serial.println("Message sent");

  delay(5000);
}

Day 5: IoTプロジェクト開発

5.1 環境モニタリングシステムの構築

以下のプロジェクトでは、温度センサーと光センサーを使用して環境データを収集し、それをMQTTを通じてクラウドに送信します。

回路図

graph LR
    A[Arduino UNO R4 WiFi] -- A0 --> B[光センサー]
    A -- A1 --> C[温度センサー LM35]
    B --> D[GND]
    C --> D
    B --> E[5V]
    C --> E

コード

#include <WiFiS3.h>
#include <ArduinoMqttClient.h>

char ssid[] = "YourNetworkSSID";
char pass[] = "YourNetworkPassword";

WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);

const char broker[] = "test.mosquitto.org";
int        port     = 1883;
const char topic[]  = "arduino/environment";

const int lightSensorPin = A0;
const int temperatureSensorPin = A1;

void setup() {
  Serial.begin(9600);
  while (!Serial);

  // WiFi接続
  Serial.print("Attempting to connect to WPA SSID: ");
  Serial.println(ssid);
  while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
    Serial.print(".");
    delay(5000);
  }

  Serial.println("You're connected to the network");

  // MQTTブローカーへの接続
  Serial.print("Attempting to connect to the MQTT broker: ");
  Serial.println(broker);

  if (!mqttClient.connect(broker, port)) {
    Serial.print("MQTT connection failed! Error code = ");
    Serial.println(mqttClient.connectError());
    while (1);
  }

  Serial.println("You're connected to the MQTT broker!");
}

void loop() {
  // センサーデータの読み取り
  int lightLevel = analogRead(lightSensorPin);
  float voltage = analogRead(temperatureSensorPin) * 5.0 / 1024.0;
  float temperatureC = voltage * 100;

  // JSONフォーマットでデータを作成
  String message = "{\"light\":" + String(lightLevel) + 
                   ",\"temperature\":" + String(temperatureC) + "}";

  // メッセージの送信
  Serial.print("Sending message to topic: ");
  Serial.println(topic);

  mqttClient.beginMessage(topic);
  mqttClient.print(message);
  mqttClient.endMessage();

  Serial.println("Message sent: " + message);

  delay(5000);
}

5.2 データ可視化

収集したデータを可視化するために、Webアプリケーションを作成することができます。以下は、簡単なHTMLとJavaScriptを使用したデータ可視化の例です。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Environment Monitor</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
    <h1>Environment Monitor</h1>
    <canvas id="environmentChart"></canvas>

    <script>
        // MQTTクライアントの設定
        const client = new Paho.MQTT.Client("test.mosquitto.org", 8080, "webclient-" + parseInt(Math.random() * 100, 10));

        client.onMessageArrived = onMessageArrived;

        client.connect({onSuccess:onConnect});

        function onConnect() {
            console.log("Connected to MQTT broker");
            client.subscribe("arduino/environment");
        }

        // グラフの設定
        const ctx = document.getElementById('environmentChart').getContext('2d');
        const chart = new Chart(ctx, {
            type: 'line',
            data: {
                labels: [],
                datasets: [{
                    label: 'Light Level',
                    data: [],
                    borderColor: 'rgb(255, 99, 132)',
                    tension: 0.1
                }, {
                    label: 'Temperature (°C)',
                    data: [],
                    borderColor: 'rgb(54, 162, 235)',
                    tension: 0.1
                }]
            },
            options: {
                responsive: true,
                scales: {
                    x: {
                        type: 'time',
                        time: {
                            unit: 'second'
                        }
                    }
                }
            }
        });

        function onMessageArrived(message) {
            const data = JSON.parse(message.payloadString);
            const now = new Date();

            chart.data.labels.push(now);
            chart.data.datasets[0].data.push(data.light);
            chart.data.datasets[1].data.push(data.temperature);

            if (chart.data.labels.length > 20) {
                chart.data.labels.shift();
                chart.data.datasets[0].data.shift();
                chart.data.datasets[1].data.shift();
            }

            chart.update();
        }
    </script>
</body>
</html>

この HTML ファイルをウェブブラウザで開くと、Arduino から送信されたデータをリアルタイムでグラフ表示することができます。

5.3 プロジェクトの拡張

このプロジェクトは以下のように拡張することができます:

  1. より多くのセンサーを追加する(例:湿度センサー、気圧センサーなど)
  2. アクチュエータを追加して、特定の条件下で動作するようにする(例:温度が高すぎる場合にファンを起動する)
  3. データをクラウドストレージに保存し、長期的なトレンド分析を行う
  4. アラート機能を追加し、特定の閾値を超えた場合に通知を送る
  5. モバイルアプリを開発し、リモートでデータをモニタリングおよび制御できるようにする

これらの拡張を行うことで、より複雑で実用的なIoTシステムを構築することができます。

まとめ

この5日間のコースを通じて、Arduino UNO R4 WiFiの基本的な使用方法から、センサーの制御、WiFi通信、そしてIoTプロジェクトの開発まで学びました。これらの知識とスキルを基に、さまざまな組み込みシステムやIoTデバイスを開発することができます。

継続的な学習と実践を通じて、より高度なプロジェクトに挑戦し、組み込みエンジニアとしてのスキルを磨いていくことをおすすめします。

UNO R4 WiFiチートシート(NEW TAB)