ブレボー亀の子

投稿日:

 ブレッドボードに小さいプロトタイプを作るとき、この「プロトタイピングシールド」も捨てがたい。だが、しばらく使ってみての感想なのだが、小さくて不便だ。また、電源ラインもどうも使いづらい。シールド上の赤ソケットには実は5Vは到達していないので、自分で配線しなければならないのだ。

便利だが、小さいところが難
IMG_3031

 と言って、大きい方だと、Arduinoに重ねるわけにもいかず、昨日のようになってしまう。

たかが7セグLED2個のためにゴチャつくブレッドボード(笑)
IMG_3240

 何かいいことないかな、と思ってネットを漁っていたら、ある方がブレッドボードの脇に直接Arduino用のピンヘッダを接着剤で取り付けて、目的を達成しておられるのを見つけた。ほほー、なるほどなるほど……。

 つまり、大抵のブレッドボードは、同じメーカーの物なら、こういうふうに脇を取り外したり組み合わせたりできるのだが、電源ラインを一つ外すと、Arduinoの上下のピン幅とピッタリなのである。

IMG_3252
IMG_3253

 チナミに、このようにバラしたり組み合わせたりするには、ブレッドボード裏の両面テープの、つけ外しする部分をカッターナイフでスーッと切ると良い。

 しかし、接着剤でピンソケットを付けてしまう、てのも、なあ……。他のことにブレッドボードが使えなくなってしまうし……。

 で、考えてみたら、私は次の写真のようなArduino用のプラスチックケースを使っているが……

IMG_3254

……この上に電源ラインを一本外したブレッドボードを亀の子にし、輪ゴムか何かで縛っておけば、目的は達成できるではないか。

IMG_3255

 どうして今までこうしなかったかと言うと、そのままだとプラスチックケースの上下に細く開けてあるピンソケットにアクセスするためのスリットがふさがり、Arduinoから信号線が出せないからである。しかし、電源ラインを外すと、上下ともちょうどピッタリ、スリットが隠れずにすむのだ。

 ほうほう、なるほど、というわけで、この前作ったビーズのLEDなど植えてみる。Arduinoの「Arduino AT HEART♥」みたいな感じで、ハートですな、男のくせにw。

IMG_3256

 動かすとこんな感じ。

 このLチカはシンプルで、スケッチはこう。

//
//  differSin.ino
//    サインカーブをちょっとづつずらしてLチカ
//    佐藤俊夫
//    27.08.11(火) 1100~
//    
void setup() {
  pinMode( 9, OUTPUT);
  pinMode(10, OUTPUT);
}

void loop() {
  static float x1 = 0.0, x2 = 0.0;
  x1 = x1 > (2.0 * PI) ? 0.0 : x1 + (2.0 * PI / 1000.0);
  x2 = x2 > (2.0 * PI) ? 0.0 : x2 + (2.0 * PI / 1100.0);
  analogWrite( 9, (int)((sin(x1) + 1) * 128));
  analogWrite(10, (int)((sin(x2) + 1) * 128));
  delay(2);
}

 そう言えば、以前、「なんとっ!Arduinoって3項演算子ないのかッ!?」「ううっ、あったらなあ」などと書いたことがあったが、これは早とちりで、私の間違い。ちゃんとありました。上記スケッチでご覧のとおり(苦笑)

2桁順番

投稿日:

 次に、TLC5940NTを使って、数字をちゃんと表示させる。

 前と同じ回路で、スケッチは次のようにする。

//
//  tlc594027segmentLED.ino
//    7セグメントLEDをTLC5940NTで制御
//    27.08.10(月)1800~
//    佐藤俊夫
//
#include "Tlc5940.h"
//
void setup()
{
  Tlc.init();
}

void loop()
{
  Tlc.clear();
  static int n = 0;
  disp7LED(n++);
  if(n >= 100) n = 0;
  delay(1000);
}
//
void disp7LED(int n){
  const int on = 4095, off = 0;
  const int pat[10][8] = {
    // 0    1    2    3    4    5    6    7pin   num
    { on,  on,  on, off,  on,  on,  on, off},  //  0
    {off, off,  on, off,  on, off, off, off},  //  1
    { on,  on, off, off,  on,  on, off,  on},  //  2
    {off,  on,  on, off,  on,  on, off,  on},  //  3
    {off, off,  on, off,  on, off,  on,  on},  //  4
    {off,  on,  on, off, off,  on,  on,  on},  //  5
    { on,  on,  on, off, off,  on,  on,  on},  //  6
    {off, off,  on, off,  on,  on,  on, off},  //  7
    { on,  on,  on, off,  on,  on,  on,  on},  //  8
    {off,  on,  on, off,  on,  on,  on,  on}   //  9
  };
  //  一旦消す
  Tlc.clear();
  //  10の位
  int n10 = n / 10, i = 0;
  for(i = 0; i <= 7; i++){
    Tlc.set(i, pat[n10][i]);
  }
  // 1の位
  int n1 = n % 10;
  for(i = 0; i <= 7; i++){
    Tlc.set(i + 8, pat[n1][i]);
  }
  Tlc.update();    
}

 次のようにカウントアップしていく。

 そういえば昔の刑事ドラマなんかで、時限爆弾のカウントって、こんな感じで、電線がゴチャゴチャしてたっけなあ。ふふっ、爆発しそうだな、これじゃ(笑)。

次に2桁を

投稿日:

 7セグメントLEDの1桁の制御の基礎がわかったので、今度は2桁だ。

 当然、ArduinoのI/Oはこれでは足りない。

 したがって、ドライバICを使う。この前買ったテキサス・インスツルメントの定番IC、「TLC5940NT」を使うのである。秋葉原千石電商で390円だ。

IMG_3240

 16本のカソードを全部ICに入れてあるので、配線はだいぶゴチャつく。ブレッドボードも2連結だ。

 この配線は、ArduinoのTLC5940用ライブラリをインストールすると使えるようになるサンプルスケッチ「BasicUse」のコメントの冒頭にアスキーアートで詳しく図示されている。

 とりあえず、この「BasicUse.ino」を動かしてみた。次のようになって面白い。

 

お稽古

投稿日:

 7セグメントLEDのお稽古をする。意味のあるなしはどうだってよろしい。レッツゴー。

 私は古株ぶっているが、実は若い頃に7セグLEDを扱ったことがない。子供の頃の電子工作はもっぱらラジオなどのトランジスタ回路、長じてからは仕事関係で5極真空管やマイクロ波の発振管などを扱っていた。

 数値表示のためには、その頃の仕事関係では「ニキシー管」という数値表示のための真空管を扱っていた。これは放電管で、数字の形をした陰極が赤く光るものだ。

 そういうわけで、7セグLEDを知らないのである。いや、無論、当時から7セグメントLEDは世の中にあったが、私の職場が特殊だったのである。

 で、これが昨日秋月電子八潮店で買ってきた、1個60円の7セグLEDである。

IMG_3234
IMG_3236
OSL10561-IRA

 さて、まずは点灯からだ。データシートから、抵抗と電流っ。

 各素子I_F = 20mA, V_F = 2.1V……とあるから、V_0 = 5Vとして、

I_R = \frac{V_0 - V_F}{I_F} = \frac{5 - 2.1}{20mA} = 181.25\Omega

……まず、200Ωばかりつけておいてやればよいのだろう。この前買った集合抵抗の手持ち、8素子9ピンで330Ωのがあるから、それを付ければ多少暗いが10mA前後で光るだろう。

 さっそく、全点灯で光らせてみよう。単に電源をくれてやって、抵抗に結線するだけだ。

7セグLED全点灯
回路図

 光らせてみると、計算上の抵抗の倍近い抵抗値なのに、なかなかどうして、結構明るく光る。

IMG_3237
単純全点灯で光らせてみたところ

 次に、Arduinoをつないで、数字を表示させる。全点灯で電流を測ってみると67mAほど流れているので、電源はこのまま別建てのほうがいいだろう。

 アノードコモンのLEDであるから、カソード側で制御しなければならない。集合抵抗では一本づつ制御できないので、330Ωの電流制御抵抗をバラで8本とりつける。それぞれの足をArduinoのデジタル2ピンから9ピンまで取り付ける。

 スケッチをこう書く。点灯のパターンは配列に書くのが手早いだろう。

//
//  7segmentLED_1.ino
//    7セグメントLEDを1個動かす。
//    27.08.10(月) 1300~
//    佐藤俊夫
//
//    LED「OSL10561-IRA」
//    LED 1 -> Digital 2
//    LED 2 -> Digital 3
//    LED 4 -> Digital 4
//    LED 5 -> Digital 5
//    LED 6 -> Digital 9
//    LED 7 -> Digital 8
//    LED 9 -> Digital 7
//    LED10 -> Digital 6
//
void setup() {
  for(int i = 2; i <= 9; i++){
    pinMode(i, OUTPUT);
  }
}

void loop() {
  for(int i = 0; i <= 9; i++){
    lighting(i);
    delay(1000);
  }
}

void lighting(int n){
  const int pat[10][8] = {
    { LOW,  LOW,  LOW, HIGH, HIGH,  LOW,  LOW,  LOW},  //  0
    {HIGH, HIGH,  LOW, HIGH, HIGH, HIGH, HIGH,  LOW},  //  1
    { LOW,  LOW, HIGH, HIGH,  LOW, HIGH,  LOW,  LOW},  //  2
    {HIGH,  LOW,  LOW, HIGH,  LOW, HIGH,  LOW,  LOW},  //  3
    {HIGH, HIGH,  LOW, HIGH,  LOW,  LOW, HIGH,  LOW},  //  4
    {HIGH,  LOW,  LOW, HIGH,  LOW,  LOW,  LOW, HIGH},  //  5
    { LOW,  LOW,  LOW, HIGH,  LOW,  LOW,  LOW, HIGH},  //  6
    {HIGH, HIGH,  LOW, HIGH, HIGH,  LOW,  LOW,  LOW},  //  7
    { LOW,  LOW,  LOW, HIGH,  LOW,  LOW,  LOW,  LOW},  //  8
    {HIGH,  LOW,  LOW, HIGH,  LOW,  LOW,  LOW,  LOW}   //  9
  };
  int i = 0;
  for(i = 0; i <= 7; i++){
    digitalWrite(i + 2, HIGH);
  }
  for(int i = 0; i <= 7; i++){
    digitalWrite(i + 2, pat[n][i]);
  }
}

 アノードコモンなので、論理は負論理だ。

 Arduinoとブレッドボードをこういうふうにする。

IMG_3238

 動かすと、ゆっくりカウントアップする。

ネット便器

投稿日:

 時代はIoTである。モノをネットに接続することは、もはや正義を通り越して神の啓示であるとすら言えるほどだ(笑)。

 やろうやろうと思ってやっていない一事はこのことだ。すなわち、「Arduino」を使用して、直接モノにツイートさせること、これである。モノがツイートするのはきっと面白いに違いない。

 「Twitter Arduino」あたりで検索すると、ライブラリが出てくる。今回はこれ(Tweet Library 1.3)をありがたく使わせていただく。

 さて、そうと決まれば何をネットに接続するか、である。ここはやはり、自宅の便器をネットに接続するという、これを一度やってみるべきであろう。

 やはり、IoT時代であるから、便器もネットにつないでやらなければ面白くないだろう。便器だって平等に扱ってやらねば、他の物品との差別感を覚えてひがむようになり、性格が曲がってしまうかもしれない。このように性格の歪んだ便器は、人間様が用を足すときに局部に噛みついてくるようなことが万に一つはないとも限らない。便器にも時々はインターネットと会話をさせてやるべきだ。

 とりあえず、便所のフタの開閉を検知するため、「チルトスイッチ」を使用する。

チルトスイッチ
IMG_3218

 これは、傾けるとスイッチが入るというもので、Arduinoを買ったときに一緒に買った「Seeedstudio SIDEKICK BASIC KIT」というセットに入っていたものだ。

 回路は簡単である。下図のように、行儀よく10kΩほどプルダウンしておけば誤動作は少ない。

チルトスイッチ回路図

 スケッチのほうは、ライブラリの導入に多少手間取った。使用させていただいた「Tweet Library」は、「ETHERNET SHIELD」のほうに対応しており、私が持っている「ETHERNET SHIELD 2」にはそのままでは対応していない。

 基本的にヘッダファイルのインクルードを「#include <Ethernet.h>」から「#include <Ethernet2.h>」に書き換えるだけでいいのでは、と思ったのだが、どうもうまくいかない。さっぱりお手上げだったのだが、いろいろといじくりまわしているうち、エラーメッセージをよく見てみると、「クラスの2重定義」という意味のエラーが出ていることがわかった。なぜか、「libraries\Ethernet2\srcの下にあるやつと重なっている」みたいなメッセージが出ている。ハテ、とライブラリのあるディレクトリを見てみると、「libraries\Ethernet2\src」の下に、なぜか「Twitter.h」と「Twitter.cpp」がある。

 なんだかわかんないけどいいや、消しちゃえ!と、それをぞんざい適当に消したら、うまくコンパイルできるようになった。しかし、そのことで5~6時間ほどハマッてしまった。

 ETHERNET SHIELD 2とプロトタイプシールドを、先日買った「継ぎ足しピンヘッダ」を介して積み重ね、次のようにしていつもの100円ショップのアクリル枠にねじ止めする。

IMG_3213

 手前に緑色のチルトスイッチが取り付けられていることがわかるだろう。

 Twitterに専用アカウントをとり、Tweet Libraryの説明にしたがってトークンを取得する。専用アカウントは、その名も「佐藤家の物」である(笑)。

 それから、スケッチを次のように書く。

//
//  つぶやき便所 tweetToilet.ino
//    27.08.08(土) 1000~
//    佐藤俊夫
//    チルトスイッチで便所のふたの動きを検出し、呟かせる。
//
#include <SPI.h>
#include <Ethernet2.h>
#include <Twitter.h>
#include <stdio.h>
//
byte MAC[] = { 0x90, 0xA2, 0xDA, 0x0F, 0xF6, 0x74 };
IPAddress IP(192, 168, 1, 129);
Twitter TWITTER("hogehogehoge-hagehagehagehage......");  //  トークン
const int TILTSW = 9;
//
void setup()
{
  pinMode(TILTSW, INPUT);
  delay(1000);
  Ethernet.begin(MAC, IP);
  delay(1000);
}

void loop()
{
  static int tiltSwStatus = LOW, prevStatus = LOW;
  int i = 0;
  tiltSwStatus = tiltSw();
  if(tiltSwStatus != prevStatus){
    prevStatus = tiltSwStatus;
    tweetMsg(tiltSwStatus);
    delay(1000);
  }else{
    ;
  }
}
//
int tiltSw(){
  //  チルトスイッチの読み取りを安定させるため、100回連続して同じ値が返るまで読む。
  int i = 0, prevStatus = LOW, nowStatus = LOW;
  prevStatus = digitalRead(TILTSW);
  do{
    nowStatus = digitalRead(TILTSW);
    if(nowStatus == prevStatus){
      i ++;
    }else{
      i = 0;
    }
    prevStatus = nowStatus;
  }while(i < 100);
  return(nowStatus);
}
//
void tweetMsg(int tiltStatus){
  const char
    openMsg[] = "%e3%82%84%e3%81%82%e3%80%82%e4%bf%ba%e3%81%af%e4%bd%90%e8%97%a4%e5%ae%85%e3%81%ae%e4%be%bf%e5%99%a8%e3%81%a0%e3%80%82%e4%bb%8a%e3%83%95%e3%82%bf%e3%81%8c%e9%96%8b%e3%81%84%e3%81%a6%e3%81%84%e3%82%8b%e3%80%82",
    //  'やあ。俺は佐藤宅の便器だ。今フタが開いている。'    
    closeMsg[] = "%e4%bf%ba%e3%81%af%e4%bd%90%e8%97%a4%e5%ae%85%e3%81%ae%e4%be%bf%e5%99%a8%e3%81%a0%e3%80%82%e4%bb%8a%e3%83%95%e3%82%bf%e3%81%8c%e9%96%89%e3%81%be%e3%81%a3%e3%81%9f%e3%80%82";
    //  '俺は佐藤宅の便器だ。今フタが閉まった。'
  char tweetStr[256];
  if(tiltStatus == HIGH){
    sprintf(tweetStr, "%s  \r\n %ld", openMsg, millis());
    //  Twitterは同じ文字列を繰り返し書き続けられないので、起動時間を付けて書き、重複を防ぐ。
  }else{
    sprintf(tweetStr, "%s  \r\n %ld", closeMsg,  millis());
  }
  TWITTER.post(tweetStr);
  TWITTER.wait();
}

 うまく動くようになったら、ホット・グルーでプロトタイプを便器のフタに取り付ける。

IMG_3216IMG_3215

 便所にLAN工事を施しておしまいだ。

IMG_3214
 

 上記動画のように便器のふたを開け閉めすると、やおら便器が次のように呟きだすのである。



引き続きLチカ

投稿日:

 引き続きLEDで遊ぶ。

 100円ショップのプラスチック・ビーズにLEDを埋め込むという武蔵野電波のマネはなかなか楽しく、それをたくさん作ったのだが、この前のやり方だといまいち個数が少なく、寂しい感じが否めない。

IMG_3193
この前のLED生け花

 それはなぜかというと、小さいブレッドボード上に電流制御抵抗をLEDごとに付けようとすると、どうしてもLEDか抵抗のどちらかを「ラインまたぎ」に横向けにしなければならず、最低2ラインが消費されてしまうからだ。このブレッドボードだと、電源回路を入れると、どうしても5個しかLEDが配置できない。

どうしてもこうなる
IMG_3195

 ブレッドボードの中身は、タテのラインが下のように一列づつ内部で接続されており、真ん中の横一文字の仕切りで分けられている。抵抗かLEDのどちらかしか真ん中をまたげないから、どちらかは横向きになるのである。

ブレッドボードの中身の結線状況
ミニブレッドボード

 そこで、便利なものがある。「集合抵抗」だ。

集合抵抗
IMG_3203

 これは、抵抗を集めてワン・パッケージにしたものだ。この写真のものは、「8素子9ピン」というもので、内部はこうなっている。

集合抵抗の回路
集合抵抗の内部

 秋葉原千石電商なら、本店地下の、レジから一番遠い、奥の抽斗で売られている。ひとつ20円だ。

 表面にはカラーコードではなく、「103」等と数字が刻まれている。これはセラコンの読み方と似ていて、「103」であれば 10\times 10^3=10k\Omega である。今回は「331」、すなわち33\times 10^1=330\Omega のものを買ってきた。

 足のピッチはちょうど2.54mmなので、ブレッドボードにピッタリ挿すことができる。これを使うと、ブレッドボード上、LEDと抵抗の組み合わせで2ピッチ消費していたところを1ピッチですませることができる。

集合抵抗を使うと1ピッチですむ
IMG_3202

 こうすると、LEDは真ん中の仕切りをまたぐだけでよいから、LEDビーズの花を8個植えることができる。

IMG_3207

 紙コップに活けると、前回より多少華やかになった。

IMG_3200

 さて、LEDビーズが増えたので、これを16個ほど量産し、「TLC5940NT」とArduinoの回路に取り付けてみよう。スケッチやブレッドボードは前に試したのと同じでいい。

IMG_3212

 動かすとこんな感じだ。

 パルス幅変調がうまくかかって、1個1個のLEDの消え具合になかなか余韻があってよい。また、よく見ていただくと、赤いビーズが必ずしも赤く光るわけではなく、緑や青に変化して光るのも、面白いところだ。




耽るLチカ

投稿日:

 LEDは半導体であるから、電球と違って、光り始める前は抵抗は無限大であり、電流は流れない。ところが電圧がVfを超えて光り始めたら最後、抵抗がなくなって電源をショートさせた状態でぶっ飛び、自分自身も壊れる。従って必ず抵抗を一緒にくっつけてやるのだ。

 その抵抗を選ぶのは簡単で、基本的に E = I\cdot R という、この式のみでよい。LEDを買ってくると、流すべき電流値(If)、光り始める電圧(Vf)がどこかに書いてあるから、それに従って計算する。すなわち、

R = \frac{V - Vf}{If}

ここに、

V 自分が用意する電源の電圧
Vf 買ってきたLEDのVf(順方向電圧)、つまり光り始める電圧
If 買ってきたLEDのIf(順方向電流)、つまり光らせるために必要な電流

 ただ、抵抗は入手可能な数値が決まっており、そのものピタリという抵抗値のものは売っていない。なので、計算した値と一番近い抵抗を選び、その抵抗値で再び電流を計算して、買ってきたLEDのIfを超えていないかどうかを確かめる。

 これが、簡単な計算ではあるけどいちいち面倒くさい。

 それでまあ、抵抗を選ぶのにこういうスプレッドシートを作る。

 それから、これを使ってみよう。

IMG_3181

 これは、「武蔵野電波のプロトタイパーズ第15回『TLC5940で16個のLEDを遊ぶ』」で取り上げられている「TLC5940NT」というICだ。千石電商本店2階、入って左側の、一番奥のほうの抽斗で売られている。武蔵野電波のページでは400~700円とされているが、千石電商の店頭売りでは390円である。

 Arduinoで使うには、GitHubにあるライブラリをダウンロードし、zipを展開して出てくる「tlc5940」というディレクトリをArduino IDEのインストールディレクトリの下にある「libraries」の中にコピーすればよい。

 スペックシートはコレだが、スペックシートを見るより、Arduinoにライブラリを入れると出てくるようになるサンプルスケッチの「BasicUse」を見た方が分かり易いと思う。こんな風にサンプルは書かれている。

/*
    Basic Pin setup:
    ------------                                  ---u----
    ARDUINO   13|-> SCLK (pin 25)           OUT1 |1     28| OUT channel 0
              12|                           OUT2 |2     27|-> GND (VPRG)
              11|-> SIN (pin 26)            OUT3 |3     26|-> SIN (pin 11)
              10|-> BLANK (pin 23)          OUT4 |4     25|-> SCLK (pin 13)
               9|-> XLAT (pin 24)             .  |5     24|-> XLAT (pin 9)
               8|                             .  |6     23|-> BLANK (pin 10)
               7|                             .  |7     22|-> GND
               6|                             .  |8     21|-> VCC (+5V)
               5|                             .  |9     20|-> 2K Resistor -> GND
               4|                             .  |10    19|-> +5V (DCPRG)
               3|-> GSCLK (pin 18)            .  |11    18|-> GSCLK (pin 3)
               2|                             .  |12    17|-> SOUT
               1|                             .  |13    16|-> XERR
               0|                           OUT14|14    15| OUT channel 15
    ------------                                  --------

    -  Put the longer leg (anode) of the LEDs in the +5V and the shorter leg
         (cathode) in OUT(0-15).
    -  +5V from Arduino -> TLC pin 21 and 19     (VCC and DCPRG)
    -  GND from Arduino -> TLC pin 22 and 27     (GND and VPRG)
    -  digital 3        -> TLC pin 18            (GSCLK)
    -  digital 9        -> TLC pin 24            (XLAT)
    -  digital 10       -> TLC pin 23            (BLANK)
    -  digital 11       -> TLC pin 26            (SIN)
    -  digital 13       -> TLC pin 25            (SCLK)
    -  The 2K resistor between TLC pin 20 and GND will let ~20mA through each
       LED.  To be precise, it's I = 39.06 / R (in ohms).  This doesn't depend
       on the LED driving voltage.
    - (Optional): put a pull-up resistor (~10k) between +5V and BLANK so that
                  all the LEDs will turn off when the Arduino is reset.

    If you are daisy-chaining more than one TLC, connect the SOUT of the first
    TLC to the SIN of the next.  All the other pins should just be connected
    together:
        BLANK on Arduino -> BLANK of TLC1 -> BLANK of TLC2 -> ...
        XLAT on Arduino  -> XLAT of TLC1  -> XLAT of TLC2  -> ...
    The one exception is that each TLC needs it's own resistor between pin 20
    and GND.

    This library uses the PWM output ability of digital pins 3, 9, 10, and 11.
    Do not use analogWrite(...) on these pins.

    This sketch does the Knight Rider strobe across a line of LEDs.

    Alex Leone <acleone ~AT~ gmail.com>, 2009-02-03 */

#include "Tlc5940.h"

void setup()
{
  /* Call Tlc.init() to setup the tlc.
     You can optionally pass an initial PWM value (0 - 4095) for all channels.*/
  Tlc.init();
}

/* This loop will create a Knight Rider-like effect if you have LEDs plugged
   into all the TLC outputs.  NUM_TLCS is defined in "tlc_config.h" in the
   library folder.  After editing tlc_config.h for your setup, delete the
   Tlc5940.o file to save the changes. */

void loop()
{
  int direction = 1;
  for (int channel = 0; channel < NUM_TLCS * 16; channel += direction) {

    /* Tlc.clear() sets all the grayscale values to zero, but does not send
       them to the TLCs.  To actually send the data, call Tlc.update() */
    Tlc.clear();

    /* Tlc.set(channel (0-15), value (0-4095)) sets the grayscale value for
       one channel (15 is OUT15 on the first TLC, if multiple TLCs are daisy-
       chained, then channel = 16 would be OUT0 of the second TLC, etc.).

       value goes from off (0) to always on (4095).

       Like Tlc.clear(), this function only sets up the data, Tlc.update()
       will send the data. */
    if (channel == 0) {
      direction = 1;
    } else {
      Tlc.set(channel - 1, 1000);
    }
    Tlc.set(channel, 4095);
    if (channel != NUM_TLCS * 16 - 1) {
      Tlc.set(channel + 1, 1000);
    } else {
      direction = -1;
    }

    /* Tlc.update() sends the data to the TLCs.  This is when the LEDs will
       actually change. */
    Tlc.update();

    delay(75);
  }

}

 この最初のほうのコメントにアスキー・アートで書かれている図を見て結線するとよい。こんな感じだ。

IMG_3185

 LEDは秋葉原・千石電商の隣の店、「akiba LEDピカリ館」で売っていた10個入り300円の白色LEDで、Vfが3.0V~3.4V、Ifが20mAとある。電源が5Vならば100Ωばかり抵抗を付けてやればいい理屈だが、全部点灯させるとArduinoがダメになってしまうから、さらに絞って10KΩつけてやる。

 コンパイルして動かすとこうなる。

 10kΩでもこれくらい明るい。

 このICを使うと、パルス幅変調の幅も、Arduinoが256段階であるのに比べ、4096段階と格段に細かくなる。

 アレンジを加えてみよう。昨日買ってきたポテンショメータを使う。アナログの4番ピンと5番ピンに50kΩのポテンショメータと10kΩの抵抗をつなぎ、それぞれを強さと速さにして、「尾を引いたみたいに」明るさ制御をする。

 ポテンショメータの回路はこうする。

IMG_3191

 図の「E1」をアナログ入力で読めばよい。ポテンショメータのつまみの位置は、次の計算でR2を求めれば明らかになる。

E_{0} = I_{0}\cdot(R_{1} + R_{2})
I_{0} = \frac{E_{0}}{R_{1} + R_{2}}…①
I_{0} = \frac{E_{1}}{R_{2}}…②
① = ②
\frac{E_{0}}{R_{1} + R_{2}} = \frac{E_{1}}{R_{2}}
E_{0}\cdot R_{2} = E_{1}\cdot R_{1} + E_{1}\cdot R_{2}
R_{2}(E_{0} - E_{1}) = E_{1}\cdot R_{1}
R_{2} = \frac{E_{1}\cdot R_{1}}{E_{0}-E_{1}}

 組み付けるとこうなる。

IMG_3187

 動かすとこんな感じ。

 スケッチはこんな感じ。

//
//  wPotentio2tlc5940.ino
//    ポテンショメータとTLC5940でLチカ
//    27.08.02(日)0900~
//    佐藤俊夫
//
#include "Tlc5940.h"
//
const float
  R1 = 10000.0,     //  ポテンショメータ前の抵抗10kΩ, 
  E0 = 5.0,         //  電源電圧5V, 
  MAXVR = 50000.0;  //  ポテンショメータの最大抵抗
const unsigned int   VR1 = 4, VR2 = 5;  //  ポテンショメータはアナログピンのA4・A5
const unsigned int MAX_LED = 15;  //  LEDは0~15の16個
//
void setup()
{
  Tlc.init();
  pinMode(VR1, INPUT);
  pinMode(VR2, INPUT);
}

void loop()
{
  float vr1 = 0.0, vr2 = 0.0, e11 = 0.0, e21 = 0.0;
  static unsigned int topLed = 0, tailLen = 10;
  e11 = analogRead(VR1) * (5.0 / 1024);
  e21 = analogRead(VR2) * (5.0 / 1024);
  vr1 = (e11 * R1) / (E0 - e11);  //  明るさ
  vr2 = (e21 * R1) / (E0 - e21);  //  速さ
  if(++topLed > MAX_LED + tailLen)  topLed = 0;
  Tlc.clear();
  int bright = constrain(fmap(vr1, 0.0, MAXVR, 0, 4095), 0, 4095);
  Tlc.set(topLed, bright);
  for(int i = topLed - 1; i >= 0; i--){
    bright -= (4096 / tailLen);
    if(bright < 0) bright = 0;
    Tlc.set(i, bright);
  }
  Tlc.update();
  unsigned int delayTime = constrain(fmap(vr2, 0.0, MAXVR, 100, 10), 10, 100);
  delay(delayTime);
}
//
float fmap(float x, float in_min, float in_max, float out_min, float out_max) {
  //  もともとの「map()」がlong int型でこの用途に合わないので、float型を定義
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

ただのLチカがこれまた

投稿日:

 釣りは「へら鮒に始まりへら鮒に終わる」と言うそうだが、「ArduinoはLチカに始まりLチカに終わる」などと誰かが言っていそうで多分誰も言っていない(笑)。

 さておき、けっこう楽しいんだよな、Lチカ。

 で、なんっか、手持ちのものをいろいろとくっつけたくなるのだ。今日目に入ったのはSeeedstudio SIDEKICK BASIC KITに入っていた青いポテンショメータ。私が少年の頃は「バリオーム」「ボリューム」「可変抵抗」と言ったものだが、今はポテンショメータと言うそうな。

 ポテンショメータでLチカのスピードを調整してみよう。

 まず、ポテンショメータのスペックシートなどがなくてはっきりしないから、テスターを当てて抵抗を測る。0Ωから10.5kΩまで変化できることがわかった。

 このまま直列に+5Vを印加してアナログピンに入力してしまいそうだが、0Ωの時に過電流になってしまうから、10kΩの別の抵抗と直列に入れた方がいいだろう。そうするとポテンショメータを最小に回し切っても0.5mAくらいに抑えられる。

 計算はどうなるかというと、こんなようなことになる。

IMG_3161

 式に代入すれば、ポテンショメータを最大抵抗にしたとき2.44V、最小抵抗にしたとき0Vになることがわかる。

 プロトタイピングシールドのブレッドボードは小さくて全部の部品が載らないから、普段使っている普通のブレッドボードにつける。

IMG_3157

 動かすとこんな感じだ。

 スケッチはこんな感じ。

//
//  vr2speed.ino
//    ポテンショメータでLチカ制御
//    27.07.26(日)1300~
//    佐藤俊夫
//
const unsigned int
  STARTPIN  = 2,
  ENDPIN    = 8,
  INPUTPIN  = 9,
  VR        = 0,
  DELAYMIN  = 5,
  DELAYMAX  = 100;
const float
  V0 = 5.0,         //  +5V
  R1 = 10000.0,     //  アナログピンに入れるための電流制限抵抗10kΩ
  VRMIN = 0.0,      //  ポテンショメータの最小抵抗実測値 0Ω
  VRMAX = 10500.0;  //  ポテンショメータの最大抵抗実測値 10.5kΩ
//
void setup() {
  //  330Ωをカソードにそれぞれ入れてデジタル2~8番にLEDを繋いである。
  for(int i = STARTPIN; i <= ENDPIN; i++){
    pinMode(i, OUTPUT);
  }
  //  タクトスイッチは9番に繋いでアースし、内蔵プルアップ抵抗を使っている。
  pinMode(INPUTPIN, INPUT_PULLUP);
  //  ポテンショメータは10kΩ抵抗と直列に繋ぎ、間から出力を取っている。
  pinMode(VR, INPUT);
}

void loop() {
  static int i = STARTPIN, RLdirection = 1, delaytime = DELAYMIN;
  static unsigned long int prevtime = 0;
  if(prevtime + delaytime < millis()){
    digitalWrite(i, LOW);
    i += RLdirection;
    if(i > ENDPIN) i = STARTPIN;
    if(i < STARTPIN) i = ENDPIN;
    digitalWrite(i, HIGH);
    prevtime = millis();
  }
  if(digitalRead(INPUTPIN) == LOW){
    delay(500);
    RLdirection *= -1;
  }
  float v1 = (V0 * R1) / (R1 + VRMAX);
  float vr = analogRead(VR) * (V0 / 1024);
  delaytime = constrain(fmap(vr, v1, 0.0, DELAYMAX, DELAYMIN), DELAYMIN, DELAYMAX);
}

float fmap(float x, float in_min, float in_max, float out_min, float out_max) {
  //  もともとの「map()」がlong int型でこの用途に合わないので、float型を定義
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}




出来る限り美しく

投稿日:

 同じLチカをやるのでも、単線タイプのジャンプワイヤをちゃんと使い、できる限りブレッドボード上を整然と配置してみた。これまではあまりそんなことは考えていなかったからだ。

 とりあえず持っているLEDを持っている330Ωの電流制御抵抗の個数の限り配置した。タクトスイッチをつけて、入力を受け付けるようにする。とりあえず、LEDの点滅が右から左へ流れ、タクトスイッチを押すたびに左右の向きが入れ替わる、というふうにしよう。

IMG_3153

 タクトスイッチの入力にプルダウン抵抗を取り付けるスペースがなくなってしまったので、内蔵プルアップ抵抗を使うことにし、負論理にする。

 動かすとこんな感じだ。

 スケッチはこんな感じ。

//
//  smartBreadboard.ino
//    出来るだけ美しくブレッドボードを作ってみた。
//    27.07.26(日)0800~
//    佐藤俊夫
//
const unsigned int
  STARTPIN  = 2,
  ENDPIN    = 8,
  INPUTPIN  = 9,
  DELAYTIME = 50;
//
void setup() {
  //  330Ωをカソードにそれぞれ入れてデジタル2~8番にLEDを繋いである。
  for(int i = STARTPIN; i <= ENDPIN; i++){
    pinMode(i, OUTPUT);
  }
  //  タクトスイッチは9番に繋いでアースし、内蔵プルアップ抵抗を使っている。
  pinMode(INPUTPIN, INPUT_PULLUP);
}

void loop() {
  static int i = STARTPIN, j = 1;
  static unsigned long int prevtime = 0;
  if(prevtime + DELAYTIME < millis()){
    digitalWrite(i, LOW);
    i += j;
    if(i > ENDPIN) i = STARTPIN;
    if(i < STARTPIN) i = ENDPIN;
    digitalWrite(i, HIGH);
    prevtime = millis();
  }
  if(digitalRead(INPUTPIN) == LOW){
    delay(500 );
    j *= -1;
  }
}