大數據

使用AliOS Things快速構建溫度計應用

使用AliOS Things快速構建溫度計應用

本文是基於AliOS Things 3.1快速構建溫度計的應用場景。涉及AliOS Things組件開發,構建AliOS Things用戶項目,AliOS Things HAL API使用,向AliOS Things中添加並使用組件。用到的硬件設備有半導體開發板、溫度傳感器、數碼管顯示器。

背景信息

  • AliOS Things HAL API

AliOS Things向用戶提供的統一硬件抽象API,為用戶提供標準的對MCU片上硬件操作的能力。使得用戶應用在多個不同平臺之間遷移時,可以無需考慮硬件平臺本身的區別,同時也使外設驅動類組件可以快速地在適配過AliOS Things的不同硬件之間複用,提高開發效率。

  • AliOS Things 組件

AliOS Things提供的功能擴展能力。通過將外設驅動,通信協議,控制算法,數據算法等通用能力封裝為符合AliOS Things標準的組件,是各種附加能力可以快速被用戶複用於自己的應用中。同時,組件與OS分離設計,按需安裝使用,可以有效地控制資源佔用。

  • I2C總線

I2C總線用於總線上的器件之間傳送信息,是一種簡單、雙向二線制同步串行總線。發送數據一方稱為主器件,被尋址的器件稱為從器件,由主器件負責產生定時時鐘和終止數據傳送。

  • TM1637芯片

TM1637 是一種帶鍵盤掃描接口的LED(發光二極管顯示器)驅動控制專用電路,內部集成有MCU 數字接口、數據鎖存器、LED 高壓驅動、鍵盤掃描等電路。主要應用於電磁爐、微波爐及小家電產品的顯示屏驅動。
整體流程圖如下:
image.png

  • 物聯網系統使用AliOS Things 3.1版本作為基礎軟件平臺。
  • 設備端開發使用AliOS Things的HAL(硬件抽象層) API及組件,實現片上外設的使用及外部傳感器的數據採集。
  • 開發板採用意法半導體NUCLEO-F103RB開發板,主控芯片為stm32f103RBT6。AliOS Things已完成對該主板的適配。
  • 溫度傳感器採用LM75A數字溫度傳感器,該傳感器通過I2C總線與主控MCU通信,可以提供0.125℃精度的溫度輸出。
  • 數碼管採用由TM1637驅動的6位數碼管進行顯示。

硬件連接圖如下:
image.png

步驟一:創建AliOS Things用戶項目

1.單擊左下角+按鈕。在彈窗的選項框中選擇project
image.png
2.選擇helloworld_demo作為工程構建模板。
image.png
3.選擇stm32f103rb-nucleo作為開發板。
image.png
4.輸入應用名,按enter鍵,例如:myapp_wdj。
image.png
5.選擇工程存儲目錄,按enter鍵生成項目工程。
image.png
6.開發工具Visual Studio Code自動打開生成的用戶應用。
用戶應用主入口位於appdemo.c文件中。
image.png
7.單擊下面的編譯圖標image.png進行編譯。
在控制檯中看到編譯結果。
image.png
8.單擊下面的燒錄image.png圖標,將編譯好的固件燒寫到開發板中。
9.單擊插頭圖標,可以打開串口調試工具進行觀察。
開發板已在按照模板程序打印hello world字符及打印計數。
image.png
至此,用戶應用工程建立完畢。

步驟二:加入溫度採集

1.在工程appdemo.c文件中加入如下代碼。

#include <aos/hal/i2c.h>                // 包含需要用到的I2C HAL驅動
#define I2C1_PORT_NUM PORT_I2C_1       // 使用開發板的第一路I2C通道
#define I2C_RX_TIMEOUT 10               // 定義接收超時時間宏
i2c_dev_t i2c1;                         // 定義一個I2C設備結構體,用戶後續操作具體的I2C接口

/* i2c初始化函數 */

void i2c1_init(void)
{
    int ret = -1;
    /* i2c attr config */
    i2c1.port = PORT_I2C_1;
    i2c1.config.address_width = I2C_HAL_ADDRESS_WIDTH_7BIT;
    i2c1.config.freq = I2C_BUS_BIT_RATES_400K;
    i2c1.config.mode = I2C_MODE_MASTER;
    /* init i2c1 with the given settings */
    ret = hal_i2c_init(&i2c1);
}

HAL的其他參數細節請參考文檔

2.在方法application_start中加入I2C初始化。

int application_start(int argc, char *argv[])
{

    int count = 0;

    printf("nano entry here!\r\n");
    //fd = board_lcd_create("name");  
    //board_lcd_write(fd,buffer,len);

    i2c1_init();                    // 調用I2C初始化

    while(1) {
        printf("hello world! count %d \r\n", count++);
        aos_msleep(1000);
    };

}

3.加入溫度採集及相關數據處理部分到主循環中。

int application_start(int argc, char *argv[])

{

    int count = 0;

    int ret = -1;

    float temp;

    unsigned char
    i2c_data_buf[10];

    uint16_t TempAll;
    int sig = 1;

    int temp_int;

    printf("nano entry here!\r\n");

    i2c1_init();                    // 調用I2C初始化

    while(1) {

        // printf("hello world! count %d \r\n", count++);

        /*通過HAL讀取 0x90地址設備的0x00寄存器,讀取長度為2字節,返回數據放入i2c_data_buf中*/

        ret = hal_i2c_mem_read(&i2c1, 0x90, 0x00, I2C_MEMADD_SIZE_8BIT,i2c_data_buf,2,I2C_RX_TIMEOUT);

        if(ret != 0)

        {

            printf("read fail!\r\n");
            // return;
        }

        TempAll = ((i2c_data_buf[0] << 8) + i2c_data_buf[1]);   // 根據LM75自身特性拼接溫度數據

       
        printf("middle=%d\r\n",TempAll);

        if ((i2c_data_buf[0] & 0x80) != 0)                      // 判斷數據的符號

        {

            TempAll = ~(TempAll) + 1;

            sig = -1;

        }

        TempAll >>=5;      // 低5位無效數據除

       
        printf("middle=%d\r\n",TempAll);    // 打印中間數據用於調試

        temp = TempAll * 0.125* sig;       // 計算最終數據

        printf("temp = %.2f\n",temp);       // 打印最終數據

        aos_msleep(1000);

    };
}             

4.再次編譯、燒錄、串口監控。
在串口調試框中看到數據已完成採集。至此,溫度採集部分完成。

步驟三:加入本地顯示

1.組件包安裝。
在組件包所在目錄,輸入如下安裝命令。

aos install comp -L aos_TM1637-1.0.3.zip

aos-cube工具會把組件安裝到AliOS Things源碼目錄。
輸入以下命令查看安裝的組件。

aos list comp

image.png
2.在應用中加入組件。

  • 在應用中進行組件的頭文件引用。

加入的代碼如下:

#include <aos_TM1637.h>                 // 包含組件頭文件
  • 在應用中加入組件提供的相關API,完成顯示設備驅動輸出。

加入的代碼如下:

aos_drv_TM1637_init(1,0);       // 組件初始化,PA1=clk;PA0=data
aos_drv_TM1637_SetBrightness(3);    // 通過組件設置數碼管亮度
temp_int = temp * 100;              // 數碼管不支持小數顯示,先將溫度轉為整數
aos_drv_TM1637_DisplayDecimal(temp_int,2);  // 通過組件API使數碼管顯示,並將小數點定到第二位以匹配真實數據

3.再次編譯、燒錄、進行串口監控。
看到溫度數據顯示到了數碼管上,和串口輸出一致。
image.png
appdemo.c文件的完整代碼如下:

/*
 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
 */

#include <stdio.h>
#include <stdlib.h>
#include <aos/kernel.h>
#include "aos/init.h"
#include "board.h"
#include <k_api.h>

#include <aos/hal/i2c.h>                // 包含需要用到的I2C HAL驅動

#include <aos_TM1637.h>                 // 包含組件頭文件

#define I2C1_PORT_NUM  PORT_I2C_1       // 使用開發板的第一路I2C通道
#define I2C_RX_TIMEOUT 10               // 定義接收超時時間宏

i2c_dev_t i2c1;                         // 定義一個I2C設備結構體,用戶後續操作具體的I2C接口

/* i2c初始化函數 */
void i2c1_init(void)
{
    int ret = -1;

    /* i2c attr config */
    i2c1.port                 = PORT_I2C_1;
    i2c1.config.address_width = I2C_HAL_ADDRESS_WIDTH_7BIT;
    i2c1.config.freq          = I2C_BUS_BIT_RATES_400K;
    i2c1.config.mode          = I2C_MODE_MASTER;
    /* init i2c1 with the given settings */
    ret = hal_i2c_init(&i2c1);
}

int application_start(int argc, char *argv[])
{
    int count = 0;
    int ret = -1;
    float temp;
    unsigned char i2c_data_buf[10];
    uint16_t TempAll;
    int sig = 1;
    int temp_int;
    printf("nano entry here!\r\n");

    i2c1_init();                    // 調用I2C初始化
    aos_drv_TM1637_init(1,0);       // 組件初始化,PA1=clk;PA0=data
    aos_drv_TM1637_SetBrightness(3);    // 通過組件設置數碼管亮度
    while(1) {
        // printf("hello world! count %d \r\n", count++);
        /*通過HAL讀取 0x90地址設備的0x00寄存器,讀取長度為2字節,返回數據放入i2c_data_buf中*/
        ret = hal_i2c_mem_read(&i2c1, 0x90, 0x00, I2C_MEMADD_SIZE_8BIT,i2c_data_buf,2, I2C_RX_TIMEOUT);
        if(ret != 0)
        {
            printf("read fail!\r\n");
            // return;
        }
        TempAll = ((i2c_data_buf[0] << 8) + i2c_data_buf[1]);   // 根據LM75自身特性拼接溫度數據
        printf("middle=%d\r\n",TempAll);
        if ((i2c_data_buf[0] & 0x80) != 0)                      // 判斷數據的符號
        {
            TempAll = ~(TempAll) + 1;
            sig = -1;
        }
        TempAll >>= 5;      // 低5位無效數據除
        printf("middle=%d\r\n",TempAll);    // 打印中間數據用於調試
        temp = TempAll * 0.125 * sig;       // 計算最終數據
        printf("temp = %.2f\n",temp);       // 打印最終數據
        temp_int = temp * 100;              // 數碼管不支持小數顯示,先將溫度轉為整數
        aos_drv_TM1637_DisplayDecimal(temp_int,2);  // 通過組件API使數碼管顯示,並將小數點定到第二位以匹配真實數據
        aos_msleep(1000);
    };
}

Leave a Reply

Your email address will not be published. Required fields are marked *