「Done Compiling」が「Damn Complaining」に見えてきた

それはともかく、とりあえず LED をチカチカさせるところまではできるようになったよ。

紫色(near-UV)LED なんてものを使っているので写真も大変なことになっている。(そういうものが当たり前のように手許にある理由についても依然謎のままである。本人もわかっていない。)ものすごく目に悪そう。(実際よくない ← ならやめなよ)
…ていうか、LED をチカチカとかそのぐらいならポケコンで既にやってた気もするのだが、そういうことは言わない約束で。まごころとおもいやり。それと、えさをほしがってもあげないでください。


実際やってみて、かなり予想外だった気もするので、メモ程度に書いておく試み。
私にとって最大の障壁は、記述言語が C言語的な何かというところだと思っていたのだが、そこはなんというか、とりあえずちょっと試す程度の場合はキーボードすらいらないというか、IDE(統合環境)にサンプルプログラム(あちらの世界では「スケッチブック」と称するらしい)が仕込んであるので、そこかしこで紹介されている はじめのほんとの最初の一歩である「13番ピンに LED を差して点滅させてみましょう」という

void setup () {
    pinMode (LED_PIN, OUTPUT);
}
void loop () {
    digitalWrite (LED_PIN, HIGH);
    delay (1000);
    digitalWrite (LED_PIN, LOW);
    delay (1000);
}

ですら、コピペの必要さえ無い。
逆に、ここまで用意されてしまうと、ぬるま湯すぎて言語を覚えられない。これは困ったことである。

これは予想外に「ラク」だった点。「敷居が低い」「低い」と彼方此方で言われているのは、普通は導入やら初期設定やらが面倒なこのへんで苦労せずに済む、というところのことを言っているのだろう。難しいことは一切考えずに、ユーザはやりたいことをざっくり翻訳して書けばそれでだけでいい。最初は書く必要もない。慣れてからだって、恐らくはいろんなところからのコピペやら拝借やらでかなり事足りてしまうあろう。


反面、予想外に苦労した点。というより、「え、そこでつまずかされますか」みたいな。
例えば、なんだか巷では あるじゃーのん ? 見たいな名前の何かが流行っているらしい。それを使うと決まった時間にネコに餌をやる装置とか、結構簡単に作れてしまうらしい。そういうことならやってみましょうか、って Amazon でも売ってるのね。¥3,000.- ちょいならいいか、と、ポチる。で、届く。届いたものを見てまあまず驚くのが、なんだ、予想外に小さいな、ということ、でもそんなことはさしたる問題ではない、それよりも、「何もついてこない」。説明書、保証書、電源ケーブル、ACアダプタ、接続ケーブル、電池*1…なんか最近ではごちゃごちゃ付いていて当然、と思っていた諸々が一切無い。本当に、紙切れ 1枚、ついてこないのである。
実際やってみるとわかるのだが、そういうものはほとんど要らない、というより、付いてくる必要が無いから付いてないのであって、そもそも Arduino に手を出そうという人間の家(あるいはオフィス)には 10kΩの抵抗ぐらい探せばあるし、余っている USB ケーブルぐらい 2, 3本無造作に転がっているわけだ。ACアダプタのジャックが付いているからといって、これが即必要になるかというと、当座は USB 給電で事足りるのでそんなことも無い。これだって、Arduino に興味を持つぐらいの人間なら出力 7 〜 12V *2でセンタープラス(2.1mmφ)の ACアダプタあるいは USB 電源アダプタぐらいとっくに持っているし、よしんば無くてもありかは熟知している。
でも、それにしても、不親切であるとは思わないが拍子抜けはする。
また、手軽すぎる、ということは、反面なにかトラブルがあったときには解決の方法を見出すのに大変手間取るということでもある。最新機種ではもう本当に至れり尽くせりで、英文さえなんとなく読めればウェブ上のチュートリアルを見ながらポチポチやるだけで全部自動でやってくれちゃうのだが、中には「スケッチ」のロードの際に手動でリセットをかけてやらなくてはいけないもの(機種)もある。注意して読解しないと、その「リセット」ボタンさえ付いていない機種のリセットはどうすればいいのかわからず、いつまで経っても起動失敗の憂き目に遭う。リセット動作は、リセット端子をプルアップするのではない。普段はプルアップしておかないとだめなのである。では、リセットの際にそのプルアップしているリセット端子をリリースすればいいのか、というと、それでは不充分。グラウンドに落としてやらなくてはいけない。つまり、ブレッドボード上でジャンパピンを使ってこの動作を実現するには、予め接続してある RESET と VCC のあいだのジャンパを引っこ抜き、これを使って RESET と GND を繋ぎ、すぐに外して元通り VCC に繋ぎなおす、という操作が必要になる。…大して面倒臭くないだろ、って? この作業後、すばやくスケッチを UP しなくてはいけない(少なくとも数秒以上 間を置くと失敗する)としても?
よく読めばちゃんとどこかに書いてあるのだろうけど、どちらかというとそこは注意深く読まなくても大丈夫なように声高に注意喚起すべきところでないのかと。


そう、良くも悪くも、イタリア的なのである。流石はイタリア生まれなのである。


このままでは何も覚えられずに「飽き」の方が先に来てしまう、と危惧した私は、サンプルを用いての実験が手軽にできるのをいいことに、ちょっとした改造をしてみることにした。ここでもまた適当にやってみると実は……みたいな話が発掘されたりして、えーってなったりするのだが、それはたぶん碌に読まないでとにかく実験してみようとする私がいけないのだろうと考える。


で、いくつかできた(自分では何もしてないですけどね)うちのひとつ。

/*
  Button2LED
 
 Turns on and off a light emitting diode(LED) connected to digital  
 pin 13, when pressing a pushbutton attached to pin 2. 
 And turns 2 LEDs when trigged a pushbutton (as binary status).
 
 
 The circuit:
 * LED attached from pin 9 to ground 
 * LED attached from pin 10 to ground 
 * LED attached from pin 13 to ground (for monitoring pushbutton)
  
 * pushbutton attached to pin 2 from +5V
 * 10K resistor attached to pin 2 from ground
 
 
 
 
 created 2005
 by DojoDave <http://www.0j0.org>
 modified 17 Jun 2009
 by Tom Igoe
 
 modified 2009/11/15
 by 熾火研究所(Okibi Labo.)
 
 
  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 ledPin00 =  9;     // the number of the LED pin
const int ledPin01 =  10;    // the number of the LED pin
const int ledPinIdc = 13;    // the number of the LED pin
// set voltage value for LED as
//         赤橙黄緑 => 1.8V / 5.0V * 255 = ca.90
//         青紫白UV => 3.2V / 5.0V * 255 = ca.160
const int analogV =  160;      // 
// set interval time for delay (msec) to
const int basedelay0 = 700;
const int basedelay1 = 50;


// variables will change:
int buttonState0 = 0;     // variable for reading the pushbutton status
int buttonState1 = 0;     // variable for pushbutton status of 1-loop before
int LedState = 0;         // variable for keeping the LED status
long timeCount = 0;            // variable for keeping base timer
long btnRepeatCount0 = 0;      // variable for keeping timer
long btnRepeatCount1 = 0;      // variable for keeping timer


void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin00, OUTPUT);      
  pinMode(ledPin01, OUTPUT);      
  pinMode(ledPinIdc, OUTPUT);      
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);  
  // initialize the time counter:
  timeCount = millis();      // variable for keeping base timer
  btnRepeatCount0 = millis();      // variable for keeping timer
  btnRepeatCount1 = millis();      // variable for keeping timer

  // open the Serial Port for debug output
  Serial.begin(9600); 
}

void LedDrive() {
      // increment LED status:    
      LedState += 1;
      LedState = LedState & 3;   // This statemant (line) isn't needed :-P
      // drive LEDs:
        if ((LedState & 1) == 1) {
          // turn on LED00:
          analogWrite(ledPin00, analogV);
        } else {
          // turn off LED00:
          analogWrite(ledPin00, 0);
        }
        if ((LedState & 2) == 2) {
          // turn on LED01:
          analogWrite(ledPin01, analogV);
        } else {
          // turn off LED01:
          analogWrite(ledPin01, 0);
        }
      // Clear the button counter 1:
      btnRepeatCount1 = millis();
}

void loop(){
  // get timer:
  timeCount = millis();
  // read the state of the pushbutton value:
  buttonState0 = digitalRead(buttonPin);

  // check if the pushbutton is not pressed:
  if (buttonState0 == LOW) {
    // Clear the button counter:
    btnRepeatCount0 = millis();
    btnRepeatCount1 = millis();
    // turn off Indicator LED:
    digitalWrite(ledPinIdc, LOW);
      // if the button JUST RELEASED:
      if (buttonState1 == HIGH) {
        // call LED Rrive Routine:
        LedDrive();
      }
  // if the pushbutton pressed:
  } else {   
    // turn on Indicator LED:
    digitalWrite(ledPinIdc, HIGH);
      if ((timeCount - btnRepeatCount0  >= basedelay0) && 
          (timeCount - btnRepeatCount1  >= basedelay1)) {
        LedDrive();
      }
  } 
  
  // stock pushbutton status:
  buttonState1 = buttonState0; 
  
  
  
/* for debug --- value check ( to SerialPort ) 
  Serial.print("LedState:"); 
  Serial.print(LedState);
  Serial.print("  timer:");
  Serial.print(timeCount);
  Serial.print("  btnRep0:");
  Serial.print(btnRepeatCount0);
  Serial.print("  btnRep1:");
  Serial.println(btnRepeatCount1);
*/
}

長くてすみません。(ってよくよく見れば半分はコメントじゃないか。)
ボタンを押すたびに 2個の LED の点灯状態が変わってゆく、というものだが、折角なんで、ボタン長押しで「キーリピート」的なものが効くようにしてみた。(結構苦労した。→ 文字列操作関数とか、演算子のルールとか、そういう処理系ごとの細かい細かい違いで非常に苦労する。あと、条件分岐とかも頭で考えてるとどっちがどっちだか分からなくなったり(大丈夫でしょうか)、そもそも基本的に、引き算が苦手*3です*4←ぉぃ)


まあ、非常におもしろい。


とりあえずの「目標」的なものはというと、これを使用して充電池の放電器を作りたいな、というあたり。たぶん、そんなに難しくはない。でも、ちょっと凝ったことをやろうと思えば、それはたぶん何でもできて、ただしそのぶんだけ、それこそ天井知らずでそれに見合うだけの高いハードルが用意されるであろう。
実用性と利便の「落としどころ」は? みたいな話は、ともすれば私のもっとも苦手とする分野だ。どのくらい苦手かというと、苦手すぎて今まで生きてきた中ではそういうことを一度もやったことがない。
あとは、あわよくば C言語なんかマスターできちゃったりなんかしちゃったりしないかなぁなんていう虫のいいことも妄想していたりもするのだが、流石にそれはちょっとばかり虫がよすぎにも程がある。

*1:そもそも電池は使用しません

*2:カタログスペックではそういう Voltage でってことになっているらしいが 5V でもこれといって問題なく動作したりするし。

*3:小学校 5〜6年のときの計算ドリルの後遺症。

*4:なんか if() 文の中に入っていかないなーと思っていたら、減数と被減数を逆にしていた。そりゃ、いつまで経っても真にならんよなぁ。←ぉぃぉぃ