AIを使ってRGB LEDを点灯するスケッチを作成しました

AIを使ってスケッチを書く

  • ChatGPTが2022年に公開された時は、コンピュータでここまでできるのか?と大きな衝撃を受けました。しばらくすると仕事にも使い始め、文書の校正や翻訳、色々な調べものなど、今では、なくてはならないツールになっています。
  • Arduinoに接続できる部品をつないで、動きを考え、思惑通りに動くようにスケッチを書きますが、関数を調べたり、ケアレスミスや思い込みのバグの修正でかなりの時間を使ってしまうことがあります。
  • AIにArduinoを操作する仕様を与えたら、それを実現するスケッチを書いてくれるはずです。またAIはコンピュータを用いて知能を模しているのだから、コーディングとの相性はかなり良いはずです。 [Arduino用のUNO R3 最終版スタータキット]で購入したArduinoキットから部品を選んで動作仕様を作ってAIに指示してスケッチを作る練習をしました。

RGB LEDを違う周期で光らせるスケッチ

  •  [Arduino用のUNO R3 最終版スタータキット]にRGB LEDが含まれています。RGB LEDは一つのパッケージにRGBのLEDが内蔵されています。RGBのそれぞれのLEDを周期を変えて点灯させると合成された色でチカチカと光るはずです。LEDの接続仕様と光らせる周期の仕様を書いて、それをAIで判読してスケッチを生成します。
  •  ArduinoとRGB LEDの接続は下記のようにします。
  •  RGB LEDは一つのパッケージにRGBの3色のLEDが含まれています。RGBを下図のように違った周期で点灯します。下図のHiでLEDが点灯し、Loでは消灯します。どのLEDが点灯するかで目で見える色が変わります。例えば、青と赤のLEDが同時に点灯すればMagenta(赤紫)になります。

AIに指示する点灯させる仕様の作成

  •  AIにスケッチを生成する仕様を指示をしました
以下の仕様で、Arduino UNOのスケッチを作って
---

Dgital 5ピンに青 LEDを接続
Dgital 6ピンに緑 LEDを接続
Dgital 7ピンに赤 LEDを接続

初期は、Pin 5,6,7はLoとする

以下の周期で各PinをHi、Loに切り替える
5ピン 1秒 Hi 1秒 Lo
6ピン 2秒 Hi 2秒 Lo
7ピン 4秒 Hi 4秒 Lo
// ピン番号の定義
const int blueLED = 5;   // 青LED
const int greenLED = 6;  // 緑LED
const int redLED = 7;    // 赤LED

void setup() {
  // 各ピンを出力モードに設定
  pinMode(blueLED, OUTPUT);
  pinMode(greenLED, OUTPUT);
  pinMode(redLED, OUTPUT);

  // 初期状態はすべてLOW
  digitalWrite(blueLED, LOW);
  digitalWrite(greenLED, LOW);
  digitalWrite(redLED, LOW);
}

void loop() {
  // 青LED: 1秒ON、1秒OFF
  digitalWrite(blueLED, HIGH);
  delay(1000);
  digitalWrite(blueLED, LOW);
  delay(1000);

  // 緑LED: 2秒ON、2秒OFF
  digitalWrite(greenLED, HIGH);
  delay(2000);
  digitalWrite(greenLED, LOW);
  delay(2000);

  // 赤LED: 4秒ON、4秒OFF
  digitalWrite(redLED, HIGH);
  delay(4000);
  digitalWrite(redLED, LOW);
  delay(4000);
}
  •  スケッチをArduinoに書き込み動作させると、青を点灯し、次に緑、次に赤と順次点灯するスケッチになっていました。スケッチはdelay()関数を使って青、緑、赤のLEDが指示した時間で点灯しています。
  • AIにRGB LEDを点灯させる周期の記述が不明瞭だったようです。スケッチの開始から、青LED、緑LED、赤LEDを独立した周期で点灯するように、AIへの指示を明確にします。 以下の仕様でAIにスケッチを生成する指示をしました
以下の仕様で、Arduino UNOのスケッチを作って
---

Dgital 5ピンに赤 LEDを接続
Dgital 6ピンに緑 LEDを接続
Dgital 7ピンに青 LEDを接続

初期は、Pin 5,6,7はLoとする

プログラムを開始すると、それぞれのpinを独立して以下の周期でHi、Loに切り替える
5ピン 1秒 Hi 1秒 Lo
6ピン 2秒 Hi 2秒 Lo
7ピン 4秒 Hi 4秒 Lo
// ピン番号の定義
const int RED_PIN = 5;
const int GREEN_PIN = 6;
const int BLUE_PIN = 7;

// LED状態管理
bool redState = LOW;
bool greenState = LOW;
bool blueState = LOW;

// タイマー管理
unsigned long prevRedMillis = 0;
unsigned long prevGreenMillis = 0;
unsigned long prevBlueMillis = 0;

// 各LEDのON/OFF時間
const unsigned long RED_ON = 1000, RED_OFF = 1000;     // 赤: 1秒ON、1秒OFF
const unsigned long GREEN_ON = 2000, GREEN_OFF = 2000; // 緑: 2秒ON、2秒OFF
const unsigned long BLUE_ON = 4000, BLUE_OFF = 4000;   // 青: 4秒ON、4秒OFF

// 現在のインターバル管理
unsigned long redInterval = RED_OFF;
unsigned long greenInterval = GREEN_OFF;
unsigned long blueInterval = BLUE_OFF;

void setup() {
  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);

  // 初期状態をLOWに設定
  digitalWrite(RED_PIN, LOW);
  digitalWrite(GREEN_PIN, LOW);
  digitalWrite(BLUE_PIN, LOW);

  // タイマーを現在時刻で初期化
  unsigned long currentMillis = millis();
  prevRedMillis = currentMillis;
  prevGreenMillis = currentMillis;
  prevBlueMillis = currentMillis;
}

void loop() {
  unsigned long currentMillis = millis();

  // 赤LED制御
  if (currentMillis - prevRedMillis >= redInterval) {
    prevRedMillis = currentMillis;
    redState = !redState;
    digitalWrite(RED_PIN, redState);
    redInterval = redState ? RED_ON : RED_OFF;
  }

  // 緑LED制御
  if (currentMillis - prevGreenMillis >= greenInterval) {
    prevGreenMillis = currentMillis;
    greenState = !greenState;
    digitalWrite(GREEN_PIN, greenState);
    greenInterval = greenState ? GREEN_ON : GREEN_OFF;
  }

  // 青LED制御
  if (currentMillis - prevBlueMillis >= blueInterval) {
    prevBlueMillis = currentMillis;
    blueState = !blueState;
    digitalWrite(BLUE_PIN, blueState);
    blueInterval = blueState ? BLUE_ON : BLUE_OFF;
  }
}
  • スケッチは全く変わりました。 millis()関数を使って経過時間を確認しながら、青LED、緑LED、赤LEDを独立した周期でて点灯しており、意図した動作になっています。
  • LEDの色を目視のみで確認するのは動作の確認としては甘いのでシリアルポートから1秒毎にPin 5,6,7の設定状況と表示される色の目安を表示させるように、AIへの指示を増やしました。
以下の仕様で、Arduino UNOのスケッチを作って
---
Serialモニタは9600 bpsに設定する

Dgital 5ピンに青 LEDを接続
Dgital 6ピンに緑 LEDを接続
Dgital 7ピンに赤 LEDを接続

初期は、Pin 5,6,7はLoとする。HiでLEDが点灯する。

プログラムを開始すると、それぞれのpinを独立して以下の周期でHi、Loに切り替える。

5ピン 1秒 Hi 1秒 Lo
6ピン 2秒 Hi 2秒 Lo
7ピン 4秒 Hi 4秒 Lo

Serialモニタに、1秒ごとに、5pin、6pin、7PinのHi、Loの状態およびLEDの合成色の目安を表示する。
// ピン番号の定義
const int BLUE_PIN = 5;
const int GREEN_PIN = 6;
const int RED_PIN = 7;

// LED状態管理
bool blueState = LOW;
bool greenState = LOW;
bool redState = LOW;

// タイマー管理
unsigned long prevBlueMillis = 0;
unsigned long prevGreenMillis = 0;
unsigned long prevRedMillis = 0;
unsigned long prevPrintMillis = 0;

// 各LEDのON/OFF周期
const unsigned long BLUE_ON = 1000, BLUE_OFF = 1000;   // 1秒ON、1秒OFF
const unsigned long GREEN_ON = 2000, GREEN_OFF = 2000; // 2秒ON、2秒OFF
const unsigned long RED_ON = 4000, RED_OFF = 4000;     // 4秒ON、4秒OFF

// 現在のON/OFF時間管理
unsigned long blueInterval = BLUE_OFF;
unsigned long greenInterval = GREEN_OFF;
unsigned long redInterval = RED_OFF;

void setup() {
  Serial.begin(9600);
  pinMode(BLUE_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(RED_PIN, OUTPUT);

  // 初期状態をLOW
  digitalWrite(BLUE_PIN, LOW);
  digitalWrite(GREEN_PIN, LOW);
  digitalWrite(RED_PIN, LOW);
}

void loop() {
  unsigned long currentMillis = millis();

  // 青LED制御
  if (currentMillis - prevBlueMillis >= blueInterval) {
    prevBlueMillis = currentMillis;
    blueState = !blueState;
    digitalWrite(BLUE_PIN, blueState);
    blueInterval = blueState ? BLUE_ON : BLUE_OFF;
  }

  // 緑LED制御
  if (currentMillis - prevGreenMillis >= greenInterval) {
    prevGreenMillis = currentMillis;
    greenState = !greenState;
    digitalWrite(GREEN_PIN, greenState);
    greenInterval = greenState ? GREEN_ON : GREEN_OFF;
  }

  // 赤LED制御
  if (currentMillis - prevRedMillis >= redInterval) {
    prevRedMillis = currentMillis;
    redState = !redState;
    digitalWrite(RED_PIN, redState);
    redInterval = redState ? RED_ON : RED_OFF;
  }

  // 1秒ごとに状態を表示
  if (currentMillis - prevPrintMillis >= 1000) {
    prevPrintMillis = currentMillis;

    Serial.print("Pin5(BLUE): ");
    Serial.print(blueState ? "Hi" : "Lo");
    Serial.print(" | Pin6(GREEN): ");
    Serial.print(greenState ? "Hi" : "Lo");
    Serial.print(" | Pin7(RED): ");
    Serial.print(redState ? "Hi" : "Lo");

    // 合成色の目安
    Serial.print(" | Color: ");
    if (blueState || greenState || redState) {
      if (blueState && greenState && redState) Serial.print("White");
      else if (blueState && greenState) Serial.print("Cyan");
      else if (blueState && redState) Serial.print("Magenta");
      else if (greenState && redState) Serial.print("Yellow");
      else if (blueState) Serial.print("Blue");
      else if (greenState) Serial.print("Green");
      else if (redState) Serial.print("Red");
    } else {
      Serial.print("Off");
    }
    Serial.println();
  }
}
  • シリアルモニタを9600 bpsで表示させます。青LED、緑LED、赤LEDへのポート出力のHi、Loの状態、また期待されるLEDの色の表示がされています。表示の細かな書式はAIに指示をしていませんが解り易く表示されています。

AIを使ったスケッチの作成の感想は?

  • こんなに簡単にスケッチが作れるのか! という感じです。仕様を変えたり、表示を追加したりするのに、たぶん10分程度しかかかっていません。AIが生成したコードを自分が作っていれば、何倍かの時間がかかっていたと思います。当然、個人の力量差によって変わると思いますが、私が作るよりは、作る速度は速いし、コメントは丁寧です。 自分で作ると、特に趣味のプログラムはコメントはいいかげんですが、AIが作ると綺麗ですね。AIが作成したスケッチを読むと何をしているか解り易いです。

御質問、誤植の指摘、記事の改善点の気づきなどありましたら「問い合わせ 」のページからお願いします。