紅外測溫槍,超進化!--智能溫度傳感器!基於 arduino 的智能測溫模塊


前言

之前用 arduino(arduino 開發制導) 做了一個傻了吧唧的 紅外測溫槍,后來又照着 Spirit 1 官方文檔成功做出來一個能讓設備和 Spirit 1 通訊的 調試用 demo,雖然 BUG 有億點點多,但是!好歹能用了!
( ੭ ˙ᗜ˙ )੭牛逼!!!,通訊解決了,服務器有了,那不得開始 搞事情!!!٩(๑>◡<๑)۶ 開始利用 Spirit 1 做一個能通過手機控制和查看的智能紅外測溫模塊。

硬件選擇

硬件與之前的 紅外測溫槍 完全一致,安信可 ESP32S 開發板+ GY906 (MLX90614ESF ) 紅外測溫傳感器。詳細介紹和引腳圖可以看之前紅外測溫槍的文檔。
在這里插入圖片描述

而 Spirit 1 的使用和介紹可以看我之前的 搭載着EdgerOS 的 Spirit 1 開箱超便宜的個人智能設備服務器!-- 邊緣計算機 Spirit 1 初體驗,也是淘寶就能搜到。

代碼講解

我自己移植了一個他們的 sddc 庫,在 Spirit 1 官方的 demo 的基礎上對 arduino 做了適配,接入了紅外測溫槍流程。
在這里插入圖片描述

通過 SDDC 協議接入 Spirit 1 部分

在 setup 函數中初始化 SDDC 協議,然后在 loop 函數運行 SDDC 協議主循環,

void setup() {
  byte mac[6];
  char *data;
  int ret;
  
  // 初始化打印串口
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  Serial.println();
  
  // 啟動紅外模塊
  mlx.begin();
  
  // 清除一下按鍵狀態機的狀態
  button.reset();
  
  // 創建按鍵掃描線程,長按 IO0 按鍵,松開后ESP32 將會進入 SmartConfig 模式
  sddc_printf("長按按鍵進入 Smartconfig...\n");
  button.attachLongPressStop(esp_io0_key_task);
  xTaskCreate(esp_tick_task, "button_tick", ESP_KEY_TASK_STACK_SIZE, NULL, ESP_KEY_TASK_PRIO, NULL);
  
  // 啟動 WiFi 並且連接網絡
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }

  // 獲取並打印 IP 地址
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("'ip :");
  Serial.print(WiFi.localIP());
  Serial.println("' to connect");   
  
  // 創建 SDDC 協議對象
  g_sddc = sddc_create(SDDC_CFG_PORT);
  
  // 設置事件響應函數
  sddc_set_on_message(g_sddc, iot_pi_on_message);                              // 設置接收消息請求時的回調函數
  sddc_set_on_message_ack(g_sddc, iot_pi_on_message_ack);                      // 設置接收消息確認時的回調函數
  sddc_set_on_message_lost(g_sddc, iot_pi_on_message_lost);                    // 設置丟失消息時的回調函數
  sddc_set_on_invite(g_sddc, iot_pi_on_invite);                                // 設置接受邀請請求時的回調函數
  sddc_set_on_invite_end(g_sddc, iot_pi_on_invite_end);                        // 設置發送邀請后的回調函數
  sddc_set_on_update(g_sddc, iot_pi_on_update);                                // 設置接收更新請求時的回調函數
  sddc_set_on_edgeros_lost(g_sddc, iot_pi_on_edgeros_lost);                    // 設置 EdgerOS 斷連時的回調函數

  // 設置設備密碼
#if SDDC_CFG_SECURITY_EN > 0                                                   // SDDC_CFG_SECURITY_EN 宏控制是否支持數據加密通信
    ret = sddc_set_token(g_sddc, "1234567890");
#endif 

  // 創建並設置 Report 報文數據
  data = iot_pi_report_data_create();
  sddc_return_if_fail(data);
  sddc_set_report_data(g_sddc, data, strlen(data));
  
  // 創建並設置 Invite 報文數據
  data = iot_pi_invite_data_create();
  sddc_return_if_fail(data);
  sddc_set_invite_data(g_sddc, data, strlen(data));
  
  // 獲取並打印網卡 mac 地址
  WiFi.macAddress(mac);
  sddc_printf("MAC addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
              mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]);
  // 使用網卡 mac 地址設置設備唯一標識 UID
  sddc_set_uid(g_sddc, mac);
}

void loop() {
  // 運行 SDDC 協議循環
    while (1) 
    {
        sddc_printf("SDDC running...\n");
        sddc_run(g_sddc);
        sddc_printf("SDDC quit!\n");
    }

    // 銷毀 SDDC 協議
    sddc_destroy(g_sddc);
}

配置設備信息

這部分代碼可以配置 WiFi 名字和 WiFi 密碼,按鍵引腳和按鍵狀態,並且配置設備在 Spirit 1 上顯示的信息
代碼如下(示例):

#include "Arduino.h"    
#include <OneButton.h>       
#include <WiFi.h>
#include <sddc.h>
#include <cJSON.h>
#include <Wire.h>
#include <Adafruit_MLX90614.h>

#define SDDC_CFG_PORT             680U             // SDDC 協議使用的端口號
#define PIN_INPUT 0                                // 選擇 IO0 進行控制
#define ESP_KEY_TASK_STACK_SIZE   4096
#define ESP_KEY_TASK_PRIO         25

static sddc_t *g_sddc;
static const char* ssid = "EOS-000045";            // WiFi 名
static const char* password = "1234567890";        // WiFi 密碼

OneButton button(PIN_INPUT, true);
Adafruit_MLX90614 mlx = Adafruit_MLX90614();

/*
 * 創建 REPORT 數據
 */
static char *iot_pi_report_data_create(void)
{
    cJSON *root;
    cJSON *report;
    char *str;

    root = cJSON_CreateObject();
    sddc_return_value_if_fail(root, NULL);

    report = cJSON_CreateObject();
    sddc_return_value_if_fail(report, NULL);

    cJSON_AddItemToObject(root, "report", report);
    cJSON_AddStringToObject(report, "name",   "紅外測溫模塊");
    cJSON_AddStringToObject(report, "type",   "device");
    cJSON_AddBoolToObject(report,   "excl",   SDDC_FALSE);
    cJSON_AddStringToObject(report, "desc",   "ESP32S");
    cJSON_AddStringToObject(report, "model",  "1");
    cJSON_AddStringToObject(report, "vendor", "靈感桌面");
    
    str = cJSON_Print(root);
    sddc_return_value_if_fail(str, NULL);
    sddc_printf("REPORT DATA: %s\n", str);
    cJSON_Delete(root);

    return str;
}
/*
 * 創建 INVITE 數據
 */
static char *iot_pi_invite_data_create(void)
{
    cJSON *root;
    cJSON *report;
    char *str;

    root = cJSON_CreateObject();
    sddc_return_value_if_fail(root, NULL);

    report = cJSON_CreateObject();
    sddc_return_value_if_fail(report, NULL);

    cJSON_AddItemToObject(root, "report", report);
    cJSON_AddStringToObject(report, "name",   "紅外測溫模塊");
    cJSON_AddStringToObject(report, "type",   "device");
    cJSON_AddBoolToObject(report,   "excl",   SDDC_FALSE);
    cJSON_AddStringToObject(report, "desc",   "ESP32S");
    cJSON_AddStringToObject(report, "model",  "1");
    cJSON_AddStringToObject(report, "vendor", "靈感桌面");

    str = cJSON_Print(root);
    sddc_return_value_if_fail(str, NULL);

    sddc_printf("INVITE DATA: %s\n", str);
    
    cJSON_Delete(root);

    return str;
}

數據獲取與發送流程

iot_pi_on_message() 是在 setup 設置的接收消息請求時的回調函數,設備收到 Spirit 1 發過來的 message 后就會進入這個函數,我們就在這寫我們需要的處理流程。

/*
 * 事件響應函數
 */
static sddc_bool_t iot_pi_on_message(sddc_t *sddc, const uint8_t *uid, const char *message, size_t len)
{
    cJSON *root = cJSON_Parse(message);
    cJSON *item;
    cJSON *temperature;
    char *str;
    char *msg;

    sddc_return_value_if_fail(root, SDDC_TRUE);

    str = cJSON_Print(root);
    sddc_goto_error_if_fail(str);

    sddc_printf("iot_pi_on_message: %s\n", str);
    cJSON_free(str);

    // 判斷收到的是否是溫度傳感器命令
    if((item = cJSON_GetObjectItem(root, "unit")) != NULL)
    {
        sddc_return_value_if_fail(item, SDDC_TRUE);
        
        msg = cJSON_Print(item);
        sddc_printf("iot_pi_on_msg: %s\n", msg);

        temperature = cJSON_CreateObject();
        sddc_return_value_if_fail(temperature, SDDC_TRUE);

        // 判斷需要發送的是否是攝氏溫度
        if ((strcmp(item->valuestring, "Centigrade")) == 0)
        {
            Serial.print("環境溫度 Ambient = "); Serial.print(mlx.readAmbientTempC()); 
            Serial.print("*C\t 目標溫度 Object = "); Serial.print(mlx.readObjectTempC()); Serial.println("*C");
            cJSON_AddNumberToObject(temperature, "Ambient temperature C", mlx.readAmbientTempC());
            cJSON_AddNumberToObject(temperature, "Object temperature C", mlx.readAmbientTempC());
        }

        // 判斷需要發送的是否是華氏溫度
        if ((strcmp(item->valuestring, "Degree")) == 0)
        {
            Serial.print("環境溫度 Ambient = "); Serial.print(mlx.readAmbientTempF()); 
            Serial.print("*F\t 目標溫度 Object = "); Serial.print(mlx.readObjectTempF()); Serial.println("*F");
            cJSON_AddNumberToObject(temperature, "Ambient temperature F", mlx.readAmbientTempF());
            cJSON_AddNumberToObject(temperature, "Object temperature F", mlx.readAmbientTempF());
        }
        
        // 發送消息
        msg = cJSON_Print(temperature);
        sddc_send_message(sddc, uid, msg, strlen(msg), 1, SDDC_FALSE, NULL);
        cJSON_free(msg);
//        cJSON_Delete(temperature);
    }
    
error:
    cJSON_Delete(temperature);
    cJSON_Delete(root);

    return SDDC_TRUE;
}

代碼寫完之后燒錄進去就完事了,和之前完全一樣,點一下保存,然后上傳OK,具體可以看上一篇文檔 我就懶得再寫一遍啦 (/ω\)

融合!特殊召喚:智能溫度傳感器!

傳感器設備准備完畢!現在我的場上有一只可以連接 WIFI 的溫度傳感器,還有一只可以作為服務器的 Spirit 1 !現在就可以發動融合卡!設備連接,特殊召喚出一只智能溫度傳感器!

具體過程參考:官方的 SDDC 協議介紹 中Wi-Fi 智能配網的章節。

第一步:打開我們那空空如也設備應用,點擊下方的 + :
add_device
第二部:點擊加號之后,等了一會就看見我的設備了!
在這里插入圖片描述

添加成功!:點擊添加,輸入自己設定的密碼(官方代碼里默認是 1234567890)就能完成添加:
在這里插入圖片描述

效果

打開我們之前寫的 調試工具 輸入命令可以看到確實收到了傳感器返回的溫度!ヾ(゚∀゚ゞ) 不過目前只能用這個 demo 手動構築報文,還是比較 LOW 以后想辦法自己寫一個專門的應用吧!(๑>ڡ<)✿
在這里插入圖片描述

總結

現在自制智能家居設備的小目標又近了一步!(๑>ڡ<)✿ 雖然現在只是個小小的 demo 但是證明了這東西確實可以作為我自己的智能設備服務器使用!之后想辦法寫個小應用出來!

如果在具體使用上還有什么疑問的可以看看 簡單無腦,上手即用 - 手把手教你使用 智能紅外溫度傳感器代碼以及依賴庫! 我覺得寫得非常詳細了。

本文僅個人學習使用,如有錯誤,歡迎指正, ( ੭ ˙ᗜ˙ )੭謝謝老板!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM