Skip to main content

GR-COTTON Special Project: 8-Unit LED Stick

Overview

This project introduces how to activate an LED stick lined with multiple lights using the GR-COTTON board.  

cotton-sp-prepare-serial-led-lights

Preparation

The program requires a GR-COTTON board, a USB cable (Micro B type), and an LED stick.
You will need to connect a pin socket to GR-COTTON. The jumper wire should be soldered to the LED stick. Connect the three LED signals (GND, DIN, 5VDC) as follows:

*GND – [-]
*DIN – [3]
*5VDC – [+]

The LED stick and the jumper wire can be purchased from the Akizuki Denshi website.

cotton-sp-prepare-serial-led-connect
cotton-sp-prepare-serial-led

Make sure the white jumper on the reverse side of GR-COTTON is moved to the “3V3 USB” side. If it is set to the BATT side, remove and reinsert it into the USB side.

cotton-sp-prepare2

Depressing the Button Switch to Activate a Variety of LED Patterns

The LED stick uses unique signals to create light patterns. Although the sample is a rather long sketch, the basic function of activating an LED pattern is shown below.

・void sendLedData(uint8_t red, uint8_t green, uint8_t blue)

One set of RGB data is sent. The range of values is from 0 - 255; the larger the value, the brighter the color. Repeat this process to create various LED patterns.

・void sendLedBuf(uint8_t* red, uint8_t* green, uint8_t* blue, uint8_t num);

RGB data is sent based on the number of units indicated in num. Determine the array variable for each RGB set in advance, and include the number of patterns.


#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();
}