RSL10-002GEVB照明控制节点设计
本帖最后由 dql2016 于 2021-7-12 19:37 编辑<p>本次项目中有一个照明控制节点,用于演示通过在RGB灯泡内集成RSL10蓝牙模块进而通过微信小程序控制。在踩了前面无数坑之后,实现各个节点的功能就变得十分简单了,为了充分利用手头资源,照明控制节点中的RGB灯泡采用涂鸦智能推出的具有arduino uno v3接口的RGB扩展板,这样就可以直接插到同样具有 arduino uno v3接口的RSL10-002GEVB开发板上,如下图所示:</p>
<p></p>
<p></p>
<p>涂鸦的照明开发板(PWM+I2C)可实现五路照明功能,带有暖光,冷白及 RGB 灯珠和相应的控制芯片。RGB 控制采用 SM726EB,DC-DC 降压型 I2C控制线性恒流调光芯片。冷白,暖白控制采用 SLM211A DC-DC 降压型 PWM 线性恒流调光控制芯片。原理图如下所示:</p>
<p></p>
<p>由于RSL10-002GEVB板卡上面对应的IO并不支持PWM功能,因此本次项目演示没有使用到冷白,暖白控制,使用了I2C接口控制RGB颜色。整个系统框图如下:</p>
<p></p>
<p> RSL10-002GEVB实现的主要功能是:上电后向周围广播,等待中央设备连接,连接成功后,接收中央设备下发的控制指令,进行RGB灯光颜色的调整。SM726EB这个国产芯片网上搜索不到任何资料,最后还是在github上找到了一个应该是它同系列的芯片SM16716的驱动,稍加改造,没想到驱动成功了,使用两个GPIO即IO7、IO8 模拟i2c驱动如下:</p>
<pre>
<code class="language-cpp">#define XLGT_03 3
void delay_us(uint32_t us)
{
uint32_t n=15;
while(n--);
}
void delay_ms(uint32_t ms)
{
delay_us(1000*ms);
}
#define D_LOG_SM726EB "SM726EB: "
struct SM726EB {
uint8_t pin_clk;
uint8_t pin_dat;
uint8_t pin_sel;
bool enabled;
} sm726eb;
void SM726EB_SendBit(uint8_t v)
{
if(v==0)
{
Sys_GPIO_Set_Low(sm726eb.pin_dat);
}
else
{
Sys_GPIO_Set_High(sm726eb.pin_dat);
}
delay_us(1);
Sys_GPIO_Set_High(sm726eb.pin_clk);
delay_us(1);
Sys_GPIO_Set_Low(sm726eb.pin_clk);
}
void SM726EB_SendByte(uint8_t v)
{
uint8_t mask;
for (mask = 0x80; mask; mask >>= 1)
{
SM726EB_SendBit(v & mask);
}
}
void SM726EB_Update(uint8_t duty_r, uint8_t duty_g, uint8_t duty_b)
{
if (sm726eb.pin_sel < 99)
{
bool should_enable = (duty_r | duty_g | duty_b);
if (!sm726eb.enabled && should_enable)
{
sm726eb.enabled = true;
Sys_GPIO_Set_High(sm726eb.pin_sel);
delay_us(1000);
SM726EB_Init();
}
else if (sm726eb.enabled && !should_enable)
{
sm726eb.enabled = false;
Sys_GPIO_Set_Low(sm726eb.pin_sel);
}
}
PRINTF("Update; rgb=%02x%02x%02x\n", duty_r, duty_g, duty_b);
SM726EB_SendBit(1);
SM726EB_SendByte(duty_r);
SM726EB_SendByte(duty_g);
SM726EB_SendByte(duty_b);
SM726EB_SendBit(0);
SM726EB_SendByte(0);
SM726EB_SendByte(0);
SM726EB_SendByte(0);
}
void SM726EB_Init(void)
{
for (uint32_t t_init = 0; t_init < 50; ++t_init) {
SM726EB_SendBit(0);
}
}
void Sm16716ModuleSelected(void)
{
sm726eb.pin_clk = 7;
sm726eb.pin_dat = 8;
sm726eb.pin_sel = 15;
Sys_DIO_Config(sm726eb.pin_clk, DIO_MODE_GPIO_OUT_0);
Sys_GPIO_Set_Low(sm726eb.pin_clk);
Sys_DIO_Config(sm726eb.pin_dat, DIO_MODE_GPIO_OUT_0);
Sys_GPIO_Set_Low(sm726eb.pin_dat);
if (sm726eb.pin_sel < 99)
{
Sys_DIO_Config(sm726eb.pin_sel, DIO_MODE_GPIO_OUT_0);
Sys_GPIO_Set_Low(sm726eb.pin_sel);
}
else
{
SM726EB_Init();
}
}</code></pre>
<p>成功驱动效果如下,可以任意控制RGB颜色显示:<br />
</p>
<p></p>
<p>RSL10-002GEVB端程序基于例程peripheral_server实现,在主循环中解析微信小程序下发的数据后驱动RGB即可。</p>
<pre>
<code class="language-cpp"> if (cs_env.rx_value_changed)
{
PRINTF("[%s:%d %s]==== get data from phone start_hdl:0x%04x ====\n",__FILE__,__LINE__,__FUNCTION__,cs_env.start_hdl);
for (int j=0;j<cs_env.rx_len;j++)
{
PRINTF("[%s:%d %s]==== get data from phone %d:0x%02x ====\n",__FILE__,__LINE__,__FUNCTION__,j,cs_env.rx_value);
}
r=cs_env.rx_value*10+cs_env.rx_value;
g=cs_env.rx_value*10+cs_env.rx_value;
b=cs_env.rx_value*10+cs_env.rx_value;
SM726EB_Update(r, g, b);
cs_env.rx_value_changed=false;
}</code></pre>
<p>RSL10-002GEVB端程序没有什么难度和新意,比较麻烦的是微信小程序的设计,由于是第一次接触微信小程序,很多概念都不熟悉,想搜索都不知道搜什么,微信小程序照明节点控制界面主要实现RGB拾色器,即用户选定一个颜色,及时的将它发送给RSL10-002GEVB端。</p>
<p></p>
<p>这里需要十分注意的是数据格式的问题,在微信小程序中我主要使用的是十六进制字符串:</p>
<pre>
<code class="language-javascript">// 显示取色器
toPick: function () {
this.setData({
pick: true
})
},
//取色结果回调
pickColor(e) {
let myrgb = e.detail.color;
console.log('选择的颜色:'+myrgb)//rgb(100,200,210)
//给蓝牙页面发送数据
event.emit('LightControlSendData2Device',myrgb);
this.setData({
rgb: myrgb
})
},</code></pre>
<p>在蓝牙数据收发控制界面将数据发送出去:</p>
<pre>
<code class="language-javascript"> //灯光控制页面发来的RGB数据
event.on('LightControlSendData2Device', this, function(data) {
//另外一个页面传过来的data是16进制字符串形式
console.log("要发送给蓝牙设备的数据:"+data);
var a=data;
var b = a.indexOf("(")
var c = a.indexOf(")")
var d = a.substring(c,b+1)//100,200,230
var e=d.substring(0,d.indexOf(","));
console.log("分词R:"+parseInt(e,10))
var f=d.substring(d.indexOf(",")+1,d.lastIndexOf(",")+1);
console.log("分词G:"+parseInt(f,10))
var g=d.substring(d.length,d.lastIndexOf(",")+1);
console.log("分词B:"+parseInt(g,10))
var myrgb=this.myStringToHex(parseInt(e,10).toString(16))+this.myStringToHex(parseInt(f,10).toString(16))+this.myStringToHex(parseInt(g,10).toString(16));
console.log("myrgb:"+myrgb)
//var buffer = new ArrayBuffer(5)
//var dataView = new Uint8Array(buffer)
var buffer=that.stringToBytes(myrgb);
wx.writeBLECharacteristicValue({
deviceId: app.globalData._deviceId,//蓝牙设备 id
serviceId: app.globalData._serviceId,//蓝牙特征值对应服务的 uuid
characteristicId: app.globalData._writeCharacteristicId,//蓝牙特征值的 uuid
value: buffer,//ArrayBuffer 蓝牙设备特征值对应的二进制值
success: function (res) {//接口调用成功的回调函数
console.log('发送成功')
},
fail: function(res) {//接口调用失败的回调函数
//发送蓝牙数据失败
console.log('发送失败')
}
}
)
})
},
</code></pre>
<p> </p>
<p>主界面有2个小按钮用于单独控制某个灯,一个灯泡图标按钮用于控制所有灯,在实际中可以模拟控制单路和多路的效果。</p>
<p>主界面如下:开启的效果:</p>
<p></p>
<p>最后来看看测试视频吧:</p>
<p><iframe allowfullscreen="true" frameborder="0" height="450" src="//player.bilibili.com/player.html?bvid=1Hb4y1k7BJ&page=1" style="background:#eee;margin-bottom:10px;" width="750"></iframe><br />
总结:其实如前面的帖子所述,实现了微信小程序和RSL10之间的蓝牙数据双向收发,其它的几乎所有功能就是在这个的基础上的包装了。</p>
<p>比较奇怪为什么RSL10-002GEVB板卡上面对应的IO并不支持PWM功能,和其他的单片机还是有所不同的</p>
<p>楼主的I2C接口控制RGB颜色效果还是可以的</p>
<p> </p>
Jacktang 发表于 2021-7-12 21:13
比较奇怪为什么RSL10-002GEVB板卡上面对应的IO并不支持PWM功能,和其他的单片机还是有所不同的
楼主的I2 ...
<p>RSL10管脚资源确实紧张</p>
<p>感觉还不错,着调光效果也好,弄个动态颜色变化就很炫了!</p>
w494143467 发表于 2021-7-13 09:08
感觉还不错,着调光效果也好,弄个动态颜色变化就很炫了!
<p>这个想法不错,adc接个模拟mic,内置dsp做fft算法,可玩性很高<img height="50" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/wanwan33.gif" width="58" /></p>
页:
[1]