天天看點

樂鑫Esp32學習之旅 24 分享在 esp32 SDK實作冷暖光色溫RGB/HSV平滑調節的封裝,輕松內建到您的項目去。(附帶Demo)前言一、冷暖光的PWM關系;二、 RGB/HSV三、函數說明四、其他

  • 本系列部落格學習由非官方人員 半顆心髒 潛心所力所寫,僅僅做個人技術交流分享,不做任何商業用途。如有不對之處,請留言,本人及時更改。

1、 爬坑學習新旅程,虛拟機搭建esp32開發環境,列印 “Hellow World”。

2、 巧用eclipes編輯器,官方教程在在Windows下搭建esp32開發環境,列印 “Hellow World”。

3、 認識基本esp32的GPIO接口,開始點亮您的第一盞 LED和中斷回調實作按鍵功能 。

4、體會esp32的強大的定時器功能, 實作定時2s閃爍一盞LED燈。

5、接觸實踐esp32的pwm寬度脈沖功能, 實作呼吸效果閃爍一盞LED燈。

6、smartConfig和微信airKiss在esp32的實作,一鍵配網輕松快捷連接配接路由器。

7、利用GPIO中斷做一個按鍵的短按和長按的回調事件,再也無須擔心觸發源。

8、esp32上實作本地 UDP 用戶端和服務端角色,在區域網路内實作通訊。

9、esp32上實作本地 TCP 用戶端和服務端角色,可斷線重連原路傳回資料。

10、樂鑫esp32 SDK程式設計利用rmt驅動ws2812七彩燈,實作彩虹漸變效果。

11、入門 樂鑫esp-adf 音頻架構開發,esp32造一個藍牙耳機,實作切換歌曲,擷取歌曲資訊等功能。

12、開源一個微信公衆号airkiss配網esp32以及區域網路發現功能的工程,分享一個airkiss配網小工具。

13、esp32 内置 dns 伺服器,無需外網通路域名傳回指定網頁。

14、esp32 sdk程式設計實作門戶強制認證,連接配接esp32熱點之後,自動強制彈出指定的登入界面。

15、認識本地離線語音喚醒識别架構 esp-skainet ,實作較低成本的硬體語音本地識别控制。

16、學習本地語音喚醒離線識别架構 esp-skainet ,如何修改喚醒詞? 如何自定義指令詞?如何做意圖動作?

17、全網首發,樂鑫esp32 sdk直連京東微聯·小京魚 · IoT開放平台,實作叮咚音響語音智能控制。

18、入門京東微聯·小京魚的控制台H5開發,讀懂vue文法,做自己的控制頁面。

19、重磅開源,如何在微信小程式上ble藍牙配網esp32,blufi的那些事!

20、一篇好文,開發過程中編譯esp32固件太大,無法正常啟動?教你如何自定義分區表partitions.csv。

21、 esp32藍牙配網blufi的高度封裝,內建簡單、使用簡單、容易上手,提高開發效率!

22、讨論下程式員 “青春飯” 那些事,分享在esp32實作多種加密算法md5 |AES CBC-ECB| Sha1 | Sha256 等!

23、安信可 esp32-a1s 音頻開發闆移植最新 esp-adf 音頻架構,小試牛刀如何實作線上文字轉語音播放。

25、分享在 esp32 SDK實作冷暖光色溫平滑調節的封裝,輕松內建到您的項目去。

前言

     技術需要沉澱,很久沒更新esp32的博文了,下個月的

esp32-s2

就要量産了,據說這是一個全新的晶片。已經在樂鑫 tao寶店鋪預售了,我也預了一塊,先玩玩吧。後面再給大家寫些評論;

     最近一個月在忙 TB02 子產品的開發,包括使用文檔手冊,都已經差不多了,感覺泰淩的代碼 就是 很爛,一堆宏,學起來吃力,沒有C語言基礎是入門不了的;(純個人觀點)

     做了很多燈具接入各大雲平台開發,接觸的絕對多大數都是色溫調光什麼的。于是乎,這種外設是最常用的,是以,有必要給大家或自己以後的項目總結這樣的子產品,提高開發效率;

一、冷暖光的PWM關系;

     我們在買燈具時候,一般看我們的燈支援怎麼樣的調節,比如隻是單色,冷暖色,還是RGB七彩控制的。

    一般地,家庭也就單色和冷暖光為多,而 RGB 是那些舞台音樂場景為多。是以,智能家居的燈具涉及,以單色和冷暖光為多,以 冷暖光為例,那些燈具的色溫是怎麼定義的? PWM 又是如何輸出這樣的效果呢? 這裡,我一一為大家闡述:

2.1、色溫的定義

    任何一種屬性都有機關,比如溫度有攝氏度,而色溫的機關是 卡爾文 ,簡稱 K,下面一圖說明了:

    色溫數值越大,看到的效果越冷白;

    誤解:色溫越大,就越暖光;

樂鑫Esp32學習之旅 24 分享在 esp32 SDK實作冷暖光色溫RGB/HSV平滑調節的封裝,輕松內建到您的項目去。(附帶Demo)前言一、冷暖光的PWM關系;二、 RGB/HSV三、函數說明四、其他

    而我們常買的燈具又是如何産生這樣的效果呢? 聰明的開發者,采用冷白燈珠和暖光燈具各自産生的亮度不一樣,就有了以上的效果!下面是我平時開發中常用的2鐘燈珠類型,3.3v即可點亮;

樂鑫Esp32學習之旅 24 分享在 esp32 SDK實作冷暖光色溫RGB/HSV平滑調節的封裝,輕松內建到您的項目去。(附帶Demo)前言一、冷暖光的PWM關系;二、 RGB/HSV三、函數說明四、其他

2.2、PWM與指定的色溫亮度的計算

     既然有2個燈珠同時在亮,各自的亮度不同來調節色溫亮度,那麼我們好奇的是如何通過 pwm 産生這樣的關系呢?

     很多人也許會這樣說:色溫大小就是暖色燈珠的亮度明暗,而亮度大小就是冷白燈珠的亮度明暗,這樣的說話是錯誤的!

     對于 PWM 和 色溫亮度的計算的公式,部落客接觸到很多公式,這裡以樂鑫開源的為例,如下:

  • color_temperature :使用者預想的燈具的色溫數值,範圍[0,100]
  • brightness :使用者預想的燈具的亮度數值,範圍[0,100]
  • 計算過程如下,得到的

    cold_tmp

    PWM

    冷燈珠的占空比,

    warm_tmp

    PWM

    冷燈珠的占空比:
uint8_t warm_tmp = color_temperature * brightness / 100;
    uint8_t cold_tmp = (100 - color_temperature) * brightness / 100;
           

     看了上面的計算步驟,是否很簡單?我們可以假想一下:

  • 效果1 中性光 :

         入參

    color_temperature

    = 50 ,

    brightness

    = 100 ;

         代入公式後得到:

    warm_tmp

    :50 ,

    cold_tmp

    :50 ;
  • 效果2 最冷光 :

         入參

    color_temperature

    = 100 ,

    brightness

    = 100 ;

         代入公式後得到:

    warm_tmp

    :100 ,

    cold_tmp

    :0;
  • 效果3 最暖光 :

         入參

    color_temperature

    = 0,

    brightness

    = 100 ;

         代入公式後得到:

    warm_tmp

    :0,

    cold_tmp

    :100 ;
效果 預想的各路PWM輸出 以上公式算出來的PWM輸出 對比結果
中性光 2路一樣亮度的輸出

warm_tmp

:50 ,

cold_tmp

:50
符合
最冷光效果 冷燈珠100亮度,暖燈珠0亮度

warm_tmp

:100 ,

cold_tmp

:0
反了
最暖光效果 冷燈珠 0亮度,暖燈珠100亮度

warm_tmp

:0,

cold_tmp

:100
反了

     以上步驟,為啥結論是反了?因為上上圖可以看到:色溫數值越大表示越冷效果,意味着色溫越大,其暖燈珠的PWM高電平占空比越小! 那麼我們如何糾正這個錯誤呢?

樂鑫Esp32學習之旅 24 分享在 esp32 SDK實作冷暖光色溫RGB/HSV平滑調節的封裝,輕松內建到您的項目去。(附帶Demo)前言一、冷暖光的PWM關系;二、 RGB/HSV三、函數說明四、其他

     這不用我來說吧?把入參的

color_temperature

修改為即可:

color_temperature = 100 - color_temperature;
           

二、 RGB/HSV

    這個應該是最簡單的啦!部落客讀書的時候,經常接觸這樣的模型轉換,下面給大家貼貼轉換代碼把?

HSV模型轉RGB

static esp_err_t light_driver_hsv2rgb(uint16_t hue, uint8_t saturation, uint8_t value,
                                      uint8_t *red, uint8_t *green, uint8_t *blue)
{
    uint16_t hi = (hue / 60) % 6;
    uint16_t F = 100 * hue / 60 - 100 * hi;
    uint16_t P = value * (100 - saturation) / 100;
    uint16_t Q = value * (10000 - F * saturation) / 10000;
    uint16_t T = value * (10000 - saturation * (100 - F)) / 10000;

    switch (hi)
    {
    case 0:
        *red = value;
        *green = T;
        *blue = P;
        break;
    case 1:
        *red = Q;
        *green = value;
        *blue = P;
        break;
    case 2:
        *red = P;
        *green = value;
        *blue = T;
        break;
    case 3:
        *red = P;
        *green = Q;
        *blue = value;
        break;
    case 4:
        *red = T;
        *green = P;
        *blue = value;
        break;
    case 5:
        *red = value;
        *green = P;
        *blue = Q;
        break;
    default:
        return ESP_FAIL;
    }
    *red = *red * 255 / 100;
    *green = *green * 255 / 100;
    *blue = *blue * 255 / 100;
    return ESP_OK;
}
           

RGB模型轉 HSV

static void light_driver_rgb2hsv(uint16_t red, uint16_t green, uint16_t blue,
                                 uint16_t *h, uint8_t *s, uint8_t *v)
{
    double hue, saturation, value;
    double m_max = MAX(red, MAX(green, blue));
    double m_min = MIN(red, MIN(green, blue));
    double m_delta = m_max - m_min;

    value = m_max / 255.0;
    if (m_delta == 0)
    {
        hue = 0;
        saturation = 0;
    }
    else
    {
        saturation = m_delta / m_max;
        if (red == m_max)
        {
            hue = (green - blue) / m_delta;
        }
        else if (green == m_max)
        {
            hue = 2 + (blue - red) / m_delta;
        }
        else
        {
            hue = 4 + (red - green) / m_delta;
        }
        hue = hue * 60;
        if (hue < 0)
        {
            hue = hue + 360;
        }
    }
    *h = (int)(hue + 0.5);
    *s = (int)(saturation * 100 + 0.5);
    *v = (int)(value * 100 + 0.5);
}
           

三、函數說明

  • light_driver_set_hue(uint16_t hue); //設定HSV模型的H
  • light_driver_set_saturation(uint8_t saturation); //設定HSV模型的S
  • light_driver_set_value(uint8_t value); //設定HSV模型的V
  • light_driver_set_color_temperature(uint8_t color_temperature); //設定色溫
  • light_driver_set_brightness(uint8_t brightness); //設定倆亮度
  • light_driver_set_hsv(uint16_t hue, uint8_t saturation, uint8_t value); //設定HSV模型
  • light_driver_set_ctb(uint8_t color_temperature, uint8_t brightness); //設定色溫亮度
  • light_driver_set_switch(bool status); //設定 開關

四、其他

  • 一般地,不能同時調節 RGB 和 冷暖燈珠的;
  • 具體的使用參考我的demo吧,也歡迎大家留言:

    https://github.com/xuhongv/StudyInEsp32/tree/master/17_light_utils_pwm

另外,不要把我的部落格作為學習标準,我的隻是筆記,難有疏忽之處,如果有,請指出來,也歡迎留言哈!

  • 玩轉

    esp8266

    帶你飛、加群

    QQ

    群,不喜的朋友勿噴勿加:434878850
  • esp8266源代碼學習彙總(持續更新,歡迎star):https://github.com/xuhongv/StudyInEsp8266
  • esp32源代碼學習彙總(持續更新,歡迎star):https://github.com/xuhongv/StudyInEsp32
  • 關注下面微信公衆号二維碼,幹貨多多,第一時間推送!
樂鑫Esp32學習之旅 24 分享在 esp32 SDK實作冷暖光色溫RGB/HSV平滑調節的封裝,輕松內建到您的項目去。(附帶Demo)前言一、冷暖光的PWM關系;二、 RGB/HSV三、函數說明四、其他