いろいろ作るよ

IT、電子工作、裁縫

SHIROBAKO adventar ~どんどんLED~

SHIROBAKOのadventarに参加させてもらいました!!!

www.adventar.org

SHIROBAKOとわたし

SHIROBAKO、言わずと知れた2015年神アニメです。モノづくりに関係した仕事であれば、他人事ではないあるあるの話がたくさんでてきて・・涙なしには見れません。主人公の成長を通して、自分の過去も顧みたりしてとても感慨深いアニメです。

木下監督は理想のプロダクトオーナーだなあ

最終的に良いプロダクトを完成させている点、納期に間に合っている点においてSHIROBAKOのチームは本当にいいチームだと思います。得に私はいつも思いますが監督と一緒に働きたいなあと思ってます。自分の理想をガンとして持っていて(時にはそれがめんどくさいこともあるけど)主張してくれる、そういう人の意見をヒアリングしながら、マッシュアップしていくような職場が理想。なかなか監督はレアな存在ですよね!

で、何をやるか・・ネタは?

POV(LEDの残像で文字を表示するやつです)作ってで"ドンドン" って表示させて、ドーナツ!2015お疲れ様でしたー!って占めたかったんですよ。個人的に2015年はArduinoにはまった年だったので、それを使ってやりたかった。

万策つきたぁーーー。IDEのバージョン上げたらAVR書き込みができなくなった。

いまもう14日ですよ!ArduinoIDEのバージョンを、最近他の基盤(ESP8266)で開発をするために上げたんです。1.0.5系 -> 1.6系に。そしたら!Atmega328に書き込みができなくなって今ですよ。もうね今日は解決できないです。インフルエンザでちょと熱が高いんです。ふんだり蹴ったりです。しかし、配線もPOVのプログラムを作り終わっているのでそれをアップして、後は熱が下がり次第ということで許してください。ごめんなさい。

配線

Arduino互換であるAtmega328を使ったArduino互換機を使って開発してます。
LEDはI/Oピン6~13の8本を使います。

材料はこれです。
Arduino互換と、LED8個、抵抗8本です。

f:id:mikodayo:20151213222401j:plain

配線後は以下です。LEDをそれぞれIOピンに抵抗を介したうえで接続してあげます。

f:id:mikodayo:20151213223237j:plain

POVのプログラム

ダイナミック点灯(常時点灯していると電池消費がすごいので、切り替えを高速でやる手法)を使ってます^-^!基本的にdelayは予期しない動きになって非常に悲しい事態に陥ることがあるので、sleep目的ではTimeroneを使います。当プログラムをIDE上でコンパイルするにはTimeroneのヘッダファイルが必要です。

#include <TimerOne.h>

// common var
// leds
int leds[] = {6, 7, 8, 9, 10, 11, 12, 13};
#define NUMBER_OF_LEDS (sizeof(leds)/sizeof(int))
// menu
unsigned long led = 0;
// wait
unsigned long start = 0;
unsigned long now = 0;
unsigned long elapsed = 0;
// pov
unsigned char pos = 0;
unsigned char i = 0;
// led
#define TIMER_US 100                       // ScanRate (Duration of one LED period) 100mS = uS 100000                        
//unsigned long frames = 0;                 // ++ on every 'frame' of the LED bar
volatile bool LSTATE[8];                  // Desired state for each LED (can use 0 / 1 or LOW / HIGH)
volatile int LDRAW = 0;                   // Which LED are we 'drawing' right now?
//Standard Millis timers
//const long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
  // LED 6,7,8,9,10,11,12,13
  for (led=0; led<NUMBER_OF_LEDS; led++) {
    pinMode(leds[led], OUTPUT);
  }
  // led
  Timer1.initialize(TIMER_US);                  // Initialise timer 1
  Timer1.attachInterrupt( timerIsr );           // attach the ISR routine here
}

// --------------------------
// timerIsr() 1x milli second interrupt ISR()
// Called every time the hardware timer 1 times out.
// --------------------------
void timerIsr()
{
    noInterrupts();                       // temporarilly disable interrupts
    digitalWrite(leds[LDRAW], LOW);   // turn the current LED off
     LDRAW++;                              // move to the next..  
    if (LDRAW >= NUMBER_OF_LEDS){                 // reset to zero if necessary
      LDRAW = 0;
      //frames++;
      LSTATE[7] = LOW;
    }
    digitalWrite( leds[LDRAW], LSTATE[LDRAW]);   // set new current LED state
    interrupts();                         // restart interrupts
}       // get out of the ISR ASAP

void loop(){
  pov();
}

// !!notice!! mydelay can not user inside interrput.
void myDelay(unsigned long ms) {              // ms: duration
  // start: timestamp
  start = millis();           
  for (;;) {
    // now: timestamp
    now = millis();
    // elapsed: duration
    elapsed = now - start;
    if (elapsed >= ms)
      return;
  }
}

// led
//-----------------------------
//----------- common
// all off
void led_off() {
  byte bitmap_led_off[] = {
  0b00000000  
  };
  led_flash_by_order_arry(bitmap_led_off, sizeof(bitmap_led_off)/sizeof(byte),400);
}
// 指定されている配列のみHIGHにして、あとはLOWにする
void led_flash_by_order_arry(byte *array_order, int bitmap_size, unsigned long ms) {

    // first byte big array
    for(i=0; i<bitmap_size; i++){

          start = millis();
          for(;;) {
              now = millis();
            for(led=0;led<NUMBER_OF_LEDS;led++) {      
              LSTATE[led] = (array_order[i]>>led)&0b00000001 ? 1 : 0;
            }
          // check system timer
          elapsed = now - start;
          if (elapsed >= ms)
            break;

          }
      
  }  
}

void pov(){
  // pov
  byte bitmap_pov[] = {
0b00000000,
0b11111110,
0b00010000,
0b00010010,
0b00010100,
0b00000010,
0b00000100,
0b00000000,
0b00010000,
0b00010000,
0b10010000,
0b10000000,
0b01000000,
0b00111110,
0b00000000
  };
  led_flash_by_order_arry(bitmap_pov, sizeof(bitmap_pov)/sizeof(byte),5);
}


来年は・・

もっと体力つけたいです。