アフィリエイト広告
アフィリエイト広告

Arduino Nano Every を使ってみる – ホタルライト

前回まで、デジタル出力を使って LED を点滅させるサンプルを試してみました。

Arduino Nano Every を使ってみる - L チカ (2)
前回は、Arduino Nano Every の内蔵 LED を点滅させてみました。 今回は、Arduino Nano Every 自身の動作ではないのですが、ちょっと初心に返って、外につけた LED を点滅させるみることにします。 LED...

今回は、スケッチ例の「Fading」、アナログ出力 (PWM) を使って LED を明滅させるサンプルを試してみます。

Fading

Arduino Nano Every のアナログ出力できる入出力ピンは、3 、5 、6 、9 、10 番ピンです。
UNO や Nano など ATmega328P を使った Arduino ボードでは 11 番ピンでもこの機能が使えましたが、Arduino Nano Every では 11 番ピンは利用できません。注意が必要です。
また、PWM の周波数は、全てのピンで 976Hz です。

サンプル例 Fading では 9 番ピンを使っていますので、それにならいます。
Blink のときは 13 番ピンにつなぎましたが、同じ回路を、今回はアナログ出力の使える 9 番ピンに変更です。これで Blink のスケッチを 9番ピンに変更すれば、L チカできますね。

スケッチ例から Fading を選択します。が、このスケッチ例も delay() を使っていますので、Ditch the delay() してしまいましょう。

  1. // Fading
  2. int ledPin = 9;
  3. void setup() {
  4. }
  5. void loop() {
  6.   static int fadeValue = 0;
  7.   static int increment = 5;
  8.   static unsigned long previousMillis = 0;
  9.   static const unsigned long interval = 30;
  10.   if(interval < millis() - previousMillis) {
  11.     fadeValue += increment;
  12.     if(255 < fadeValue) {
  13.       fadeValue = 255;
  14.       increment *= -1;
  15.     }
  16.     if(0 > fadeValue) {
  17.       fadeValue = 0;
  18.       increment *= -1;
  19.     }
  20.     analogWrite(ledPin, fadeValue);
  21.     previousMillis = millis();
  22.   }
  23. }

setup() は何もすることがありません。
analogWrite() では、pinMode() で OUTPUT に設定しておく必要はありません。

LED の明るさ fadeValue を漸増させ、255 を超えたら増分をマイナスにします。増分がマイナスになることで fadeValue は漸減し、0 を下回ったら再び増分をプラスに戻します。

ホタルライト

Fading で明滅する LED を眺めていたら、ホタルの光るようすを思い浮かべました。ホタルライトを作ってみましょう。

ところで、ホタルってどんなふうに発光するんですか?

参考にさせていただいたのは「コンピュータ解析法による日本産ホタルの発光パターン」という、横須賀市自然・人文博物館のレポートです。
このレポートにあった、西日本型と東日本型のゲンジボタルの発光パターンのグラフから、Google スプレッドシートで近似式を導き出して、Arduino Nano Every で計算、出力させました。なので、厳密に再現できているわけではありません m(_ _;)m

回路図

Hotaru-light 回路図

LED の数と、それをどこにつなぐか、が異なるだけで、入出力ピンに抵抗と LED をつなぐことに変わりはありません。

Arduino Nano Every では LED は 5 回路ですが、Arduino UNO や Nano ならばもう一つ、11 番ピンも利用可能です。

LED 1個あたりの電流は 3mA 、全体で 15mA です。

スケッチ

3 日もすると、どんなスケッチやったっけ?になるので、俺自身のための、備忘録的解説です。

  1. // hotaru 2022.06.25 meyon
  2. // luminesence_1 : Western-Japan type Genji-Botaru
  3. // luminesence_2 : Eastern-Japan type Genji-Botaru
  4. void setup() {
  5. }

setup() ですることはありません。デジタル出力は使いませんので、pinMode() を指定する必要はありません。

  1. void luminesence_1(byte ledPin) {
  2.   static int increased = 0;
  3.   static int decreased = 0;
  4.   static int t = 0;
  5.   static int power = 0;
  6.   static unsigned long previousMillis = 0;
  7.   unsigned long lapse = millis() - previousMillis;
  8.   if(350 > lapse) {
  9.     increased = 0.409-0.0592*lapse+1.792E-3*pow(lapse,2)-2.343E-6*pow(lapse,3);
  10.     power = map(increased, 5, 100, 0, 255);
  11.     power = constrain(power, 0, 255);
  12.     analogWrite(ledPin, power);
  13.   }
  14.   else if(1700 > lapse) {
  15.     decreased = 358-1.070*lapse+1.193E-3*pow(lapse,2)-0.581E-6*pow(lapse,3)+0.104E-9*pow(lapse,4);
  16.     power = map(decreased, 5, 100, 0, 255);
  17.     power = constrain(power, 0, 255);
  18.     analogWrite(ledPin, power);
  19.   }
  20.   else {
  21.     previousMillis = millis();
  22.   }
  23. }

関数 luminesence_1() は、西日本型ゲンジボタルの発光パターンの出力です。

発光から 0.35 秒までは、増加の近似式で LED を制御します。その後 1.7 秒まで減少の近似式で制御し、消光します。近似式の値は 0〜100 なので、アナログ出力の 0〜255 に map() で範囲を変換し、constrain() でその範囲に制限しています。

Arduino Nano Every では constrain() はなくても問題ありませんでした。が、Nano では範囲を制限しないと動作がおかしくなります。 Nano Every と Nano では、近似式の答えが異なっているようです。
map() は返り値の範囲を制限しませんので、constrain() は入れておくべきでしょう。

  1. void luminesence_2(byte ledPin) {
  2.   static int increased = 0;
  3.   static int decreased = 0;
  4.   static int t = 0;
  5.   static int power = 0;
  6.   static unsigned long previousMillis = 0;
  7.   unsigned long lapse = millis() - previousMillis;
  8.   if(1200 > lapse) {
  9.     increased = 0.387-0.0121*lapse+0.18E-3*pow(lapse,2)-0.0848E-6*pow(lapse,3);
  10.     power = map(increased, 5, 100, 0, 255);
  11.     power = constrain(power, 0, 255);
  12.     analogWrite(ledPin, power);
  13.   }
  14.   else if(4000 > lapse) {
  15.     decreased = 348-0.269*lapse+0.0535E-3*pow(lapse,2)+3.51E-9*pow(lapse,3)-1.37E-12*pow(lapse,4);
  16.     power = map(decreased, 5, 100, 0, 255);
  17.     power = constrain(power, 0, 255);
  18.     analogWrite(ledPin, power);
  19.   }
  20.   else {
  21.     previousMillis = millis();
  22.   }
  23. }

関数 luminesence_2() は、東日本型ゲンジボタルの発光パターンの出力です。

こちらは、発光から 1.2 秒まで増加し、その後 4 秒まで減少して、消光します。周期と近似式が異なるだけで、スケッチ自体は同じものです。

  1. void loop() {
  2.   luminesence_1(5);
  3.   luminesence_1(9);
  4.   luminesence_2(3);
  5.   luminesence_2(6);
  6.   luminesence_2(10);
  7. }

それぞれの関数には、出力ピン番号を引数として渡します。ここでは、5 、9 番ピンへ西日本型、3 、6 、10 番ピンへ東日本型発光パターンを出力していますが、お好みで。

ヒメボタルの発光パターンを追加する、とか、発光パターンをもっと複雑にする、とか、いろいろできるかとは思いますけど、まぁそこらへんもお好みで。

ホタルライト試作

ホタルライト試作

ブレッドボード上のホタルライトです。

特に説明することもありません。
短い周期で明滅している方が西日本型ゲンジボタル、長い周期が東日本型ゲンジボタルの発光です。ステートマシンにより、それぞれが独立して明滅しています。

観葉植物にホタル

ホタルライトがなんだかいい感じにできたので、観葉植物にのっけてみました。

ジャンク箱にチップ LED があったので、これにリード線としてポリウレタン銅線をはんだ付けしています。ポリウレタン銅線は高いので、目立たないところは安い電線につなぎ替えています。 (^_^;)

葉にのせたチップ LED

ポリウレタン線は写真のように撚ることができて便利。もっと細い線を使うと目立ちにくくなりますね。

チップ LED は、赤と緑の 2 連ですが、赤だけ使っています。

タイトルとURLをコピーしました