炫彩灯带

更新时间Invalid dateCreatingLiu

概况

本作品通过arduino和涂鸦联网模组配合,实现了将灯带接入智能家居

作品视频展示: https://www.bilibili.com/video/BV1rK4y1u7BZ/

物料清单

硬件 (4)软件 (1)
  • WBR3模组

    数量:1

    在涂鸦开发面板采购

  • Arduino MEGA 2560

    数量:1

    可以用其它arduino型号代替,不过需要修改一下pcb,同时串口可能不够用

  • 灯带

    数量:1

    淘宝搜索ws2812b即可

  • PCB板

    数量:1

    自己设计制作,在GitHub开源

步骤

本项目已经开源在GitHub,链接已编辑在B站视频简介处

在涂鸦控制台创建项目并配置

  1. 参考快速入门,新建项目。创建项目时选择炫彩灯带,选择自定义方案
  2. 功能点本项目选择开关、模式和亮度。模式保留白光、彩色和音乐。
  3. 设备面板可随意选择一款,或使用图形化界面设计自己的界面。
  4. 硬件开发页,选择“涂鸦标准模组MCU SDK开发”。然后选择一个模块。本项目选择了WBR3。
  5. 选择完成后,选择一个默认的固件,然后就可以下单购买了。
  6. 点击下面开发资料中的快速指南,下载得到一个根据配置生成的pdf。开发时部分参数可参考该pdf文件。
  7. 复制并保存项目PID,后续开发会用到。

硬件设计制作

本项目已经开源了PCB设计文件,可直接使用。

涂鸦的模组使用十分方便。只需接通电源,使用串口操作即可。

涂鸦的模块可使用两种模式配网,分别是MCU处理和模块自行处理。此处为了减轻Arduino程序开发工作量,选择了模块自行处理。

选择模块自行处理时需要注意在模块上连接一个LED和一个按键。按键拉低5秒以上可恢复出厂设置并重新配网,因此硬件需要设计上拉电阻。

模块除了一组串口用于操作,还预留了一个串口输出内部日志。该引脚可以不接,但本项目将其连接到了Arduino的一个串口,Arduino随后会将日志转发给上位机。

WS2812B灯带每颗灯珠满载功率0.2W,设计时还需要额外考虑线宽满足电流要求。

本项目使用Arduino MEGA 2560。开源的设计可直接插在Arduino MEGA 2560上。

准备库文件

涂鸦官方提供了用于Arduino的库文件。但该库开发还不够完整,为了实现需要的功能,需要做一些修改。

修改过的库已经开源

config.h

该文件是官方提供的配置文件。配置使用宏定义的方式进行。需要配置的选项需要都在这里进行。

在这里,我们做以下修改:

修改模块的节能模式为默认

/*  Distribution mode selection, only three choices, Anti-touch mode is recommende */
#define CONFIG_MODE     CONFIG_MODE_DEFAULT             //Default working mode
//#define CONFIG_MODE     CONFIG_MODE_LOWPOWER            //Safe mode (low power working mode)
//#define CONFIG_MODE CONFIG_MODE_SPECIAL // Anti-touch mode (special working mode)

修改配网模式为模块自处理

#define WIFI_CONTROL_SELF_MODE //配置为模块自处理
#define WF_STATE_KEY 11//设置LED指示灯引脚
#define WF_RESERT_KEY 2//设置配网按键引脚

src/TuyaWifi.cpp

该文件是库函数主要部分源代码。因库函数未开发完全,直接设置为模块自处理会导致报错,因此需要做一些修改

  1. 修改TuyaWifi::mcu_get_wifi_work_state函数如下
unsigned char TuyaWifi::mcu_get_wifi_work_state(void)
{
#ifndef WIFI_CONTROL_SELF_MODE
    return wifi_work_state;
#else
    return WIFI_SATE_UNKNOW;
#endif
}
  1. 修改TuyaWifi::mcu_reset_wifi函数如下
void TuyaWifi::mcu_reset_wifi(void)
{
#ifndef WIFI_CONTROL_SELF_MODE
    reset_wifi_flag = RESET_WIFI_ERROR;
    
    tuya_uart.wifi_uart_write_frame(WIFI_RESET_CMD, MCU_TX_VER, 0);
#endif
}

编写程序

程序已经开源

程序代码如下:

#include <FastLED.h>
#include <TuyaWifi.h>

//hardware define
#define OUT_PIN 34
#define LED_NUMS 50
#define MIC_PIN A10

//dpid define
#define DPID_SWITCH 20
#define DPID_MODE   21
#define DPID_LIGHT  22
#define DPID_COLOR  24

//serial define
#define TUYA_SERIAL Serial1
#define LOG_SERIAL  Serial2

//datapoint value define
#define STATE_ON    0x01
#define STATE_OFF   0x00
#define MODE_WHITE  0x00
#define MODE_COLOUR 0x01
#define MODE_MIC   0x02

unsigned char pid[] = {"g2kypenftkitli6z"};
unsigned char mcu_ver[] = {"1.0.0"};
unsigned int led_light = 8;
#define COLOR_NUMS 7
CRGB colors[] = {
  CRGB::Red,
  CRGB::Orange,
  CRGB::Yellow,
  CRGB::Green,
  CRGB::LightGreen,
  CRGB::Blue,
  CRGB::Purple
};

//dp define
unsigned char dp_array[][2] =
{
  {DPID_SWITCH, DP_TYPE_BOOL},
  {DPID_MODE,   DP_TYPE_ENUM},
  {DPID_LIGHT,  DP_TYPE_VALUE},
  {DPID_COLOR,  DP_TYPE_STRING},
};

TuyaWifi my_device(&TUYA_SERIAL);
CRGB leds[LED_NUMS];
unsigned char state = STATE_OFF;
unsigned char mode = MODE_WHITE;

unsigned char led_state = LOW;
unsigned long last_time = 0;
unsigned char led_color = 0;

void setLED(CRGB data) {
  for(int i = 0; i < LED_NUMS; i++){
    leds[i] = data;
  }
}

void setup() {


  Serial.begin(115200);
  TUYA_SERIAL.begin(115200);
  LOG_SERIAL.begin(115200);
  my_device.init(pid, mcu_ver);
  my_device.set_dp_cmd_total(dp_array, sizeof(dp_array) / 2);
  my_device.dp_process_func_register(dp_process);
  my_device.dp_update_all_func_register(dp_update_all);

  FastLED.addLeds<WS2812, OUT_PIN, GRB>(leds, LED_NUMS);
  FastLED.setBrightness(led_light);

  last_time = millis();
  unsigned char value[1] = {STATE_ON};
  dp_process(DPID_SWITCH, value, 1);
}

void loop() {
  my_device.uart_service();

  while(LOG_SERIAL.available()){
    Serial.write(LOG_SERIAL.read());
  }

  if(state){
    switch(mode){
      case MODE_COLOUR:
        if(millis() - last_time > 50){
          last_time = millis();
          for(int i = LED_NUMS - 1; i > 0; i--){
            leds[i] = leds[i - 1];
          }
          leds[0] = colors[led_color];
          led_color = (led_color + 1) % COLOR_NUMS;
          FastLED.show();
        }
      break;
      case MODE_MIC:
        unsigned int lightNum = (exp(analogRead(MIC_PIN) / 675.84) - 1) * 1.5 * LED_NUMS / 1.7;
        for(int i = 0; i < lightNum && i < LED_NUMS; i++){
            leds[i] = CRGB(min(255 * i / (0.8 * LED_NUMS), 255), max(255 * (1 - i / (0.8 * LED_NUMS)), 0), 0);
        }
        for(int i = lightNum; i < LED_NUMS; i++){
            leds[i] = CRGB(0, 0, 0);
        }
        FastLED.show();
      break;
    }
  }
}

/**
 * @description: DP download callback function.
 * @param {unsigned char} dpid
 * @param {const unsigned char} value
 * @param {unsigned short} length
 * @return {unsigned char}
 */
unsigned char dp_process(unsigned char dpid,const unsigned char value[], unsigned short length) {
  switch(dpid){
    case DPID_SWITCH:
      state = value[0];
      my_device.mcu_dp_update(DPID_SWITCH, state, 1);
      if(state == STATE_OFF){
        setLED(CRGB(0, 0, 0));
        FastLED.show();
      }
      else{
        if(mode == MODE_WHITE){
          setLED(CRGB(255, 255, 255));
          FastLED.show();
        }
      }
    break;
    case DPID_MODE:
      mode = value[0];
      my_device.mcu_dp_update(DPID_MODE, mode, 1);
      if(state){
        if(mode == MODE_WHITE){
          setLED(CRGB(255, 255, 255));
          FastLED.show();
        }
      }
    break;
    case DPID_LIGHT:
      led_light = value[3];
      my_device.mcu_dp_update(DPID_LIGHT, led_light, 4);
      FastLED.setBrightness(led_light);
      FastLED.show();
    break;
  }
}

/**
 * @description: Upload all DP status of the current device.
 * @param {*}
 * @return {*}
 */
void dp_update_all(void) {
  my_device.mcu_dp_update(DPID_SWITCH, state, 1);
  my_device.mcu_dp_update(DPID_MODE, mode, 1);
  my_device.mcu_dp_update(DPID_LIGHT, led_light, 4);
}

小结

涂鸦的模块功能强大,使用方便。只要是能想到的,都可以很方便地实现。本项目看起来实现了很强大的功能,但其实只完成了硬件实际操作灯带的逻辑。真正的物联网部分完全交由涂鸦模块完成,极大地提升了开发效率。

您正在浏览的内容为涂鸦开发者平台注册用户自主发布,版权归原作者所有,涂鸦开发者平台不拥有其著作权,亦不承担相应法律责任,涂鸦开发者平台不对该等内容作出不违反、不侵权的陈述与保证。您应知晓并了解您对于该等内容的复制、改编、转发传播等任何其他使用行为应当符合法律法规并应取得相关权利人的许可,您的该等行为所造成的全部相应后果(包括但不限于侵权、违约、受损、与第三方的纠纷等)均应由您个人承担。内容知识产权相关条款可查看涂鸦开发者平台用户协议。如果您发现有涉嫌侵权的内容,请立即通过平台上的联系方式联系平台进行举报并发送有关证据,一经查实,平台将立刻删除涉嫌侵权内容。

喜欢举报