幻彩灯环

更新时间Invalid date坏人

概况

本产品是在涂鸦lot平台开发,基于arduino UNO和涂鸦cbu模组,制作一款WIFI幻彩灯环。通过涂鸦智能App控制, 可实现ws2812的幻彩情景,音乐律动等功能。

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

物料清单

硬件 (3)软件 (1)
  • cbu模组

    数量:1

    CBU 是由杭州涂鸦信息技术有限公司开发的一款低功耗嵌入式 Wi-Fi 模组。它由一个高集成度的无线射频芯片 BK7231N 和少量外围器件构成,可以支持 AP 和 STA 双角色连接,并同时支持低功耗蓝牙连接。

  • arduino uno

    数量:1

    Arduino UNO 是一款非常适合单片机入门的开发板,采用AVR单片机ATmega328P作为主控制器,集成开发环境为Arduino IDE

  • ws2812

    数量:1

    ws2812灯

步骤

创建产品

1、在 涂鸦 IoT 平台上,参考 选品类创建产品 创建一款智能产品。 2、选择 照明 类目 光源 品类,自定义方案下的幻彩灯带。

功能定义

选择自己想要的功能

设备面板

可以使用公共面板,也可以自定义面板,根据自己开发能力即时间

硬件开发

选择MCU SDK开发,通用固件不用修改。

原理图

供电使用arduino开发板,首次配网需要把arduino第7引脚要拉低(长按配网按键),烧录程序时要长按图中烧录按键,最后要把图中短接点短接(因为这是个兼容的方案)。

代码

编译时要添加两个库 1、安装涂鸦库Tuya_WIFI_SDK 2、安装ws2812相关驱动库Adafruit NeoPixel

#include <TuyaWifi.h>
#include <SoftwareSerial.h>


// Simple demonstration on using an input device to trigger changes on your
// NeoPixels. Wire a momentary push button to connect from ground to a
// digital IO pin. When the button is pressed it will change to a new pixel
// animation. Initial state has all pixels off -- press the button once to
// start the first animation. As written, the button does not interrupt an
// animation in-progress, it works only when idle.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

// Digital IO pin connected to the button. This will be driven with a
// pull-up resistor so the switch pulls the pin to ground momentarily.
// On a high -> low transition the button press logic will execute.
#define BUTTON_PIN   2

#define PIXEL_PIN    6  // Digital IO pin connected to the NeoPixels.

#define PIXEL_COUNT 24  // Number of NeoPixels

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)

boolean oldState = HIGH;
int     mode     = 0;    // Currently-active animation mode, 0-9


TuyaWifi my_device;

unsigned char led_state = 0;
/* Connect network button pin */

int key_pin = 7;

//开关(可下发可上报)
//备注:
#define DPID_SWITCH_LED 20
//模式(可下发可上报)
//备注:
#define DPID_WORK_MODE 21
//亮度值(可下发可上报)
//备注:
#define DPID_BRIGHT_VALUE 22
//冷暖值(可下发可上报)
//备注:
#define DPID_TEMP_VALUE 23
//彩光(可下发可上报)
//备注:类型:字符;
//Value: 000011112222;
//0000:H(色度:0-360,0X0000-0X0168);
//1111:S (饱和:0-1000, 0X0000-0X03E8);
//2222:V (明度:0-1000,0X0000-0X03E8)
#define DPID_COLOUR_DATA 24
//场景(可下发可上报)
//备注:类型:字符; 
//Value: 0011223344445555666677778888;
//00:情景号;
//11:单元切换间隔时间(0-100);
//22:单元变化时间(0-100);
//33:单元变化模式(0静态1跳变2渐变);
//4444:H(色度:0-360,0X0000-0X0168);
//5555:S (饱和:0-1000, 0X0000-0X03E8);
//6666:V (明度:0-1000,0X0000-0X03E8);
//7777:白光亮度(0-1000);
//8888:色温值(0-1000);
//注:数字1-8的标号对应有多少单元就有多少组
#define DPID_SCENE_DATA 25
//倒计时剩余时间(可下发可上报)
//备注:
#define DPID_COUNTDOWN 26
//音乐灯(只下发)
//备注:类型:字符串;
//Value: 011112222333344445555;
//0:   变化方式,0表示直接输出,1表示渐变;
//1111:H(色度:0-360,0X0000-0X0168);
//2222:S (饱和:0-1000, 0X0000-0X03E8);
//3333:V (明度:0-1000,0X0000-0X03E8);
//4444:白光亮度(0-1000);
//5555:色温值(0-1000)
#define DPID_MUSIC_DATA 27
//调节(只下发)
//备注:类型:字符串 ;
//Value: 011112222333344445555  ;
//0:   变化方式,0表示直接输出,1表示渐变;
//1111:H(色度:0-360,0X0000-0X0168);
//2222:S (饱和:0-1000, 0X0000-0X03E8);
//3333:V (明度:0-1000,0X0000-0X03E8);
//4444:白光亮度(0-1000);
//5555:色温值(0-1000)
#define DPID_CONTROL_DATA 28
//入睡(可下发可上报)
//备注:灯光按设定的时间淡出直至熄灭
#define DPID_SLEEP_MODE 31
//唤醒(可下发可上报)
//备注:灯光按设定的时间逐渐淡入直至设定的亮度
#define DPID_WAKEUP_MODE 32
//断电记忆(可下发可上报)
//备注:通电后,灯亮起的状态
#define DPID_POWER_MEMORY 33
//勿扰模式(可下发可上报)
//备注:适用经常停电区域,开启通电勿扰,通过APP关灯需连续两次上电才会亮灯
//Value:ABCCDDEEFFGG
//A:版本,初始版本0x00;
//B:模式,0x00初始默认值、0x01恢复记忆值、0x02用户定制;
//CC:色相 H,0~360;
//DD:饱和度 S,0~1000;
//EE:明度 V,0~1000;
//FF:亮度,0~1000;
//GG:色温,0~1000;
#define DPID_DO_NOT_DISTURB 34
//麦克风音乐律动(可下发可上报)
//备注:类型:  字符串
//Value:  AABBCCDDEEFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNN
//AA  版本
//BB  0-关闭,1-打开
//CC  模式编号,自定义从201开始
//DD  变换方式:0 - 呼吸模式,1 -跳变模式 , 2 - 经典模式
//EE  变化速度
//FF  灵敏度
//GGGG  颜色1-色相饱和度
//HHHH  颜色2-色相饱和度
//......
//NNNN  颜色8-色相饱和度
#define DPID_MIC_MUSIC_DATA 42
//炫彩情景(可下发可上报)
//备注:专门用于幻彩灯带场景
//Value:ABCDEFGHIJJKLLM...
//A:版本号;
//B:情景模式编号;
//C:变化方式(0-静态、1-渐变、2跳变、3呼吸、4-闪烁、10-流水、11-彩虹)
//D:单元切换间隔时间(0-100);
//E:单元变化时间(0-100);
//FGH:设置项;
//I:亮度(亮度V:0~100);
//JJ:颜色1(色度H:0-360);
//K:饱和度1 (饱和度S:0-100);
//LL:颜色2(色度H:0-360);
//M:饱和度2(饱和度S:0~100);
//注:有多少个颜色单元就有多少组,最多支持20组;
//每个字母代表一个字节
#define DPID_DREAMLIGHT_SCENE_MODE 51
//炫彩本地音乐律动(可下发可上报)
//备注:专门用于幻彩灯带本地音乐
//Value:ABCDEFGHIJKKLMMN...
//A:版本号;
//B:本地麦克风开关(0-关、1-开);
//C:音乐模式编号;
//D:变化方式;
//E:变化速度(1-100);
//F:灵敏度(1-100);
//GHI:设置项;
//J:亮度(亮度V:0~100);
//KK:颜色1(色度H:0-360);
//L:饱和度1 (饱和度S:0-100);
//MM:颜色2(色度H:0-360);
//N:饱和度2(饱和度S:0~100);
//注:有多少个颜色单元就有多少组,最多支持8组;
//每字母代表一个字节
#define DPID_DREAMLIGHTMIC_MUSIC_DATA 52
//点数/长度设置(可下发可上报)
//备注:幻彩灯带裁剪之后重新设置长度
#define DPID_LIGHTPIXEL_NUMBER_SET 53



///* Current device DP values */
unsigned char dp_bool_value = 0;
long dp_value_value = 0;
unsigned char dp_enum_value = 0;
unsigned char dp_string_value[21] = {"0"};
uint16_t Hue=0; //HSV
uint8_t Sat=0;
uint8_t Val=0;
uint8_t scene_mode=0;
unsigned char hex[10] = {"0"};
//unsigned char dp_raw_value[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
//int dp_fault_value = 0x01;

/* Stores all DPs and their types. PS: array[][0]:dpid, array[][1]:dp type. 
 *                                     dp type(TuyaDefs.h) : DP_TYPE_RAW, DP_TYPE_BOOL, DP_TYPE_VALUE, DP_TYPE_STRING, DP_TYPE_ENUM, DP_TYPE_BITMAP
*/
unsigned char dp_array[][2] = {
  {DPID_SWITCH_LED, DP_TYPE_BOOL},
  {DPID_WORK_MODE, DP_TYPE_ENUM},
  {DPID_BRIGHT_VALUE, DP_TYPE_VALUE},
  {DPID_TEMP_VALUE, DP_TYPE_VALUE},
  {DPID_COLOUR_DATA, DP_TYPE_STRING},
  {DPID_SCENE_DATA, DP_TYPE_STRING},
  {DPID_COUNTDOWN, DP_TYPE_VALUE},
  {DPID_MUSIC_DATA, DP_TYPE_STRING},
  {DPID_CONTROL_DATA, DP_TYPE_STRING},
  {DPID_SLEEP_MODE, DP_TYPE_RAW},
  {DPID_WAKEUP_MODE, DP_TYPE_RAW},
  {DPID_POWER_MEMORY, DP_TYPE_RAW},
  {DPID_DO_NOT_DISTURB, DP_TYPE_BOOL},
  {DPID_MIC_MUSIC_DATA, DP_TYPE_STRING},
  {DPID_DREAMLIGHT_SCENE_MODE, DP_TYPE_RAW},
  {DPID_DREAMLIGHTMIC_MUSIC_DATA, DP_TYPE_RAW},
  {DPID_LIGHTPIXEL_NUMBER_SET, DP_TYPE_VALUE},
};

unsigned char pid[] = {"****************"};//*********处替换成涂鸦IoT平台自己创建的产品的PID
unsigned char mcu_ver[] = {"1.0.0"};

unsigned long last_time = 0;
SoftwareSerial DebugSerial(8,9);
void setup() {
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  strip.begin(); // Initialize NeoPixel strip object (REQUIRED)
  strip.show();  // Initialize all pixels to 'off'

DebugSerial.begin(9600);

  Serial.begin(9600);
 //Initialize led port, turn off led.
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
//Initialize networking keys.
  pinMode(key_pin, INPUT_PULLUP);

 //incoming all DPs and their types array, DP numbers
   //Enter the PID and MCU software version
    my_device.init(pid, mcu_ver);
    my_device.set_dp_cmd_total(dp_array, 17);
    //register DP download processing callback function
    my_device.dp_process_func_register(dp_process);
    //register upload all DP callback function
    my_device.dp_update_all_func_register(dp_update_all);

    last_time = millis();
  
}

void loop() {

  //Enter the connection network mode when Pin7 is pressed.
  if (digitalRead(key_pin) == LOW) {
    delay(80);
    if (digitalRead(key_pin) == LOW) {
      my_device.mcu_set_wifi_mode(SMART_CONFIG);

      
    }
  }
my_device.uart_service();


  /* LED blinks when network is being connected */
  if ((my_device.mcu_get_wifi_work_state() != WIFI_LOW_POWER) && (my_device.mcu_get_wifi_work_state() != WIFI_CONN_CLOUD) && (my_device.mcu_get_wifi_work_state() != WIFI_SATE_UNKNOW)) {
    if (millis()- last_time >= 500) {
      last_time = millis();

      if (led_state == LOW) {
        led_state = HIGH;
      } else {
        led_state = LOW;
      }
      digitalWrite(LED_BUILTIN, led_state);
    }
  }

  
  // Get current button state.
  boolean newState = digitalRead(BUTTON_PIN);

  // Check if state changed from high to low (button press).
  if((newState == LOW) && (oldState == HIGH)) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState = digitalRead(BUTTON_PIN);
    if(newState == LOW) {      // Yes, still low
      if(++mode > 8) mode = 0; // Advance to next mode, wrap around after #8
      switch(mode) {           // Start the new animation...
        case 0:
          colorWipe(strip.Color(  0,   0,   0), 50);    // Black/off
          break;
        case 1:
          colorWipe(strip.Color(255,   0,   0), 50);    // Red
          break;
        case 2:
        
         // colorWipe(strip.Color(  0, 255,   0), 50);    // Green
          break;
        case 3:
          colorWipe(strip.Color(  0,   0, 255), 50);    // Blue
          break;
        case 4:
          theaterChase(strip.Color(127, 127, 127), 50); // White
          break;
        case 5:
          theaterChase(strip.Color(127,   0,   0), 50); // Red
          break;
        case 6:
          theaterChase(strip.Color(  0,   0, 127), 50); // Blue
          break;
        case 7:
          rainbow(10);
          break;
          case 8:
          theaterChaseRainbow(50);
          break;
      }
    }
  }

  // Set the last-read button state to the old state.
  oldState = newState;
}

// Fill strip pixels one after another with a color. Strip is NOT cleared
// first; anything there will be covered pixel by pixel. Pass in color
// (as a single 'packed' 32-bit value, which you can get by calling
// strip.Color(red, green, blue) as shown in the loop() function above),
// and a delay time (in milliseconds) between pixels.
void colorWipe(uint32_t color, int wait) {
  for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
    strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
    strip.show();                          //  Update strip to match
    delay(wait);                           //  Pause for a moment
  }
}

// Theater-marquee-style chasing lights. Pass in a color (32-bit value,
// a la strip.Color(r,g,b) as mentioned above), and a delay time (in ms)
// between frames.
void theaterChase(uint32_t color, int wait) {
  for(int a=0; a<10; a++) {  // Repeat 10 times...
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      strip.clear();         //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in steps of 3...
      for(int c=b; c<strip.numPixels(); c += 3) {
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
      }
      strip.show(); // Update strip with new contents
      delay(wait);  // Pause for a moment
    }
  }
}

// Rainbow cycle along whole strip. Pass delay time (in ms) between frames.
void rainbow(int wait) {
  // Hue of first pixel runs 3 complete loops through the color wheel.
  // Color wheel has a range of 65536 but it's OK if we roll over, so
  // just count from 0 to 3*65536. Adding 256 to firstPixelHue each time
  // means we'll make 3*65536/256 = 768 passes through this outer loop:
  for(long firstPixelHue = 0; firstPixelHue < 3*65536; firstPixelHue += 256) {
    for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
      // Offset pixel hue by an amount to make one full revolution of the
      // color wheel (range of 65536) along the length of the strip
      // (strip.numPixels() steps):
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      // strip.ColorHSV() can take 1 or 3 arguments: a hue (0 to 65535) or
      // optionally add saturation and value (brightness) (each 0 to 255).
      // Here we're using just the single-argument hue variant. The result
      // is passed through strip.gamma32() to provide 'truer' colors
      // before assigning to each pixel:
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show(); // Update strip with new contents
    delay(wait);  // Pause for a moment
  }
}

// Rainbow-enhanced theater marquee. Pass delay time (in ms) between frames.
void theaterChaseRainbow(int wait) {
  int firstPixelHue = 0;     // First pixel starts at red (hue 0)
  for(int a=0; a<30; a++) {  // Repeat 30 times...
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      strip.clear();         //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in increments of 3...
      for(int c=b; c<strip.numPixels(); c += 3) {
        // hue of pixel 'c' is offset by an amount to make one full
        // revolution of the color wheel (range 65536) along the length
        // of the strip (strip.numPixels() steps):
        int      hue   = firstPixelHue + c * 65536L / strip.numPixels();
        uint32_t color = strip.gamma32(strip.ColorHSV(hue)); // hue -> RGB
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
      }
      strip.show();                // Update strip with new contents
      delay(wait);                 // Pause for a moment
      firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames
    }
  }
}


/**
 * @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_LED:
      dp_bool_value = my_device.mcu_get_dp_download_data(dpid, value, length); /* Get the value of the down DP command */
      if (dp_bool_value) {
        //Turn on
        colorfill (strip.Color(  50, 23,  107)); //上一次状态
      } else {
        //Turn off
        colorfill (strip.Color(  0, 0,   0));
      }
      //Status changes should be reported.
      my_device.mcu_dp_update(dpid, value, length);
    break;
    
    case DPID_WORK_MODE:
    colorfill (strip.Color( 255, 255,  0));
    dp_enum_value  = my_device.mcu_get_dp_download_data(dpid, value, length); /* Get the value of the down DP command */
      switch(dp_enum_value){
        case 0: // white mode
          colorfill (strip.Color(  255, 255,  255));
        break;
        case 1:// colour mode
          
        break;
        case 2: // scene mode
      
        break;
       case 3: // music mode
     

        break;

      }
      //Status changes should be reported.
      my_device.mcu_dp_update(dpid, value, length);
    break;
    
    case DPID_COUNTDOWN:  //倒计时
     colorfill (strip.Color( 255, 0,  0));
      my_device.mcu_dp_update(dpid, value, length);
    break;

    case DPID_MUSIC_DATA: //音乐律动   
     
    my_device.mcu_dp_update(dpid,value, length);

        colour_data_control(value, length);
        
    break;
    
     case DPID_DREAMLIGHT_SCENE_MODE: //炫彩情景
      my_device.mcu_dp_update(DPID_DREAMLIGHT_SCENE_MODE, value, length);
       uint8_t scene_mode = value[1];
    

     scene_mode=value[1];
    
     switch(scene_mode){
       case 0:
          colorWipe(strip.Color(  0,   0,   0), 50);    // Black/off电影
          break;
        case 1:
          colorWipe(strip.Color(255,   0,   0), 50);    // Red 约会
          break;
        case 2:
        
          colorWipe(strip.Color(  0, 255,   0), 50);    // Green 晚霞
          break;
        case 3:
          colorWipe(strip.Color(  0,   0, 255), 50);    // Blue 圣诞夜
          break;
        case 4:
          theaterChase(strip.Color(  50, 23,  107), 50); // 浪漫 
          break;
        case 5:
          theaterChase(strip.Color(127,   0,   0), 50); // Red 缤纷
          break;
        case 6:
          theaterChase(strip.Color(  0,   0, 127), 50); // Blue 动感
          break;
        case 7:
          rainbow(10); //梦幻
          break;
          case 8:
          theaterChaseRainbow(50);    //彩虹
          break;
             case 9:
          theaterChaseRainbow(100);    //流水
          break;
          
     }
  
      break;

      case DPID_LIGHTPIXEL_NUMBER_SET: //长度设置
      
      my_device.mcu_dp_update(dpid, value, length);
      break;
    default:break;
  }
  return SUCCESS;
}

/**
 * @description: Upload all DP status of the current device.
 * @param {*}
 * @return {*}
 */
void dp_update_all(void)
{
  my_device.mcu_dp_update(DPID_SWITCH_LED, led_state, 1);
}



//拓展
void colorfill(uint32_t color) {
 strip.fill(color,0,PIXEL_COUNT);
    strip.show();                          //  Update strip to match   
  
}





 void colour_data_control( const unsigned char value[], u16 length)
 {
   u8 string_data[13];
    u16 h, s, v;
    u8 r, g, b;
    u16 hue;
    u8 sat,val;

    u32 c=0;
  
    string_data[0] = value[0]; //渐变、直接输出
    string_data[1] = value[1];
    string_data[2] = value[2];
    string_data[3] = value[3];
    string_data[4] = value[4];
    string_data[5] = value[5];
    string_data[6] = value[6];
    string_data[7] = value[7];
    string_data[8] = value[8];
    string_data[9] = value[9];
    string_data[10] = value[10];
    string_data[11] = value[11];
    string_data[12] = value[12];
    
  
    h = __str2short(__asc2hex(string_data[1]), __asc2hex(string_data[2]), __asc2hex(string_data[3]), __asc2hex(string_data[4]));
    s = __str2short(__asc2hex(string_data[5]), __asc2hex(string_data[6]), __asc2hex(string_data[7]), __asc2hex(string_data[8]));
    v = __str2short(__asc2hex(string_data[9]), __asc2hex(string_data[10]), __asc2hex(string_data[11]), __asc2hex(string_data[12]));

    

   // if (v <= 10) {
  //       v = 0;
    // } else {
    //     v = color_val_lmt_get(v);
    // }
    
  //  hsv2rgb((float)h, (float)s / 1000.0, (float)v / 1000.0, &r , &g, &b);

    // c= r<<16|g<<8|b;
  hue=h*182;
  sat=s/4;
  val=v/4;
    c = strip.gamma32(strip.ColorHSV(hue,sat,val)); // hue -> RGB
    DebugSerial.println(hue);
    DebugSerial.println(sat);
    DebugSerial.println(val);
 
    
    strip.fill(c,0,PIXEL_COUNT);
    
    strip.show(); // Update strip with new contents

    //tuya_light_gamma_adjust(r, g, b, &mcu_default_color.red, &mcu_default_color.green, &mcu_default_color.blue);
  
    //printf("r=%d,g=%d,b=%d\r\n", mcu_default_color.red, mcu_default_color.green, mcu_default_color.blue);
    //rgb_init(mcu_default_color.red, mcu_default_color.green, mcu_default_color.blue);
 }

/**
 * @brief  str to short
 * @param[in] {a} Single Point
 * @param[in] {b} Single Point
 * @param[in] {c} Single Point
 * @param[in] {d} Single Point
 * @return Integrated value
 * @note   Null
 */
u32 __str2short(u32 a, u32 b, u32 c, u32 d)
{
    return (a << 12) | (b << 8) | (c << 4) | (d & 0xf);
}

/**
  * @brief ASCALL to Hex
  * @param[in] {asccode} 当前ASCALL值
  * @return Corresponding value
  * @retval None
  */
u8 __asc2hex(u8 asccode)
{
    u8 ret;
    
    if ('0' <= asccode && asccode <= '9')
        ret = asccode - '0';
    else if ('a' <= asccode && asccode <= 'f')
        ret = asccode - 'a' + 10;
    else if ('A' <= asccode && asccode <= 'F')
        ret = asccode - 'A' + 10;
    else
        ret = 0;
    
    return ret;
}

/**
  * @brief Normalized
  * @param[in] {dp_val} dp value
  * @return result
  * @retval None
  */
u16 color_val_lmt_get(u16 dp_val)
{
    u16 max = 255 * 100 / 100;
    u16 min = 255 * 1 / 100;
    
    return ((dp_val - 10) * (max - min) / (1000 - 10) + min);
}

/**
  * @brief hsv to rgb
  * @param[in] {h} tone
  * @param[in] {s} saturation
  * @param[in] {v} Lightness
  * @param[out] {color_r} red
  * @param[out] {color_g} green
  * @param[out] {color_b} blue
  * @retval None
  */
void hsv2rgb(float h, float s, float v, u8 *color_r, u8 *color_g, u8 *color_b)
{
    float h60, f;
    u32 h60f, hi;
  
    h60 = h / 60.0;
    h60f = h / 60;
  
    hi = ( signed int)h60f % 6;
    f = h60 - h60f;
  
    float p, q, t;
  
    p = v * (1 - s);
    q = v * (1 - f * s);
    t = v * (1 - (1 - f) * s);
  
    float r, g, b;
  
    r = g = b = 0;
    if (hi == 0) {
        r = v;          g = t;        b = p;
    } else if (hi == 1) {
        r = q;          g = v;        b = p;
    } else if (hi == 2) {
        r = p;          g = v;        b = t;
    } else if (hi == 3) {
        r = p;          g = q;        b = v;
    } else if (hi == 4) {
        r = t;          g = p;        b = v;
    } else if (hi == 5) {
        r = v;          g = p;        b = q;
    }
  
    DebugSerial.println(r);
    DebugSerial.println(g);
    DebugSerial.println(b);
    r = (r * (float)255);
    g = (g * (float)255);
    b = (b * (float)255);
  
    *color_r = r;
    *color_g = g;
    *color_b = b;
    
    // r *= 100;
    // g *= 100;
    // b *= 100;
  
    // *color_r = (r + 50) / 100;
    // *color_g = (g + 50) / 100;
    // *color_b = (b + 50) / 100;
}

PCB

云模组CBU下不铺铜,在天线部位挖空,可以有效减少 RF 干扰。

实物图

输出ws2812靠din传输信号

小结

此次在涂鸦 IoT 开发平台上第一次快速实现了硬件产品智能化。之前参加过几期,但是因为经验不足,都没成功,通过之前摸爬滚打的学习,这次我尝试了MCU开发,MCU是我熟悉的arduino。过程很煎熬但是成功了,高兴到起飞。还有成千上万款成熟的产品智能化解决方案可大大降低硬件开发成本,SoC 零代码开发我也尝试了,灵活选择,操作便捷。

不管是想 DIY 一款智能产品,还是想实现商业化量产,涂鸦都是物联网开发者最好的选择之一。

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

喜欢举报