概要
LEDが並んだスティックタイプのLEDアレイを動かします。
準備
GR-COTTON、USBケーブル(マイクロBタイプ)、LEDスティックの3つを準備します。
GR-COTTONにはピンソケットを取り付ける必要があります。LEDスティックにはジャンパーワイヤーを半田付けしてください。 LEDスティックの3本の信号(GND, DIN, 5VDC)を以下のようにつなげます。
- GND - 「-」
- DIN - 「3」
- 5VDC - 「+」
LEDスティックの購入については
ジャンパワイヤーの購入についてはこちら(秋月電子通商Web)
GR-COTTONの裏面にある白いジャンパーが3V3、USB側にします。BATT側にある場合は引き抜いて、USB側に差し込んでください。
LEDスティックは特殊な通信を使って光のパターンを作ります。サンプルは長いスケッチになっていますが、基本的にLEDにパターンを送るのは以下の関数を使うだけです。
- void sendLedData(uint8_t red, uint8_t green, uint8_t blue)
1個分のRGBデータを送ります。値の範囲は0~255で、大きいほど明るくなります。この処理を繰り返すことで多くのLEDにパターンが送られます。 - void sendLedBuf(uint8_t* red, uint8_t* green, uint8_t* blue, uint8_t num);
numで指定され個数分のRGBデータを送ります。あらかじめRGBそれぞれの配列変数を作り、その中に個数分のパターンを入れておきます。
#include <arduino.h>
#define DI() asm("di")
#define EI() asm("ei")
#define NOP() asm("nop")
#define TAPELED_PIN 3 //pin for LEDs WS2812B
#define TAPELED_NUM 8 // number of led
#define TAPELED_PINREG P1.BIT.bit6 // register for rapid access to pin
#define TAPELED_ON TAPELED_PINREG = 1
#define TAPELED_OFF TAPELED_PINREG = 0
// Wait routine to construct the signal for LEDs.
// Needed to transfer the signal during DI because tight timing.
#define TAPELED_ON_WAIT0 NOP();NOP();NOP();NOP();NOP();NOP();
#define TAPELED_OFF_WAIT0 NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();
#define TAPELED_ON_WAIT1 NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();
#define TAPELED_OFF_WAIT1 NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();
// COTTON LEDs
#define LED_R 22
#define LED_G 23
#define LED_B 24
void sendLedBuf(uint8_t* red, uint8_t* green, uint8_t* blue, uint8_t num);
void sendLedData(uint8_t red, uint8_t green, uint8_t blue);
uint8_t g_mode = 0;
void modeChange() {
g_mode++;
if (g_mode > 4) {
g_mode = 0;
}
}
// the setup routine runs once when you press reset:
void setup()
{
setPowerManagementMode(PM_STOP_MODE);
pinMode( TAPELED_PIN, OUTPUT );
pinMode(2, INPUT_PULLUP);
attachInterrupt(0, modeChange, FALLING);
}
// the loop routine runs over and over again forever:
void loop(){
while(g_mode == 4){
for (int i = 0; i < TAPELED_NUM; i++){ //
sendLedData(120, 30, 150);
}
delay(0xffffffff); // stop mode
}
while(g_mode == 0){ // loop
static uint8_t buf_r[TAPELED_NUM], buf_g[TAPELED_NUM], buf_b[TAPELED_NUM];
static uint8_t loopCount = 0;
for(int i = 0; i < TAPELED_NUM; i++){
buf_r[i] = 0;
buf_g[i] = 0;
buf_b[i] = 0;
}
buf_r[loopCount] = 10;
buf_g[loopCount] = 10;
buf_b[loopCount] = 10;
sendLedBuf(buf_r, buf_g, buf_b, TAPELED_NUM);
loopCount++;
if(loopCount == TAPELED_NUM) loopCount = 0;
delay(50);
}
while(g_mode == 1){ // gradation
static uint8_t buf_r[TAPELED_NUM], buf_g[TAPELED_NUM], buf_b[TAPELED_NUM];
static uint8_t loopCount = 0;
for (int i = 0; i < (TAPELED_NUM/2); i++){
uint8_t temp = (i+loopCount)%(TAPELED_NUM/2);
buf_r[temp] = 1 << i;
buf_g[temp] = 1 << i;
buf_b[temp] = 1 << i;
buf_r[TAPELED_NUM -temp-1] = 1 << i;
buf_g[TAPELED_NUM -temp-1] = 1 << i;
buf_b[TAPELED_NUM -temp-1] = 1 << i;
}
sendLedBuf(buf_r, buf_g, buf_b, TAPELED_NUM);
loopCount++;
if(loopCount == TAPELED_NUM) loopCount = 0;
delay(50);
}
while(g_mode == 2){ // random
uint8_t buf_LEDs[TAPELED_NUM][3];
for(int i = 0; i < TAPELED_NUM; i++) {
for (int j = 0; j < 3; j++) {
buf_LEDs[i][j] = random(0, 30);
}
}
for(int i = 0; i < TAPELED_NUM; i++){
sendLedData(buf_LEDs[i][0], buf_LEDs[i][1], buf_LEDs[i][2]);
}
delay(300);
}
while(g_mode == 3) { // standby
for (int i = 0; i < TAPELED_NUM; i++){
sendLedData(0, 0, 0);
}
delay(0xffffffff); // stop mode
}
}
void sendLedBuf(uint8_t* red, uint8_t* green, uint8_t* blue, uint8_t num){
for(int i = 0; i < num; i++){
sendLedData(*(red + i), *(green + i), *(blue + i));
}
}
void sendLedData(uint8_t red, uint8_t green, uint8_t blue){
DI();
if ( green & 0x80 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
if ( green & 0x40 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
if ( green & 0x20 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
if ( green & 0x10 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
if ( green & 0x08 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
if ( green & 0x04 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
if ( green & 0x02 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
if ( green & 0x01 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
// Red LED
if ( red & 0x80 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
if ( red & 0x40 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
if ( red & 0x20 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
if ( red & 0x10 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
if ( red & 0x08 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
if ( red & 0x04 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
if ( red & 0x02 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
if ( red & 0x01 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
// Blue LED
if ( blue & 0x80 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
if ( blue & 0x40 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
if ( blue & 0x20 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
if ( blue & 0x10 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
if ( blue & 0x08 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
if ( blue & 0x04 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
if ( blue & 0x02 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
if ( blue & 0x01 )
{ // on data send
TAPELED_ON;
TAPELED_ON_WAIT1;
TAPELED_OFF;
TAPELED_OFF_WAIT1;
}
else
{ // off data send
TAPELED_ON;
TAPELED_ON_WAIT0;
TAPELED_OFF;
TAPELED_OFF_WAIT0;
}
EI();
}