Raspberry PiでLチカ

投稿日:

 で、LED1個では寂しいから、同じコードを繰り返して、8個でLチカ。

IMG_3286

 抵抗は8素子9ピンの集合抵抗、各素子330Ω。Vfが3.0~3.4V、Ifが20mAとある青色LEDなのだが、抵抗がこれだけならせいぜい10mAくらいだ。GPIOの各ピンから流せる電流は50mAまでだそうなので、まあ、大丈夫だろう。

 動かすとこんな感じ。

 プログラムは、GPIOのセットアップをするシェルと、Perlのスクリプトだ。

 シェルはこのようなもの。コピペで繰り返しただけ。シェル内の数字がピン番号。

#!/bin/sh
echo  5 >/sys/class/gpio/export
echo  6 >/sys/class/gpio/export
echo 13 >/sys/class/gpio/export
echo 19 >/sys/class/gpio/export
echo 26 >/sys/class/gpio/export
echo 21 >/sys/class/gpio/export
echo 20 >/sys/class/gpio/export
echo 16 >/sys/class/gpio/export
echo out >/sys/class/gpio/gpio5/direction
echo out >/sys/class/gpio/gpio6/direction
echo out >/sys/class/gpio/gpio13/direction
echo out >/sys/class/gpio/gpio19/direction
echo out >/sys/class/gpio/gpio26/direction
echo out >/sys/class/gpio/gpio21/direction
echo out >/sys/class/gpio/gpio20/direction
echo out >/sys/class/gpio/gpio16/direction

 Perlも同じで、コピペで繰り返しただけ。……「配列に書けよ」とかの至極もっともなツッコミはナシの方向でお願いいたしますです(笑)。

#!/usr/bin/perl
#  perl2LEDx8
#    perlで8個Lチカ
#    27.8.16(日)1500~
#    佐藤俊夫
#
use strict;
use warnings;
use Time::HiRes 'sleep';
open(LED1, ">/sys/class/gpio/gpio5/value");
open(LED2, ">/sys/class/gpio/gpio6/value");
open(LED3, ">/sys/class/gpio/gpio13/value");
open(LED4, ">/sys/class/gpio/gpio19/value");
open(LED5, ">/sys/class/gpio/gpio26/value");
open(LED6, ">/sys/class/gpio/gpio21/value");
open(LED7, ">/sys/class/gpio/gpio20/value");
open(LED8, ">/sys/class/gpio/gpio16/value");
LED1->autoflush(1);
LED2->autoflush(1);
LED3->autoflush(1);
LED4->autoflush(1);
LED5->autoflush(1);
LED6->autoflush(1);
LED7->autoflush(1);
LED8->autoflush(1);
while(){
  print LED8 0;
  print LED1 1;
  sleep(0.2);
  print LED1 0;
  print LED2 1;
  sleep(0.2);
  print LED2 0;
  print LED3 1;
  sleep(0.2);
  print LED3 0;
  print LED4 1;
  sleep(0.2);
  print LED4 0;
  print LED5 1;
  sleep(0.2);
  print LED5 0;
  print LED6 1;
  sleep(0.2);
  print LED6 0;
  print LED7 1;
  sleep(0.2);
  print LED7 0;
  print LED8 1;
  sleep(0.2);
}

ユーザー作ったりとか

投稿日:

 Raspberry Piで遊ぶ。

 私が買ったのは、「Raspberry Pi 2 Model B」という最新のものだ。オライリー・Make:PROJECTSシリーズの「Raspberry Piをはじめよう」で解説されているのは古い方の「Raspberry Pi モデルA」「同B」なので、少しづつ合わないところがあるが、ごく細部を除いては、特に気にする必要はない。細部の違いが影響してくるのは、よほど高度なことをやる場合だ。

 今さら私が述べ立てることではないと思うが、私と同じような人で、Rasberry Piのことを知らない、という人に向けて書けば、結局はこうだ。

  •  Raspberry Piは、GPIOインターフェイスボードを積んだ普通のPCだと思えばよい。
  •  普通のPCなので、Linux系OS以外にも、Windows10なども使える。だが、成果物のほとんどはRaspbianというLinuxディストリビューション上で得られているので、OSにはRaspbianを選択しておくのが無難。
  •  前記GPIOは、普通にファイルに見えるので(と言っても、/devの下にデバイスファイルがあるわけではない;もちろん、シンボリックリンクでそういうふうにすることはできるが)、標準出力でファイルを開け、書いて閉じれば、それでGPIOにつないだ電子工作をコントロールできる。
  •  Arduinoに比べると、ロジックが正=3.3Vであること、アナログ入力がないことなどが違う。解説書「Raspberry Piをはじめよう」にも、
    「最初にRaspberry Piのニュースが流れたとき、それがArduinoキラーになるのではないかと多くの人が考えました。値段はたいして違わないのに、Piはずっと大きなCPUパワーを持っています。だったらArduinoを使う理由はもうない、というわけです。しかし、やがて両者は補完的な関係にあることが分かってきました。以下のような状況を考えると、ArduinoとPiを組み合わせるメリットが見えてきます。

    • Arduinoの豊富なライブラリと作例を活用したい。
    • すでにうまく動いているArduinoプロジェクトにCPUパワーを追加して、もっと高度なことがしたい。
    • 5Vで動作する回路を扱いたいが、Piは3.3V動作で、5V入力に対応しない。
    • 誰かがプロトタイピングの過程で少しばかり無茶をしてチップがダメージを受けた時(Arduinoのピンにモーターを直結している人を見たことがあります)、Arduinoならば数百円以下でスペアのチップを買って自分で交換することもできるが、Piでそれをするのはほぼ不可能。
    •  3Dプリンタ用コントローラのように高精度なリアルタイム処理を必要とするものを作るとき、リアルタイムOSとは言えないRaspbianよりも、命令サイクルを計算できるマイクロコントローラのほうが要求に適う可能性が高い

    (p.88冒頭から引用)
    ……等とある。

  •  Linuxなので、使い始めるにはとりあえずrootを把握して、ユーザを作ればよい。作りつけのユーザもあるが、私のようなおっさんは、まず
    「# useradd -g pi toshio ; passwd toshio ; mkdir /home/toshio ; chown toshio:pi /home/toshio」
    ……なんてことをやらないと落ち着かないのである。
  •  さまざまな作例等はPythonの利用が想定されているので、さまざまな作品例のマネがしたければPythonを使えばよいが、前記したように「普通のLinuxマシン」なので、PerlだろうがCだろうが、おっさん系の言語も全部使えるから、私のようなおっさんは自分が使いたい言語を使えばよい。

 なので、例えば、「Raspberr Piをはじめよう」の102ページあたりに載っている最初のLチカの例は、次のような方法でも再現できる。

#!/usr/bin/perl
#  perl2LED
#    perlでLチカ
#    27.8.16(日)
#    佐藤俊夫
#
open(GPIO25, ">/sys/class/gpio/gpio25/value");
GPIO25->autoflush(1);
while(){
  print GPIO25 1;
  sleep(1);
  print GPIO25 0;
  sleep(1);
}

……などとPerlで書き、「gpio25」をユーザ空間にエクスポートして、

# ./perl2LED

 とやると、LEDが1秒おきにチカチカするのである。

Raspberry PiでのLチカ最初の例
IMG_3285

その意味を

投稿日:

 終戦記念日には靖国神社へ参拝に行っている。最近──とは言っても、十数年来くらい──の習慣だ。

 その範囲で最も混雑したのは、たしか、大震災の前、民主党政権に代わって1年ほど経った後の、平成22年の8月であったと記憶する。この時には、地下鉄九段下の駅の中まで行列が続いていた。

 あの頃を振り返ると、当時実際の多くの人々の行動はマスコミの論調とは全く逆方向に志向し、精神が沸騰していたのを、生の現場ではひしひしと感じ取れたものであった。だが、あの年、例年より混雑する靖国神社周辺の様子はほとんど報道されることなく、むしろ「靖国神社なんぞに参拝するような変な日本人のことを全アジア諸国の皆さんが残念がり、ないしは激怒しており、靖国神社は低迷している」みたいな報道ぶりだった。

 去年は終戦記念日に仕事をしていたので、仕事が終わってから夕刻に参拝したが、今年は休みなので、朝から出かけた。

 私の家からは、電車1本で直接九段下へ行ける。そうして午前10時半頃に九段下の駅に着いてみて、さあ、今日と言う今日は驚いた。

 九段下の駅構内こそ人が流れてはいたが、地上へ出てみてびっくりである。九段下の駅の入り口は東西にあり、靖国神社側と九段下交差点側があるのだが、大鳥居の入り口にほど近い西側の駅入り口から九段下の交差点まで、延々と人が並んでいるではないか。しかも、単にワン・パスで並んでいるのではない、九段下駅西側入り口から九段下交差点まで反対向きに並び、列はそこから折り返して靖国神社へ向かっているのである。

 こんなことは初めてである。人員整理の仕方を少し変えていたということもあったようだが、それにしても大変な人出だ。

 数字を確かめていないので正確なところはわからないが、あの平成22年の8月よりもまだなお混雑しているように感じられた。

 靖国神社は自分の政治的思想を開陳する場とは違う。英霊へ鎮魂の祈りと誠をささげまつる場である。それを、がなり立てる右翼はまだしも、着用する資格のない軍服など一着に及んで、なにやらコスプレ祭りと勘違いしている若者も出てくる始末で、毎年毎年嘆かわしいことだが、愛の反対は無関心、ということからすれば、それもむべなるかな、とは思う。

 この世情下、これほど多くの人が参拝に来ているわけを、この混雑、その意味を、自分なりに考えてみたい。

 この膨大な人数の参拝客は、あの戦争とそれに参加し死んだ人々を、もう一度評価しなおしたいと考えているように見える。たとえ悪い方向へ批判するのであっても、逆に良い方向へ評価するというのであっても、どちらでも良いから冷静に何かを問いたい、そのための元となる行動を何かしないと、そういう行動をとらないと、もう、議論をただの一歩も先へ進めることが出来ない、何もしないでは議論を深める資格がない、そう考えているのではないだろうか。

 そうすると、靖国の境内を例年の倍にも感じられるほど埋め尽くす人々の姿は、英霊に仮託した自己の求道の姿だということになる。

 そうであるならば、それは政治的なパフォーマンスに近く、英霊の鎮魂のための行為ではない。とても神社ですることとは言えないが、しかし、護国の鬼たちは今や柔和にそれを許し給うと考えたい。

11892024_1008516605845859_6741406045379287350_n

 2時間ほどは並ぶ始末であった。中門鳥居のあたりで正午を迎えることとなったため、千鳥ヶ淵から中継でスピーカー放送されてくる慰霊式の様子に聴き入った。国歌斉唱のおり、靖国神社境内の群衆が誰ともなく歌い始めるのも例年と同じだ。はじめは遠慮がち、恥ずかしげに小さい声で口ずさんでいた人々の歌声が次第に大きな声になっていく。こうべを垂れて天皇陛下のお言葉を謹聴する。ちょうど正午、帽子を脱して黙祷する。

 ともあれ、英霊やすらかにしずみたまえ、と参拝はそれのみ考えつつ済ませ、帰路、あれこれと考えに耽った。

 靖国通りを神田に向かって歩いていたら「藪仙」という蕎麦屋があったので、ひょいと入る。大蒸篭せいろを頼んだら3枚もついてきて、お得。酒を2合。

 せっかく神田あたりに来たなら、蕎麦は名代の「まつや」に寄りたいところだが、籔仙の大蒸篭を手繰り終わってからまつやの前を通りかかると、案の定、炎天下数十人の行列だった。まつや目当てに連雀町へ来て見ても、これではとても並ぼうという気は起きなかったろう。多分今日は例年通り「神田・籔」が盆休みで、その客もまつやが吸収しているものと見える。

 暑かったが秋葉原まで歩いた。九段下から秋葉原までは歩いて30~40分だ。千石電商でフラックスとソルダーウィック、蛇の目基盤を買う。ヨドバシへ行ってHDMIとDVI-Dの変換アダプタをひとつ買う。これはRaspberry Piを今使っているPCのモニタにつなぐため。

 秋葉原のメイド通りは、今日が終戦記念日だということなどまるで知らぬげに、世界各国の老若男女とメイドでごった返していた。

今10分ほどRaspberry Piを触ってみて分かったのは、

投稿日:

 今10分ほどRaspberry Piを触ってみて分かったのは、Raspberry Piは結局のところ、Linuxでの使用が基本なので、私のようにUNIX育ちの人物には、かえってとっつきやすく扱いやすい、ということだ。

 これはいい。

 Windows10はRaspberry Piのサポートも表明しているやに聞くが、Windowsでハードウェアに触ろうなんて気持ち、まったく起きないもんなあ……。

買っちゃった

投稿日:

 前々からいじってみたいと思っていたものの一つがArduinoであった。これはもう、だいぶ前から触ってみたかった。人様より遅れ馳せながら、この春からいじりはじめることができ、楽しく過ごすことができた。

 触ってみたかった物の二つめが、「Raspberry Pi」である。

 まずArduinoがだいたいいじれるようになって、それからおもむろにRaspberry Piに行ってみよう、と考えた。この春以降頃からのArduinoのほうの進捗から言って、Raspberry Piがいじり始められるのは夏頃にはなるかな、と予測した。

 Arduinoはたぶんなかなか上達しないだろうと踏んでいたが、思いのほか、最近は思ったことがだいたいできるようになった。

 それで、最初のもくろみ通り、盆休みにははじめにRaspberry Piを買って、休みの間いじり倒してみよう、と思っていたのだが、意外にArduinoのほうで、これもやってみようあれもやってみようと、やりたいことが次々にあるものだから、休暇も終わり近くなってからやっとRaspberry Piに目が向いた。

 昨日、秋葉原へ行って、買っちゃった。小遣いがあるうちに、買っちゃえ買っちゃえ(笑)。

IMG_3277
IMG_3278
IMG_3279
IMG_3280
IMG_3282
IMG_3284

ノクターンでLチカ

投稿日:

 いやもう、「オッサンとバイエル、ピアノ等」って銘打ってて、長らくなかったこのネタ。ええ、ピアノですよ、ピアノ。

「Arduinoをピアノにつなぎたいッ!」

……すなわちコレである。Arduinoをピアノにつなぎ、LEDをピアノ演奏に合わせて明滅させようというものだ。

 いまや遅しとやってみた。

ノクターンでLチカ

 一つ覚えみたいにノクターンで申し訳ないですが(笑)、すんませんレパートリーがあんまりないもんで。

IMG_3276

 アナログピンからピアノの音声出力を読み、それに合わせてTLC5940NTに接続されたLEDを適宜明滅させるわけである。いかにもピアノ風味に明滅させるにあたっては、乱数によるLED選択と、先日会得した「PWMを十分に使い、余韻をもって各LEDを徐々に消す」という技を遺憾なく使用した。

 これをやるには、アナログピンに上手に音声を入れる必要がある。

 こういう時、電圧レベルを知るのにオシロスコープなどが使えればいいのだが、残念ながら持っていない。そこで、あらかじめテスターのACでテレビ、ラジオ、自分のピアノなどの音声出力端子からだいたいのレベルを推定し、次に十分な抵抗を入れて、Arduinoのアナログピンに入力して読み取った。その結果、だいたい200mVの振幅程度であることがわかった。これならばArduinoに直接入れてもどうということはなさそうだ。ただし、レベルが小さいから、ソフトウェアのほうでうまくやる必要がある。

 次に、音声はアナログ信号だから、プラス・マイナスに振れる。一方、Arduinoのアナログ入力は0~5Vの間を1024分割で読むのだから、ここをうまく工夫しなければならない。

 まず、2.5Vを中心に電圧が振れるよう、2.5Vを生成して合成する。ちょうどTLC5940NTを動かすために5Vの3端子レギュレータを使っているので、ここから抵抗分圧で2.5Vを作り、それを合成する。合成するとき、出力側の音声端子に電流が流れ込んではまずいから、コンデンサを0.1μFばかりつける。周波数は見当がつくが、電圧の見当がつきにくいので、とりあえず0.1μFにして、出来が悪いようなら取り換えることにする。

 まず、大して疑問もない簡素な付加回路。たしか、パルス技術ではこういうの、「クランパ」って言ったっけな……。

音声入力のためのクランパ
「voice2tlc」の回路図

 それで、TLCなどと一緒にLEDを植え込む。

IMG_3273

 ミニジャックを接続するために、秋月電子の「ステレオミニジャックDIP化キット」を取り付けた。

ミニジャックの部分
IMG_3274

 で、スケッチはこうなった。

//
//  voice2tlc.ino
//    アナログピンに音声を入れ、TLC5940NTを使ってLEDを光らせる。
//    27.08.13(木)1000~
//    佐藤俊夫
//
#include "Tlc5940.h"
#include <stdio.h>
//
const int
  AUDIO = 0, //  アナログ0ピン
  THRESH = 8;  //  8単位以上のレベルならLEDを点灯
//
void setup() {
  Tlc.init();
  Tlc.clear();
  Tlc.update();
}

void loop() {
  int v = 0, l = 0;
  static long int prevtime = 0.0;
  static int prevv = 0;
  v = abs(analogRead(AUDIO) - 512);
  l = constrain(fmap(v, 0, 15, 0, 4095), 0, 4095);
  if(millis() >= prevtime + 10){
    prevtime = millis();
    for(int i = 0; i <= 15; i++){
      Tlc.set(i, Tlc.get(i) * 0.9);
    }
  }
  for(int i = 0; i <= 15; i++){
    if(random(0, 16) == 1 && prevv != v && v >= THRESH){
      Tlc.set(i, l);
    }
  }
  Tlc.update();
  prevv = v;
}
//
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;
}

前にこの記事で

投稿日:

 前に雲の間欠撮影をするスケッチを書いた時、「こういう時、Arduinoには書式文字列付きの「sprintf」がないので、少し不便だなと思う。」と書いたが、これも早合点で、Arduino(というか、『AVR-libc』という、Arduino環境で使われているライブラリ)では「stdio.h」をインクルードすれば、ちゃんとsprintfが使える。

お稽古2

投稿日:

 7セグLEDの稽古をする。

 先日の稽古では、TLC5940NTで7セグLEDに数字を表示させる方法はわかったが、いまいちブレッドボードが乱雑で汚かった。

乱雑で汚いブレッドボード
IMG_3240

 そこで、なんとかこれを美しくする配置があるはずだ、と脳漿を絞った。

 いろいろとやったが、結局、「LEDの一番若いピンをTLC5940NTの一番若いピンに、残りのピンも同様に順番に」というような「論理的に美しい配置」だと、「物理的に汚く」なることがわかった。

 そこで、論理上のピン配置は多少前後しても、とにかく作動し、逆に物理的にはシンプルで美しく、誤りも見つけやすいという配置を追及したところ、このような配置・配線になった。

できる限り美しくした
IMG_3264

 なかなかシンメトリックで綺麗な配置になったと思う。誤りも見つけやすい。そのかわり、LEDの1・2・3・4番はそれぞれTLCの1・0・7・6番、……と言った具合に、ピンとピンとの対照関係は複雑になった。これはソフトウェアで吸収することになる。配列などでマッピングすると良いのだろう。

とにかく目一杯

投稿日:

 実用的なモノというとネット便器ぐらいしか作らず、Lチカばかりやっている今日この頃であるが、Lチカは楽しいので仕方がない。というか、「ネット便器のどこが実用的なのか?」というツッコミに極めて脆弱な文章をついつい書いてしまっているところもなかなか痛いが、さておき、昼間の「亀の子ブレボー」に、いつぞや大量生産したビーズ付きLEDを目一杯大量に植え込み、TLC5940NTでゴンゴンドライブしてみた。

 前回TLC5940NTを使ったときは、単純に右から左へ光るだけだったが、今度と言う今度は、もう、今思いつくだけあらん限りいろんな光らせ方をさせてみた。

 亀の子ブレッドボードは、なかなか省スペースで、うまく組み付けられる。

TLC5940NTを亀の子ブレボー(笑)に設置した状況
IMG_3259

 LEDをタップリ植え込むとこうなる。

IMG_3261

 動かすとこんな感じだ。

 スケッチはこうなった。はじめはタクトスイッチで手動切り替えをしていたが、面倒臭くなり、乱数で切り替えるようにした。

//
//  tlcVariation.ino
//    TLC5940NTにつないだLED、ランダムにいろんな光らせ方をしてみる。
//    27.08.11(火) 1515~
//    佐藤俊夫
//
#include "Tlc5940.h"
//
const int switchInterval = 5000;
//
void setup() {
  Tlc.init();
  Tlc.clear();
  Tlc.update();
}
//
void loop() {
  static int mode = 0;
  static long int prevtime = 0;
  if(millis() > prevtime + switchInterval){
    mode = random(0, 8);
    prevtime = millis();
    //  今のエフェクトを徐々に消す。
    int maxlum = 0;
    do{
      maxlum = 0;
      for(int i = 0; i <= 15; i++){
        Tlc.set(i, Tlc.get(i) * 0.9);
        maxlum = Tlc.get(i) > maxlum ? Tlc.get(i) : maxlum;
      }
      Tlc.update();
      delay(20);
    }while(maxlum > 0);
  }
  switch(mode){
    case 0:
      sinCurve_diff();
      break;
    case 1:
      inOrder_left();
      break;
    case 2:
      toCenter();
      break;
    case 3:
      inOrder_tail();
      break;
    case 4:
      left_right();
      break;
    case 5:
      left_right_tail();
      break;
    case 6:
      allAtOnce_tail();
      break;
    case 7:
      inOrder_right();
      break;
    default:
      sinCurve_diff();
      break;
  }
}
//
void inOrder_right(){
  //  0.1秒おきに右から切り替えていく。
  static long int prevtime = 0.0;
  static int led = 15;
  Tlc.clear();
  if(millis() >= prevtime + 100){
    Tlc.clear();
    Tlc.set(led--, 4095);
    led = led < 0 ? 15 : led;
    Tlc.update();
    prevtime = millis();
  }
}
//
void allAtOnce_tail(){
  //  一斉に点灯して徐々に消える。
  static long int prevtime = 0;
  if(millis() > prevtime + 100){
    prevtime = millis();
    if(Tlc.get(0) <= 0){
      for(int i = 0; i <= 15; i++){
        Tlc.set(i, 4095);
      }
    }else{
      for(int i = 0; i <= 15; i++){
        Tlc.set(i, Tlc.get(i) * 0.8);
      }
    }
    Tlc.update();
  }
}
    
//
void left_right_tail(){
  //  尾を引きながら右へ行ったり左へ行ったり。
  static long int prevtime = 0.0;
  static int led = 0, order = 1;
  if(millis() >= prevtime + 100){
    for(int i = 0; i <= 15; i++){
      Tlc.set(i, (int)((float)Tlc.get(i) * 0.5));
    }
    led = led + order;
    Tlc.set(led, 4095);
    order = (led >= 15) || (led <= 0) ? order * -1 : order;
    Tlc.update();
    prevtime = millis();
  }
}
//
void left_right(){
  //  右へ行ったり左へ行ったり
  static long int prevtime = 0.0;
  static int led = 0, order = 1;
  if(millis() >= prevtime + 100){
    Tlc.clear();
    led = led + order;
    Tlc.set(led, 4095);
    order = (led >= 15) || (led <= 0) ? order * -1 : order;
    Tlc.update();
    prevtime = millis();
  }
}
//
void inOrder_tail(){
  //  尾を引きながら0.1秒おきに左から切り替えていく。
  static long int prevtime = 0.0;
  static int led = 0;
  if(millis() >= prevtime + 100){
    for(int i = 0; i <= 15; i++){
      Tlc.set(i, (int)((float)Tlc.get(i) * 0.5));
    }
    Tlc.set(led++, 4095);
    led = led > 15 ? 0 : led;
    Tlc.update();
    prevtime = millis();
  }
}
//
void toCenter(){
  //  中央付近のLEDから外へ光らせる。
  static long int prevtime = 0.0;
  static int ledleft = 7, ledright = 8;
  if(millis() >= prevtime + 100){
    for(int i = 0; i <= 15; i++){
      Tlc.set(i, (int)((float)Tlc.get(i) * 0.5));
    }
    Tlc.set(ledright++, 4095);
    Tlc.set(ledleft--,  4095);
    ledright = ledright > 15 ? 8 : ledright;
    ledleft = ledleft < 0 ? 7 : ledleft;
    Tlc.update();
    prevtime = millis();
  }
  
}
//
void inOrder_left(){
  //  0.1秒おきに切り替えていく。
  static long int prevtime = 0.0;
  static int led = 0;
  Tlc.clear();
  if(millis() >= prevtime + 100){
    Tlc.clear();
    Tlc.set(led++, 4095);
    led = led > 15 ? 0 : led;
    Tlc.update();
    prevtime = millis();
  }
}
//
void sinCurve_diff(){
  //  呼ぶたびにサインカーブをちょっとづつずらしながら光らせる。
  static float x[16] = {
    0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
    0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
  };
  for(int i = 0; i <= 15; i++){
    x[i] = x[i] >= (2.0 * PI) ? 0.0 : x[i] + ((2.0 * PI) / 1000.0) * (1.0 + (float)i / 10.0);
    Tlc.set(i, (int)(((sin(x[i]) + 1.0) / 2.0) * 4095));
  }
  Tlc.update();
}