2015年1月5日月曜日

LEDアレイを波打たたせた



上の動画、音量注意っす。調節する方法がわからんw

各色LEDが一列に並んだモジュールを電子工作仲間のOさんから頂戴しました。どうもありがとうございます。

LEDとデジタル時計が三度の飯より好きな私なので、さっそくLチカしてみました。ただ、普通に点滅させても面白くないので、ウェーブしてみます。でもウェーブさせるにはPWMが必要ですが、いただいたのは12bit分、Arduino unoのPWMは6chしかありません。

ので、ソフト的に処理しました。一番内側のループphaseの値を0〜31まで変化させ、sinテーブルの値がその値よりも大きければ点灯、小さければ消灯させます。sinテーブルから拾ってくる位置をピンごと(i*3)に、また時間の経過(offset)ごとにずらしていけば、こんな具合いにうねうね動きます。モジュールの端にGND端子があり、1枚はArduino unoの13ピン隣にあるGNDに、もう1枚のGNDは7ピンに接続してLOWを出力しています。

だいたいPWMとしての基本クロックは70hzぐらい、肉眼で見ている分にはあまりフリッカは感じないですが、目をすっと動かすと点滅が軌跡となって見えますねぇ。


以下ソースです。
const int p01 = 13;
const int p02 = 12;
const int p03 = 11;
const int p04 = 10;
const int p05 =  9;
const int p06 =  8;
const int p07 =  6;
const int p08 =  5;
const int p09 =  4;
const int p10 =  3;
const int p11 =  2;
const int p12 =  1;
 
const int pGnd = 7; 
const int pins[] = {p01, p02, p03, p04, p05, p06, p07, p08, p09, p10, p11, p12};
const int nPins = sizeof(pins) / sizeof(int);
const int nSin = 32;
 
int iSin[nSin]; 
void setup() {
  pinMode(pGnd, OUTPUT);
  digitalWrite(pGnd, LOW);

  for (int i = 0; i < nPins; i++) {
    pinMode(pins[i], OUTPUT);
    digitalWrite(pins[i], LOW);
  }

  int half = nSin / 2;
  for (int i = 0; i< nSin; i++) {
    float d = (float)i / (float)nSin * 2.0 * 3.14159265;
    iSin[i] = sin(d) * half + half + 2;
  }
}

int phase = 0;
int outer = 0;
int offset = 0;

void loop() {

  for (int i = 0; i < nPins; i++) {
    int output = iSin[(i*3 + offset) % nSin] /2;
    int lowHigh = (output > phase) ? 1 : 0;
    digitalWrite(pins[i], lowHigh);
  }

  phase++;
  if (phase >= nSin) {
    phase = 0;
 
    outer++;
    if (outer > 2) {
      outer = 0;
   
      offset++;
      if (offset >= nSin) {
        offset = 0;
      }
    }
  }
}

0 件のコメント:

コメントを投稿

注: コメントを投稿できるのは、このブログのメンバーだけです。