LED Tape Control

制御マイコン内蔵のLEDをコントロールしてみます。

今回は、秋月電子で販売している(SK6812使用マイコン内蔵フルカラーテープLED 1m 60LED IP20)をコントロールしてみます。購入はこちら(秋月電子のページへジャンプします)から。

これは、SK6812とRGB LEDが入ったものが60ケシリーズに接続されたLEDテープです。

SK6812データシート

ピンマップは次のようになります。

データ入力は1本のみです、下記のタイミングを見てわかる通り、HIGHの区間でHigh,Lowを認識します。

タイミングは次のようになります。

タイミングは次のようになります。

このスペックからLOGICをVERILOGで作成して、LEDを制御してみます。

LED Tape Control Verilog

reg [23:0] reg_rgb_led_tmp;

reg [15:0] rgb_counter_1bit;

reg [7:0] rgb_count_60;

reg [7:0] rgb_count_24;

reg [2:0] rgb_control;

reg [7:0] rgb_8bit;

reg [7:0] rgb_color_red;

reg [7:0] rgb_color_green;

reg [7:0] rgb_color_blue;

reg [3:0] rgb_color_seq;

reg reg_rgb_1bit;

reg reg_rgb_mode;

always @(posedge CLOCK_100MHZ)

begin

rgb_counter_1bit = rgb_counter_1bit + 1;

if (reg_rgb_mode) begin // set rgb mode

if (rgb_counter_1bit > 124) begin // 1 cycle

rgb_count_24 = rgb_count_24 + 1;

if (rgb_count_24 > 23) begin

rgb_count_24 = 0;

rgb_count_60 = rgb_count_60 + 1;

if (rgb_count_60 > 59) begin

rgb_count_60 = 0;

reg_rgb_mode = 0; // goto reset

case (rgb_color_seq)

4'h0:

begin

rgb_color_green = 0;

rgb_color_blue = 0;

rgb_color_red = rgb_color_red + 1;

if(rgb_color_red > 254) begin

rgb_color_seq = 1;

end

end

4'h1:

begin

rgb_color_green = 0;

rgb_color_blue = 0;

rgb_color_red = rgb_color_red - 1;

if(rgb_color_red < 1) begin

rgb_color_seq = 2;

end

end

4'h2:

begin

rgb_color_red = 0;

rgb_color_blue = 0;

rgb_color_green = rgb_color_green + 1;

if(rgb_color_green > 254) begin

rgb_color_seq = 3;

end

end

4'h3:

begin

rgb_color_red = 0;

rgb_color_blue = 0;

rgb_color_green = rgb_color_green - 1;

if(rgb_color_green < 1) begin

rgb_color_seq = 4;

end

end

4'h4:

begin

rgb_color_red = 0;

rgb_color_green = 0;

rgb_color_blue = rgb_color_blue + 1;

if(rgb_color_blue > 254) begin

rgb_color_seq = 5;

end

end

4'h5:

begin

rgb_color_red = 0;

rgb_color_green = 0;

rgb_color_blue = rgb_color_blue - 1;

if(rgb_color_blue < 1) begin

rgb_color_seq = 6;

end

end

4'h6:

begin

rgb_color_red = rgb_color_red + 1;

rgb_color_green = rgb_color_green + 1;

rgb_color_blue = 0;

if(rgb_color_red > 254) begin

rgb_color_seq = 7;

end

end

4'h7:

begin

rgb_color_red = rgb_color_red - 1;

rgb_color_green = rgb_color_green - 1;

rgb_color_blue = 0;

if(rgb_color_red < 1) begin

rgb_color_seq = 8;

end

end

4'h8:

begin

rgb_color_red = rgb_color_red + 1;

rgb_color_green = 0;

rgb_color_blue = rgb_color_blue + 1;

if(rgb_color_red > 254) begin

rgb_color_seq = 9;

end

end

4'h9:

begin

rgb_color_red = rgb_color_red - 1;

rgb_color_green = 0;

rgb_color_blue = rgb_color_blue -1;

if(rgb_color_red < 1) begin

rgb_color_seq = 4'ha;

end

end

4'ha:

begin

rgb_color_red = 0;

rgb_color_green = rgb_color_green + 1;

rgb_color_blue = rgb_color_blue + 1;

if(rgb_color_green > 254) begin

rgb_color_seq = 4'hb;

end

end

4'hb:

begin

rgb_color_red = 0;

rgb_color_green = rgb_color_green -1;

rgb_color_blue = rgb_color_blue -1;

if(rgb_color_green < 1) begin

rgb_color_seq = 4'hc;

end

end

4'hc:

begin

rgb_color_red = rgb_color_red + 1;

rgb_color_green = rgb_color_green + 1;

rgb_color_blue = rgb_color_blue + 1;

if(rgb_color_red > 254) begin

rgb_color_seq = 4'hd;

end

end

4'hd:

begin

rgb_color_red = rgb_color_red - 1;

rgb_color_green = rgb_color_green -1;

rgb_color_blue = rgb_color_blue -1;

if(rgb_color_red < 1) begin

rgb_color_seq = 4'he;

end

end

4'he:

begin

rgb_color_seq = 0;

end

4'hf:

begin

end

default: rgb_color_seq = 0;

endcase

reg_rgb_led_tmp[23:16] = rgb_color_green;

reg_rgb_led_tmp[15:8] = rgb_color_red;

reg_rgb_led_tmp[7:0] = rgb_color_blue;

end

end

reg_rgb_1bit = ( reg_rgb_led_tmp >> (23 - rgb_count_23) ) & 1;

if (reg_rgb_mode == 1) begin

RGB_LED_OUTPUT = 1;

end

rgb_counter_1bit = 0;

end

else if (rgb_counter_1bit == 80) begin

RGB_LED_OUTPUT = 0;

end

else if (rgb_counter_1bit == 34) begin

if (reg_rgb_1bit == 0) begin

RGB_LED_OUTPUT = 0;

end

end

end

else begin // reset mode

if (rgb_counter_1bit > 8000) begin

RGB_LED_OUTPUT = 1;

rgb_counter_1bit = 0;

reg_rgb_mode = 1;

end

end

end

実際に生成したロジックでタイミングを見てみます。


全体像は下記のようになります。ローになっているところはリセットのタイミングです。60x24出力したあとに80usecのロー区間を挿入します。

次のものはビットを出力しているところです。

カラー制御をSoftwareで実施する場合。

int color, r1,r2, g1,g2, b1,b2, r,g,b;

double d;

int cl_2[][3] = { {0,0,255}, {0,255,0}, {0,255,255}, {255,0,0}, {255,0,255}, {255,255,0}, {255,0,0}};

int cl_st_sp = 0;

d = d+0.0001;

if (d>1.0) {

d = 0;

cl_st_sp++;

if (cl_st_sp>6) cl_st_sp = 0;

if (cl_st_sp == 6) {

r1 = cl_2[cl_st_sp][0];

r2 = cl_2[0][0];

g1 = cl_2[cl_st_sp][1];

g2 = cl_2[0][1];

b1 = cl_2[cl_st_sp][2];

b2 = cl_2[0][2];

} else {

r1 = cl_2[cl_st_sp][0];

r2 = cl_2[cl_st_sp+1][0];

g1 = cl_2[cl_st_sp][1];

g2 = cl_2[cl_st_sp+1][1];

b1 = cl_2[cl_st_sp][2];

b2 = cl_2[cl_st_sp+1][2];

}

printf("[%d] r1=%3d,g1=%3d,b1=%3d -> r2=%3d,g2=%3d,b2=%3d\r\n", cl_st_sp, r1, g1, b1, r2,g2,b2);

}

r = (int)( (double)( r2 - r1 ) * d + (double)r1 );

g = (int)( (double)( g2 - g1 ) * d + (double)g1 );

b = (int)( (double)( b2 - b1 ) * d + (double)b1 );

color = (r<<16)+(g<<8)+b;

for (i=0;i<NUM_OF_LED_STRIP;i++) {

led_strip_pos_set(i, color);

}

led_strip_refresh();