dql2016 发表于 2021-7-12 19:37

RSL10-002GEVB照明控制节点设计

本帖最后由 dql2016 于 2021-7-12 19:37 编辑

<p>本次项目中有一个照明控制节点,用于演示通过在RGB灯泡内集成RSL10蓝牙模块进而通过微信小程序控制。在踩了前面无数坑之后,实现各个节点的功能就变得十分简单了,为了充分利用手头资源,照明控制节点中的RGB灯泡采用涂鸦智能推出的具有arduino uno v3接口的RGB扩展板,这样就可以直接插到同样具有&nbsp;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>&nbsp;RSL10-002GEVB实现的主要功能是:上电后向周围广播,等待中央设备连接,连接成功后,接收中央设备下发的控制指令,进行RGB灯光颜色的调整。SM726EB这个国产芯片网上搜索不到任何资料,最后还是在github上找到了一个应该是它同系列的芯片SM16716的驱动,稍加改造,没想到驱动成功了,使用两个GPIO即IO7、IO8&nbsp;模拟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 &gt;&gt;= 1)
{
    SM726EB_SendBit(v &amp; mask);
}
}

void SM726EB_Update(uint8_t duty_r, uint8_t duty_g, uint8_t duty_b)
{
if (sm726eb.pin_sel &lt; 99)
{
    bool should_enable = (duty_r | duty_g | duty_b);
    if (!sm726eb.enabled &amp;&amp; should_enable)
    {
      sm726eb.enabled = true;
      Sys_GPIO_Set_High(sm726eb.pin_sel);
      delay_us(1000);
      SM726EB_Init();
    }
    else if (sm726eb.enabled &amp;&amp; !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 &lt; 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 &lt; 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&lt;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>&nbsp;</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&amp;page=1" style="background:#eee;margin-bottom:10px;" width="750"></iframe><br />
总结:其实如前面的帖子所述,实现了微信小程序和RSL10之间的蓝牙数据双向收发,其它的几乎所有功能就是在这个的基础上的包装了。</p>

Jacktang 发表于 2021-7-12 21:13

<p>比较奇怪为什么RSL10-002GEVB板卡上面对应的IO并不支持PWM功能,和其他的单片机还是有所不同的</p>

<p>楼主的I2C接口控制RGB颜色效果还是可以的</p>

<p>&nbsp;</p>

dql2016 发表于 2021-7-13 07:58

Jacktang 发表于 2021-7-12 21:13
比较奇怪为什么RSL10-002GEVB板卡上面对应的IO并不支持PWM功能,和其他的单片机还是有所不同的

楼主的I2 ...

<p>RSL10管脚资源确实紧张</p>

w494143467 发表于 2021-7-13 09:08

<p>感觉还不错,着调光效果也好,弄个动态颜色变化就很炫了!</p>

dql2016 发表于 2021-7-13 09:50

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]
查看完整版本: RSL10-002GEVB照明控制节点设计