硬件


Shell Lab L2 是USB串口控制的可编程LED灯带控制器

产品特点:

● 支持WS2812灯源芯片,5V供电
● 灯源数量可根据实际点数设置
● 信号灯模式,整条灯带单一颜色处理,可设置颜色、闪烁频率,指令简单
● 红绿蓝三色均可独立调节,范围0~255
● 集成闪烁效果(频率可调,0.1~20Hz,设置为0时为静态不闪烁)
● 寻址模式,单个灯源芯片可指定颜色,指令较为复杂
● 串口交互式控制,开放式通讯协议,自带命令帮助
● 不限制编程语言(推荐Python)
● 提供配套上位机“测试台软件”,自带众多示例代码
● 用pip安装mcush库(支持windows/linux/mac),编写python脚本

应用场景:

● 产品原型设计(用Python快速验证你的创意,收集用户反馈)
● 产品、软件循环测试出现异常时报警提示(可配合Shell Lab测试台软件)
● 产品生产线项目测试结果提示,如绿色正常通过,红灯故障失败并报警
● 实验进度状态提示
● 看板系统状态提示
● 物流仓储管理,货物定位提示
● ROS机器人信息提示
● 互动式游戏设计
● 教学实验设计
● 户外无人值守场景,自动信息提示
● 工控设备系统集成
● 艺术创作
● DIY玩具
● 广告招牌

工作模式:

● 信号灯模式(所有灯使用同一个颜色,指定颜色频率后自动渐变式闪烁)
● 寻址模式(静态设置,每个灯芯可寻址改颜色)

支持定制:

● 定制PCB和外壳,适应不同场景
● 定制固件,实现特定场景下的工作模式,适合作为独立的灯光模块系统集成
● 改用蓝牙转串口模块,方便手机无线控制
● RS232接口的控制器

● 多路并行灯带控制器

注意事项:

● 信号灯模式下的工作原理控制方式与Shell Lab L1信号灯基本一致,可方便替换
● USB供电能力有限,若灯带长度过长功耗过大,请自行增加外部5V供电(建议在灯带末端加电)

软件

串口通讯常见问题
C语言编程常见问题

串口指令:

1、信号灯模式控制
=>strap --help
usage: strap [-l length] [-c RGB_color] [-r red_color] [-g green_color] [-b blue_color] [-f freq]
options:
 -l/--length     led number
 -c/--color      RRGGBB format
 -r/--red        red value
 -g/--green      green value
 -b/--blue       blue value
 -f/--freq       0~20 Hz(default 1)
=> 

示例:

上电复位后先指定灯带长度,输入命令:
=>strap -l 30   (假设共30个灯源芯片)
=> 
然后发送颜色
(常用的基本色):
黑色: 0x000000
红色: 0xFF0000
绿色: 0x00FF00
蓝色: 0x0000FF
黄色: 0xFFFF00
青色: 0x00FFFF
紫色: 0xFF00FF
白色: 0xFFFFFF

红灯闪烁(默认1Hz):
=>strap -c 0xFF0000
=> 
黄色2Hz:
=>strap -c 0xFF00 -f 2
=> 
蓝色0.5Hz:
=>strap -c 0xFF -f 0.5
=> 
黄色0.1Hz:
=>strap -c 0xFFFF00 -f 0.1
=> 
紫色10Hz:
=>strap -c 0xFF00FF -f 10
=> 
青色不闪烁:
=>strap -c 0x00FFFF -f 0
=> 
单独设置红色分量64:
=>strap -r 64
=> 
单独设置绿色分量0x80:
=>strap -g 0x80
=> 
单独设置蓝色分量200:
=>strap -b 200
=> 
查看当前颜色频率设置:
=>strap
length: 30
color: 0x000000
freq: 1.0
=> 
2、寻址模式:
=>ws2812 --help
usage: ws2812 [-l length] [-G group] [--glist_file] [-L file] [-D] [-w] [-g] 
[-o offset] [-p pin] [-I] [-f] [-b] [-F] data options: -l/--length number of groups -G/--group number of pixels per group --glist_file /c/glist -L/--load load data file -D/--deinit deinit -w/--write write -g/--grb GRB instead of RGB -o/--offset data offset -p/--pin default 0.0 -I/--init init -f/--forward push forward -b/--backward push backward -F/--fill fill pattern data data to be written =>

示例(标准模式):

使用前必须先关闭信号灯模式(两者会冲突),设置长度为零即可,然后指定长度初始化:
(注:由于芯片内存容量的限制,能控制的点数为300)
=>strap -l 0
=>ws2812 -l30 -I
=>
此时已经为所有灯初始化了缓存,并设为黑色,但是未同步到灯带,需要刷新一下:
=>ws2812 -w
=>
将第#3~5号灯分别填充红、绿、蓝色,并同步刷新:
=>ws2812 -w -o3 0xff0000 0xff00 0xff
=>
将第#10~20号灯全部填充紫色,并同步刷新:
=>ws2812 -w -o10 -l11 -F 0xff00ff
=>
将整体灯带向前移动一位,#0号灯用蓝色填充,并同步刷新:
=>ws2812 -w -f 0xff
=>
将整体灯带向后移动一位,#29号灯用绿色填充,并同步刷新:
=>ws2812 -w -b 0xff00
=>
将前半段灯带向后移动一位,#29号灯用绿色填充,不刷新。
将后半段灯带向前移动一位,#0号灯用绿色填充,一起刷新:
=>ws2812 -l15 -o29 -b 0xff00 
=>ws2812 -w -l15 -f 0xff00
=>
如果先将整个灯带样式按0xRR,0xGG,0xBB三字节顺序写入文件系统(需要脚本工具配合),
后续可以直接加载文件,快速应用,适合加载预存的样式、图片等。
=>ws2812 -w -L imgfile
=>

示例(分组模式):

将多个连续的灯合并成组,每组共享同一个内存颜色,同样的内存可以控制更多的灯,但是刷新灯带需要更多的时间。
30个灯每3个一组共10组,初始化:
=>ws2812 -l10 -G3 -I
=>
红/绿交替填充整个灯带:
=>ws2812 -w -f 0xff0000 0xff
=>

示例(可变分组长度):

实际应用中,由于装配的原因,各个分组长度不同才会有更好的展示效果。
这时需要用文件定义实际分组长度,用脚本工具写入控制器的文件系统。
如已经写入文件/c/glist,内容为二进制0x03,0x05,0x0A...,对应相应分组的长度,然后初始化:
=>ws2812 --glist_file -I
=>

Python封装:

安装:pip3 install mcush
class ShellLabStrip(mcush.ShellLab.ShellLab):
    def strap(self, color=None, red=None, green=None, blue=None, freq=None, count=None):
        # 底层的串口命令封装

    def color(self, c, freq=None, count=None):
        # 设置颜色,颜色,闪烁计数
    
    def reset(self, freq=1):
        # 模式复位

class ShellLabStaticStrip(mcush.ShellLab.ShellLabStrip):
    def color( self, c, brightness=None ):
        # 设置颜色,亮度

    def brightness( self, b ):
        # 调整亮度

class LEDS(mcush.Ws2812):
    def __init__( self, controller, length=None, group_length=None, swap_rg=None, pin=None ):
        # 初始化

    def write( self, mem, offset=0, push=None, fill=None, length=None ):
        # 写颜色/样式

    def pushf( self, mem, offset=None, length=None ):
        # 正向推送颜色/样式

    def pushb( self, mem, offset=None, length=None ):
        # 反向推送颜色/样式

    def fill( self, mem, offset=None, length=None ):
        # 填充颜色/样式

示例:

import mcush
from mcush.linkong.ShellLab import ShellLabStrip
lamp = ShellLabStrip('COM10', length=30)  # 填入对应的串口号,长度
lamp.color('red', freq=2)  # 设置红色快闪

下载

Shell Lab 测试台软件


CH341虚拟串口驱动(Windows)


应用

信号灯模式闪烁效果

多重颜色闪烁效果

长灯带

推送指令

推送指令(快速)

推送指令(32*8=256灯,彩虹流水灯)




配置成上电RGBCMY颜色循环 下载
# this script runs in ShellLab Testbench Application
strap_length=30
freq = 0.2  # hz
delay_ms = int(1000/freq)  # ms

fcfs = Utils.FCFS()
fcfs.appendFile("rgbcmy", '''\
s -c 0xFF0000
delay {delay_ms}
s -c 0x00FF00
delay {delay_ms}
s -c 0x0000FF
delay {delay_ms}
s -c 0x00FFFF
delay {delay_ms}
s -c 0xFF00FF
delay {delay_ms}
s -c 0xFFFF00
delay {delay_ms}
load /c/rgbcmy
'''.format(delay_ms=delay_ms))

fcfs.appendFile("init", '''\
delay
s -l {strap_length} -f {freq}
load /c/rgbcmy
'''.format(strap_length=strap_length, freq=freq))

s = ShellLabStrip(PORT)
s.fcfsFormat()
s.fcfsProgram(fcfs.generate())
s.port.write('reboot\n')
用上述代码定制爱心形状盒子的变色灯


配置成警灯下载
# half red, half blue, three blinks alternatively
strap_length = 30
delay_ms = 100

fcfs = Utils.FCFS()
fcfs.appendFile("flash", '''\
W -w 0xFF0000 0
delay {delay_ms}
W -w 0 0
delay {delay_ms}
W -w 0xFF0000 0
delay {delay_ms}
W -w 0 0
delay {delay_ms}
W -w 0xFF0000 0
delay {delay_ms}
W -w 0 0
delay {delay_ms}
W -w 0 0xFF
delay {delay_ms}
W -w 0 0
delay {delay_ms}
W -w 0 0xFF
delay {delay_ms}
W -w 0 0
delay {delay_ms}
W -w 0 0xFF
delay {delay_ms}
W -w 0 0
delay {delay_ms}
load /c/flash
'''.format(delay_ms=delay_ms))

fcfs.appendFile("init", '''\
W -I -G{half_length} -l2
load /c/flash
'''.format(half_length=int(strap_length/2)))

s = ShellLabStrip(PORT)
s.fcfsFormat()
s.fcfsProgram(fcfs.generate())
s.port.write('reboot\n')
运行效果


用C-API编译流水灯
#include < stdio.h >
#include "mcush_api.h"

#ifdef WIN32
const char device_name[] = "\\\\.\\COM14";
#else
const char device_name[] = "/dev/ttyUSB0";
#endif

int strap_length = 30;
int push_delay_ms = 50;
int steps = 3;
int colors[] = { 0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF, 0xFF00FF };

int main( int argc, char *argv[] )
{
    mcush_dev_t dev;
    char buf[512];
    int i;

    if( mcush_open( &dev, device_name, 9600 ) <= 0 )
    {
        printf("fail to open port\n");
        return 0;
    }

    if( mcush_connect( &dev ) <= 0 )
    {
        printf("fail to connect the device\n");
        return 0;
    }

    /* identify */
    if( mcush_scpi_idn( &dev, buf ) > 0 )
        printf( "%s", buf );

    /* init strip */
    sprintf( buf, "W -l %d -I", strap_length );
    mcush_write_command( &dev, buf );

    /* push colors again and again until Ctrl-C */
    while( 1 )
    {
        /* push colors */
        for( i=0; i<6; i++ )
        {
            sprintf( buf, "L -l%d -n%d W -w -f 0x%X", push_delay_ms, steps, colors[i] );
            mcush_write_command( &dev, buf );
        }
    }

    mcush_close( &dev );
    return 0;
}
运行效果


配置成命令启动的流水灯下载
# use this script to make L2 controller a simple
# "command triggered" waterfall LED strip
# after configured, send "load /c/run" command to start
# use ShellLab Testbench App to run this script
# download at www.linkongsoft.com/shell-lab/

strap_length = 30 # total length
delay_ms = 100  # movement delay in ms
steps = 10 # length of water bar
color = 0xFF0000  # red bar

fcfs = Utils.FCFS()
fcfs.appendFile("run", '''\
L -l{delay_ms} -n{steps} W -w -f {color}
L -l{delay_ms} -n{strap_length} W -w -f 0
'''.format(delay_ms=delay_ms, steps=steps, 
      color=color, strap_length=strap_length))

fcfs.appendFile("init", '''\
W -I -l{strap_length}
'''.format(strap_length=strap_length))

s = ShellLabStrip(PORT)
s.fcfsFormat()
s.fcfsProgram(fcfs.generate())
s.port.write('reboot\n')

# wait for reboot and test the effect
time.sleep(0.5)
s.disconnect()
s.connect()
s.writeCommand('load /c/run')
运行效果


配置成上电循环显示两幅图片(8x8) 下载
# this script runs in ShellLab Testbench Application
fcfs = Utils.FCFS()
for fname in ['heart', 'heart2']:
    img = cv2.imread("emblems/%s.png"% fname)
    img = cv2.cvtColor( img, cv2.COLOR_BGR2RGB )
    pixels = []
    img = img / 4.0
    img = img.astype('int8')
    for i in range(8):
        for j in range(8):
            p = img[i][j] if i & 0x01 else img[i][7-j]
            pixels.append( bytes(p) )
            logAdd( ('%d %d ->'%(i,j)) + str(p) )
    logAdd(pixels)
    fcfs.appendFile(fname, b''.join(pixels))

fcfs.appendFile('init', '''\
W -l64 -I
load /c/play
''')

fcfs.appendFile('play', '''\
W -w -L heart
delay 400
W -w -L heart2
delay 400
load /c/play
''')

s = ShellLab(PORT)
fcfs.setIntegerUID( s.getIntegerSerialNumber() )  # keep original one
s.fcfsFormat()
s.fcfsProgram(fcfs.generate())
s.reboot()
上述代码效果


连接树莓派控制

连接树莓派单步调试


连接海龟编辑器控制