ArduinoUNOとWS2812B(8個)でテーブルの値の通り光らせる。


x 割り込みを止めないと誤作動する
x NOP (ノップ?)やループでタイミングを取らずにダイレクト
x いちお、UNOの互換機である　水晶は、16Mが刺さっている

目的
ぞくに言う「テープLED」「NeoPixel」「5050」を光らせる
GPIOのテスト

創意工夫点
テーブルの値をロムに格納

構成
windows 10 20H2
Arduino
1.8.13(Windows Store 1.8.42.0)


![h_con99.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/5b4ae4d8-5a2a-de95-d859-5606548f154b.jpeg)


![o_con34.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/6ace4020-3b2b-e0ee-a1b1-d0284f5771c2.jpeg)


![o_con35.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/697929e3-a630-705b-2661-1175d78788b9.jpeg)



参考

https://qiita.com/kemako/items/04c32d0225b91e26f8f1



![o_con33.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/88a04426-6944-833e-69e6-bc5b19cf83f7.jpeg)




清書

```c++



char l[90]; //max30 led

//             12345678   12345678   12345678   12345678
int b8[8] = {0b10000000,0b01000000,0b00100000,0b00010000,
             0b00001000,0b00000100,0b00000010,0b00000001, };

const char train_x[16][3*8] PROGMEM = 
{//G0,R0,B0  G1,R1,B1  G2,R2,B2  G3,R3,B3  G4,R4,B4  G5,R5,B5  G6,R6,B6  G7,R7,B7
  { 2,32,32,  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, 32, 2,32,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //1
  { 0, 0, 0,  0, 0, 0, 32,32, 2,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //2
  { 0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32, 2,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //3
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32,32,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //4
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  2,32,32,  0, 0, 0,  0, 0, 0}, //5
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32, 2,32,  0, 0, 0}, //6
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32, 2}, //7
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32, 2,32,  0, 0, 0}, //8 
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  2,32,32,  0, 0, 0,  0, 0, 0}, //9
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32,32,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //10
  { 0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32, 2,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //11
  { 0, 0, 0,  0, 0, 0, 32,32, 2,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //12
  { 0, 0, 0, 32, 2,32,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //13
  { 2,32,32,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //14
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}  //15
};

//              76543210
#define on1   0b00100000
#define off1  0b00000000

// 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 
void bit_off1(){

  PORTB = on1; //1 0.16uS
  PORTB = on1; //2 0.33uS
  PORTB = off1; //3
  PORTB = off1; //4
  PORTB = off1; //5
  PORTB = off1; //6
  PORTB = off1; //7
  PORTB = off1; //8

  PORTB = off1; //1
  PORTB = off1; //2
  PORTB = off1; //3
  PORTB = off1; //4
  PORTB = off1; //5
  PORTB = off1; //6
  PORTB = off1; //7
  PORTB = off1; //8

}//bit_off1

// 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
void bit_on1(){

  PORTB = on1; //1
  PORTB = on1; //2
  PORTB = on1; //3
  PORTB = on1; //4
  PORTB = on1; //5
  PORTB = on1; //6
  PORTB = on1; //7
  PORTB = on1; //8

  PORTB = on1; //1
  PORTB = on1; //2
  PORTB = on1; //3
  PORTB = on1; //4
  PORTB = on1; //5
  PORTB = on1; //6
  PORTB = off1; //7 0.32uS
  PORTB = off1; //8 0.16uS

}//bit_on1

//RGB_LEDにデータをn回分送る
int ws_led(int num1)
{
  int on_off;

noInterrupts(); //割り込み禁止

  //num1で指定された分だけループする
  for(int ii=0;ii<num1;ii++){

    //8ビット分送る
    for(int jj=0;jj<8;jj++){

      on_off = l[ii] & b8[jj];

      if( on_off == 0 ){
        bit_off1(); //ビットが0
      } else {
        bit_on1(); //ビットが1 
      }//endif

    }//for 8bit

  }//for max30byt

interrupts(); //用が済んだらコンパイラさんにお知らせしましょう。

  return(0);
}//ws_led

void setup() {

  //GPIOの初期化
  pinMode(13, OUTPUT); 

}//setup

void loop() {

    //状態を1づつ進める
    for(int jj=0;jj<16;jj++){

      //1列分8個のデータをセット
      for(int ii=0;ii<(3*8);ii++){
        l[ii] = pgm_read_byte(&(train_x[jj][ii]));
      }//for ii

      //ws2812bへデータを送る
      ws_led(3*8);

      //0.2秒待つ
      delay(200);
    }//for jj

}//loop




```


改良前


```c++



char l[90]; //max30 led

void bit_on1();
void bit_off1();

//             12345678   12345678   12345678   12345678
int b8[8] = {0b10000000,0b01000000,0b00100000,0b00010000,
             0b00001000,0b00000100,0b00000010,0b00000001, };

int ws_led(int num1)
{
  int on_off;

noInterrupts(); //割り込み禁止

  for(int ii=0;ii<num1;ii++){

    //8ビット分送る
    for(int jj=0;jj<8;jj++){

      on_off = l[ii] & b8[jj];

      if( on_off == 0 ){
        bit_off1(); //ビットが0
      } else {
        bit_on1(); //ビットが1 
      }//endif

    }//for 8bit

  }//for max30byt

interrupts(); //用が済んだらコンパイラさんにお知らせしましょう。

  return(0);
}//ws_led

const char train_x[16][3*8] PROGMEM = 
{//G0,R0,B0  G1,R1,B1  G2,R2,B2  G3,R3,B3  G4,R4,B4  G5,R5,B5  G6,R6,B6  G7,R7,B7
  { 2,32,32,  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, 32, 2,32,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //1
  { 0, 0, 0,  0, 0, 0, 32,32, 2,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //2
  { 0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32, 2,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //3
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32,32,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //4
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  2,32,32,  0, 0, 0,  0, 0, 0}, //5
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32, 2,32,  0, 0, 0}, //6
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32, 2}, //7
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32, 2,32,  0, 0, 0}, //8 
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  2,32,32,  0, 0, 0,  0, 0, 0}, //9
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32,32,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //10
  { 0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32, 2,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //11
  { 0, 0, 0,  0, 0, 0, 32,32, 2,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //12
  { 0, 0, 0, 32, 2,32,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //13
  { 2,32,32,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //14
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}  //15
};

void setup() {

  randomSeed( micros() ); //乱数の初期化

  //pinMode(PA8, OUTPUT); 
  pinMode(13, OUTPUT); 


  while(1){

    //l[3*0+0] = 31;
    //l[3*0+1] = 32;
    //l[3*0+2] = 33;
    //
    //l[3*1+0] = 30;
    //l[3*1+1] = 10;
    //l[3*1+2] = 32;
    //
    //l[3*2+0] = 10;
    //l[3*2+1] = 10;
    //l[3*2+2] = 32;

    for(int jj=0;jj<16;jj++){
      for(int ii=0;ii<(3*8);ii++){
        l[ii] = pgm_read_byte(&(train_x[jj][ii]));
      }//for ii

      //ws2812bへデータを送る
      ws_led(3*8);

      //0.1秒待つ
      delay(200);
    }//for jj
  } //while

}//setup

void loop() {
}//loop

//              76543210
#define on1   0b00100000
#define off1  0b00000000

// 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 
void bit_off1(){

  PORTB = on1; //1 0.16uS
  PORTB = on1; //2 0.33uS
  PORTB = off1; //3
  PORTB = off1; //4
  PORTB = off1; //5
  PORTB = off1; //6
  PORTB = off1; //7
  PORTB = off1; //8

  PORTB = off1; //1
  PORTB = off1; //2
  PORTB = off1; //3
  PORTB = off1; //4
  PORTB = off1; //5
  PORTB = off1; //6
  PORTB = off1; //7
  PORTB = off1; //8

}

// 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
void bit_on1(){
  
  PORTB = on1; //1
  PORTB = on1; //2
  PORTB = on1; //3
  PORTB = on1; //4
  PORTB = on1; //5
  PORTB = on1; //6
  PORTB = on1; //7
  PORTB = on1; //8

  PORTB = on1; //1
  PORTB = on1; //2
  PORTB = on1; //3
  PORTB = on1; //4
  PORTB = on1; //5
  PORTB = on1; //6
  PORTB = off1; //7 0.32uS
  PORTB = off1; //8 0.16uS

}




```