W601溫溼度監測與郵件報警系統 — 源碼詳解(LED控制模塊)

LED控制模塊在整個項目中屬於最基礎也是最簡單的應用模塊,在本項目中可以通過網頁對板載的三個LED進行開關操作。本項目選用的LED軟件包爲SignalLed軟件包。但由於在本項目的第一個版本中LED的控制邏輯極爲簡單,只有開與關兩個操作,因此最終並沒有用到該軟件包,但後續的更新中很可能加入更多的LED元素,因此在本章節開頭還是會與大家介紹一下該軟件包。

目錄

SignalLed軟件包的使用

LED模塊源碼詳解

模塊結構體

模塊函數簡介

模塊函數詳解

led_module_init

led_write

json_create_device_status


SignalLed軟件包的使用

LED控制選用SignalLed軟件包,查看軟件包鏈接

在介紹該軟件包之前,我們先來思考一下,如果我有一個LED的工作邏輯:先亮500毫秒,再滅100毫秒,再亮200毫秒,再滅500ms,接着亮1000毫秒,最後滅2000毫秒。如此循環三次。我們應該怎麼編程?這個邏輯並不複雜,編程也比較方便。無非就是打開,延時,關閉,延時,打開,延時……然而,一旦我們要操作的LED數量增加,或者邏輯變得更加複雜的時候,一個個的開關操作,一行行的延時就會佔據大量的代碼空間,不僅不美觀,還會使代碼臃腫冗長,影響我們的心情。

//常規LED操作
for(int i=0;i<3;i++)
{
    LED_ON;
    delay_ms(500);
    LED_OFF;
    delay_ms(100);
    LED_ON;
    delay_ms(200);
    LED_OFF;
    delay_ms(500);
    LED_ON;
    delay_ms(1000);
    LED_OFF;
    delay_ms(2000);
}

SignalLed對LED的閃爍邏輯進行了抽象,使使用者無需關注過多的引腳電平操作,也無需編寫一行又一行的延時代碼,取而代之的,使一串簡單明瞭的字符串。接下來,我們用該軟件包實現上文的邏輯。

//SignalLed軟件包操作

led_set_mode(led0, 3, "500,100,200,500,1000,2000,"); //閃爍模式字符串以逗號結尾

僅僅需要一行代碼,即可實現上文十幾行代碼所實現的邏輯。該函數的第一個參數爲所要控制的led句柄,第二個參數爲循環次數,第三個參數爲閃爍模式,字符串中的數字即亮、滅的時間,單位毫秒,順序爲 “亮、滅、亮、滅……”。經過對比,相信該軟件包的魅力也已經呈現在大家眼前。當然,還需要強調一下,由於目前版本並沒有涉及到這種複雜的閃爍模式,所以並沒有使用該軟件包,若感興趣的朋友可以點擊上文的軟件包鏈接,裏面有非常詳細的教程文檔供大家參考!

LED模塊源碼詳解

LED模塊的源代碼位於 /W601_APP/module 文件夾下的 board_module.c 與 board_module.h 兩個源文件中。

模塊結構體

//LED 枚舉類型
typedef enum
{
    RED,
    GREEN,
    BLUE
} led_id_e;

//LED結構體
typedef struct
{
    uint8_t red_led_status;
    uint8_t green_led_status;
    uint8_t blue_led_status;
} board_device_t;

LED模塊包含一個區分具體哪一個LED的枚舉類型與一個LED結構體,由於板載紅、綠、藍三個LED,所以其枚舉也對應爲RED、GREEN、BLUE三個類型。而LED結構體也相對簡單,只有三個標誌變量,分別存儲每個LED所處的狀態。

模塊函數簡介

函數名 函數簡介

led_module_init

初始化LED模塊

led_write

控制LED開關

json_create_device_status

生成LED狀態json字符串

模塊函數詳解

led_module_init

該函數爲led模塊的初始化函數,函數體中主要實現了LED IO 的初始化,並且將LED結構體中的狀態復位(置爲關閉狀態)。

void led_module_init(void)
{
    rt_pin_mode(PIN_LED_R, PIN_MODE_OUTPUT);
    rt_pin_mode(PIN_LED_G, PIN_MODE_OUTPUT);
    rt_pin_mode(PIN_LED_B, PIN_MODE_OUTPUT);
    w601_board.blue_led_status = LED_OFF;
    w601_board.green_led_status = LED_OFF;
    w601_board.red_led_status = LED_OFF;
}

led_write

該函數實現了三個LED的狀態設置功能,同時也是對外的LED控制接口。通過函數體可以看到,只需傳入對應的枚舉值和亮滅狀態(LED_ON或LED_OFF)即可操作對應的燈與狀態。同時LED結構體會記錄更新後的LED狀態。

void led_write(led_id_e led, uint8_t status)
{
    switch (led)
    {
    case RED:
        rt_pin_write(PIN_LED_R, status);
        w601_board.red_led_status = status;
        break;
    case GREEN:
        rt_pin_write(PIN_LED_G, status);
        w601_board.green_led_status = status;
        break;
    case BLUE:
        rt_pin_write(PIN_LED_B, status);
        w601_board.blue_led_status = status;
        break;
    default:
        break;
    }
}

json_create_device_status

該函數會將三個LED的狀態從結構體中取出,並且生成一個LED狀態的json字符串,傳輸給網頁並在前端進行LED狀態顯示。

char *json_create_device_status(void)
{
    char *json_data = RT_NULL;
    cJSON *root = cJSON_CreateObject();

    if (w601_board.red_led_status == LED_ON)
    {
        cJSON_AddItemToObject(root, "redLedStatus", cJSON_CreateString("ON"));
    }
    else
    {
        cJSON_AddItemToObject(root, "redLedStatus", cJSON_CreateString("OFF"));
    }

    if (w601_board.green_led_status == LED_ON)
    {
        cJSON_AddItemToObject(root, "greenLedStatus", cJSON_CreateString("ON"));
    }
    else
    {
        cJSON_AddItemToObject(root, "greenLedStatus", cJSON_CreateString("OFF"));
    }

    if (w601_board.blue_led_status == LED_ON)
    {
        cJSON_AddItemToObject(root, "blueLedStatus", cJSON_CreateString("ON"));
    }
    else
    {
        cJSON_AddItemToObject(root, "blueLedStatus", cJSON_CreateString("OFF"));
    }
    json_data = cJSON_PrintUnformatted(root);
    cJSON_Delete(root);
    return json_data;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章