LED Tape Control
制御マイコン内蔵のLEDをコントロールしてみます。
今回は、秋月電子で販売している(SK6812使用マイコン内蔵フルカラーテープLED 1m 60LED IP20)をコントロールしてみます。購入はこちら(秋月電子のページへジャンプします)から。
これは、SK6812とRGB LEDが入ったものが60ケシリーズに接続されたLEDテープです。
ピンマップは次のようになります。
データ入力は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();