我是靠谱客的博主 暴躁火,最近开发中收集的这篇文章主要介绍鸿蒙实训(基于智能硬件学习)第三期前言 环境监测板开发一、AHT20温湿度传感器数据读取二、MQ-2燃气传感器数据读取三、OLED显示数据四、环境监测系统总结,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述


前言 环境监测板开发


一、AHT20温湿度传感器数据读取

二、MQ-2燃气传感器数据读取

ppm是指part per million,同理b,t分别表示billion和trillion。. 即1ppm=10^-6数量级,类似的还有ppb,ppt等,分别是-9次和-12次。.

1.结果

三、OLED显示数据

四、环境监测系统

1.,目录:

2.代码和配置:

BUILD.gn


static_library("demo") {
    sources = [
        # "aht20_demo.c","aht20.c",    #温湿度传感器
        #"mq2_demo.c"      #MQ2监测环境可燃气体
        #"colorful_light_demo.c",
        #"colorful_light.c",
        # "human_sensor.c",
        # "photosensitive.c",
        #"human_sensor_light.c"
        #"oled_demo.c", "oled_ssd1306.c",     #显示屏上输出
        "main.c", "enrionment_task.c", "aht20.c", "oled_ssd1306.c", "oled_task.c",
        #"enrionment_demo.c", "oled_ssd1306.c", "aht20.c"  #环境监测系统 
    ]

    include_dirs = [
        "//utils/native/lite/include",
        "//kernel/liteos_m/components/cmsis/2.0",
        "//base/iot_hardware/interfaces/kits/wifiiot_lite",
        "//foundation/communication/interfaces/kits/wifi_lite/wifiservice",
        "//third_party/pahomqtt/MQTTPacket/src",
        "//third_party/pahomqtt/MQTTPacket/samples",
        "//vendorhisihi3861hi3861componentsatsrc",
    ]
}

main.c

//main.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "enrionment_task.h"
#include "oled_task.h"
// #include "wifi_device.h"
// #include "lwip/netifapi.h"
// #include "lwip/api_shell.h"
//主模块
static void ems_thread(void *arg)
{
    (void)arg;
    printf("Environmental monitoring system runningn");
    enrionmentTask();
    oledTask();
} //创建线程运行主模块
void ems_entry(void)
{
    osThreadAttr_t attr;
    attr.name = "emaews_thread";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 4096; // 4096;
    attr.priority = 36;
    if (osThreadNew((osThreadFunc_t)ems_thread, NULL, &attr) == NULL)
    {
        printf("[emaews] Falied to create LedTask!n");
    }
}
SYS_RUN(ems_entry); //注册函数,可以执行

enironment_task.c

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "wifiiot_i2c.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
#include "wifiiot_errno.h"
#include "aht20.h"
#include "wifiiot_adc.h"
#define AHT20_BAUDRATE 400 * 1000
#define AHT20_I2C_IDX WIFI_IOT_I2C_IDX_0
#define GAS_SENSOR_CHAN_NAME WIFI_IOT_ADC_CHANNEL_5
float humidity = 0.0f;
float temperature = 0.0f;
unsigned short gas = 0;  //单位为:ppm,ppm浓度(parts per million)是用溶质质量占全部溶液质量的百万分比来表示的浓度
// MQ-2测试范围为:300-10000ppm
unsigned short stat = 0; 
//0正常,1,警告;2,危险
void init(void)
{
    GpioInit();
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_13, WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA);
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL);
    I2cInit(AHT20_I2C_IDX, AHT20_BAUDRATE);
}
static void enrionmentThread(void *arg)
{
    (void)arg;
    init(); //初始化IIC
    uint32_t retval = 0;
    // 发送初始化校准命令
    while (WIFI_IOT_SUCCESS != AHT20_Calibrate())
    {
        printf("AHT20 sensor init failed!rn");
        usleep(1000);
    }
    while (1)
    {
        // 发送触发测量命令,开始测量
        retval = AHT20_StartMeasure();
        if (retval != WIFI_IOT_SUCCESS)
        {
            printf("trigger measure failed!rn");
        }
        else
        {
            // 接收测量结果,拼接转换为标准值
            retval = AHT20_GetMeasureResult(&temperature, &humidity);
        }  
        //读取可燃气体值检测浓度:300-10000ppm(可燃气体)
        AdcRead(GAS_SENSOR_CHAN_NAME, &gas, WIFI_IOT_ADC_EQU_MODEL_4, WIFI_IOT_ADC_CUR_BAIS_DEFAULT, 0);
        if (temperature < -35 || temperature > 25 || humidity > 80 || gas > 1840)
        {
            stat = 2; //危险
            }
            else if (temperature < 10 || temperature > 23 || humidity > 70 || gas > 1760)
            {
                stat = 1; //警告
                }
                else
                {
                    stat = 0; //正常
                }
                printf("temp:%4.1f degree,hum:%4.1f %%,gas:%d PPM,stat:%d  rn",temperature,humidity,gas,stat);
                //    usleep(500000);  //微秒
                sleep(1);//秒
            }
        }
void enrionmentTask(void)
{
    osThreadAttr_t attr;
    attr.name = "enrionmentThread";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size =1024;   //线程栈的大小
    attr.priority = osPriorityNormal;
    if (osThreadNew(enrionmentThread, NULL, &attr) == NULL)
    {
        printf("[enrionmentThread] Falied to create enrionmentThread!n");
    }
}

enironment_task.h

#ifndef ENRIONMENT_TASK_H
#define ENRIONMENT_TASK_H
extern float humidity ; //湿度值
extern float temperature ;//温度值
extern unsigned short gas ;   //可燃气体值
extern unsigned short stat ;//0正常,1,警告;2,危险
void enrionmentTask(void);  //子模块线程函数#endif
#endif

oled_task.c

#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
#include "oled_ssd1306.h"
#include "enrionment_task.h"
//该函数对GPIO管脚及OLED进行初始化
void oledTaskInit(void)
{
    GpioInit();
    OledInit();
}
//业务函数,完成数据在OLED上显示
void oledThread(void *arg)
{
    (void)arg;
    oledTaskInit();       //初始化
    OledFillScreen(0x00); //清屏,//在左上角位置显示字符串Hello, HarmonyOS
    OledShowString(0, 0, "hello,chinasoft", 1);
    sleep(1); //等待1秒
    char line[32] = {0};
    OledFillScreen(0x00); //清屏
    while (1)
    {
        OledShowString(16, 0, "Environment", 1); //组装显示温度的字符串
        snprintf(line, sizeof(line), "temp: %.1f deg", temperature);
        OledShowString(0, 3, line, 1); //在(0,1)位置显示组装后的温度字符串
        //组装显示湿度的字符串
        snprintf(line, sizeof(line), "humi: %.1f %%", humidity);
        OledShowString(0, 5, line, 1); //在(0,2)位置显示组装后的湿度字符串
        //组装显示气体的字符串单位是百万分之,检测浓度:300-10000ppm(可燃气体)
        snprintf(line, sizeof(line), "gas : %4d ppm", gas);
        OledShowString(0, 7, line, 1); //在(0,3)位置显示组装后的气体字符串
        usleep(500000);
        ; //睡眠
    }
} //创建新线程运行OledTask函数
void oledTask(void)
{
    osThreadAttr_t attr;
    attr.name = "oledThread";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 4096;
    attr.priority = osPriorityNormal;
    if (osThreadNew(oledThread, NULL, &attr) == NULL)
    {
        printf("[oledThread] Falied to create oledThread!n");
    }
}

oled_task.h

#ifndef OLED_TASK_H
#define OLED_TASK_H
/*** 初始化GPIO管脚、及OLED*/
void oledTaskInit(void);
/**** oledTask 线程函数*/
void oledTask(void);
#endif

oled_ssd1306.c


#include <stddef.h>
#include <stdio.h>
#include "oled_ssd1306.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
#include "wifiiot_i2c.h"
#include "wifiiot_errno.h"
#include "oled_fonts.h"

#define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])

#define OLED_I2C_IDX WIFI_IOT_I2C_IDX_0

#define OLED_WIDTH    (128)
#define OLED_I2C_ADDR 0x78 // 默认地址为 0x78
#define OLED_I2C_CMD 0x00 // 0000 0000       写命令
#define OLED_I2C_DATA 0x40 // 0100 0000(0x40) 写数据
#define OLED_I2C_BAUDRATE (400*1000) // 400k

#define DELAY_100_MS (100*1000)

// unsigned int I2cSetBaudrate(WifiIotI2cIdx id, unsigned int baudrate);

static uint32_t I2cWiteByte(uint8_t regAddr, uint8_t byte)
{
    WifiIotI2cIdx id = OLED_I2C_IDX;
    uint8_t buffer[] = {regAddr, byte};
    WifiIotI2cData i2cData = {0};

    i2cData.sendBuf = buffer;
    i2cData.sendLen = sizeof(buffer)/sizeof(buffer[0]);

    return I2cWrite(id, OLED_I2C_ADDR, &i2cData);
}

/**
 * @brief Write a command byte to OLED device.
 *
 * @param cmd the commnad byte to be writen.
 * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful;
 * returns an error code defined in {@link wifiiot_errno.h} otherwise.
 */
static uint32_t WriteCmd(uint8_t cmd)
{
    return I2cWiteByte(OLED_I2C_CMD, cmd);
}

/**
 * @brief Write a data byte to OLED device.
 *
 * @param cmd the data byte to be writen.
 * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful;
 * returns an error code defined in {@link wifiiot_errno.h} otherwise.
 */
static uint32_t WriteData(uint8_t data)
{
	return I2cWiteByte(OLED_I2C_DATA, data);
}

/**
 * @brief ssd1306 OLED Initialize.
 */
uint32_t OledInit(void)
{
    static const uint8_t initCmds[] = {
        0xAE, // --display off
        0x00, // ---set low column address
        0x10, // ---set high column address
        0x40, // --set start line address  
        0xB0, // --set page address
        0x81, // contract control
        0xFF, // --128   
        0xA1, // set segment remap 
        0xA6, // --normal / reverse
        0xA8, // --set multiplex ratio(1 to 64)
        0x3F, // --1/32 duty
        0xC8, // Com scan direction
        0xD3, // -set display offset
        0x00, // 
        0xD5, // set osc division
        0x80, // 
        0xD8, // set area color mode off
        0x05, // 
        0xD9, // Set Pre-Charge Period
        0xF1, // 
        0xDA, // set com pin configuartion
        0x12, // 
        0xDB, // set Vcomh
        0x30, // 
        0x8D, // set charge pump enable
        0x14, // 
        0xAF, // --turn on oled panel
    };

    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_13, WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA);
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL);

    I2cInit(WIFI_IOT_I2C_IDX_0, OLED_I2C_BAUDRATE);
    // I2cSetBaudrate(WIFI_IOT_I2C_IDX_0, OLED_I2C_BAUDRATE);

    for (size_t i = 0; i < ARRAY_SIZE(initCmds); i++) {
        uint32_t status = WriteCmd(initCmds[i]);
        if (status != WIFI_IOT_SUCCESS) {
            return status;
        }
    }
    return WIFI_IOT_SUCCESS;
}

void OledSetPosition(uint8_t x, uint8_t y)
{
    WriteCmd(0xb0 + y);
    WriteCmd(((x & 0xf0) >> 4) | 0x10);
    WriteCmd(x & 0x0f);
}

/*全屏填充*/
void OledFillScreen(uint8_t fillData)
{
    uint8_t m = 0;
    uint8_t n = 0;

    for (m=0; m < 8; m++) {
        WriteCmd(0xb0 + m);
        WriteCmd(0x00);
        WriteCmd(0x10);

        for (n=0; n < 128; n++) {
            WriteData(fillData);
        }
    }
}

/**
 * @brief 8*16 typeface
 * @param x: write positon start from x axis 
 * @param y: write positon start from y axis
 * @param ch: write data
 * @param font: selected font
 */
void OledShowChar(uint8_t x, uint8_t y, uint8_t ch, Font font)
{      	
	uint8_t c = 0;
    uint8_t i = 0;

    c = ch - ' '; //得到偏移后的值	
    if (x > OLED_WIDTH - 1) {
        x = 0;
        y = y + 2;
    }

    if (font == FONT8x16) {
        OledSetPosition(x, y);	
        for (i = 0; i < 8; i++){
            WriteData(F8X16[c*16 + i]);
        }

        OledSetPosition(x, y+1);
        for (i = 0; i < 8; i++) {
            WriteData(F8X16[c*16 + i + 8]);
        }
    } else {
        OledSetPosition(x, y);
        for (i = 0; i < 6; i++) {
            WriteData(F6x8[c][i]);
        }
    }
}

void OledShowString(uint8_t x, uint8_t y, const char* str, Font font)
{
	uint8_t j = 0;
    if (str == NULL) {
        printf("param is NULL,Please check!!!rn");
        return;
    }

	while (str[j]) {
        OledShowChar(x, y, str[j], font);
		x += 8;
		if (x > 120) {
            x = 0;
            y += 2;
        }
		j++;
	}
}

oled_ssd1306.h



#ifndef OLED_SSD1306_H
#define OLED_SSD1306_H

#include <stdint.h>

/**
 * @brief ssd1306 OLED Initialize.
 */
uint32_t OledInit(void);

/**
 * @brief Set cursor position
 *
 * @param x the horizontal posistion of cursor
 * @param y the vertical position of cursor 
 * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful;
 * returns an error code defined in {@link wifiiot_errno.h} otherwise.
 */
void OledSetPosition(uint8_t x, uint8_t y);

void OledFillScreen(uint8_t fillData);

enum Font {
    FONT6x8 = 1,
    FONT8x16
};
typedef enum Font Font;

void OledShowChar(uint8_t x, uint8_t y, uint8_t ch, Font font);
void OledShowString(uint8_t x, uint8_t y, const char* str, Font font);

#endif // OLED_SSD1306_H

3.结果:

监测:

效果图:

 


总结

最后

以上就是暴躁火为你收集整理的鸿蒙实训(基于智能硬件学习)第三期前言 环境监测板开发一、AHT20温湿度传感器数据读取二、MQ-2燃气传感器数据读取三、OLED显示数据四、环境监测系统总结的全部内容,希望文章能够帮你解决鸿蒙实训(基于智能硬件学习)第三期前言 环境监测板开发一、AHT20温湿度传感器数据读取二、MQ-2燃气传感器数据读取三、OLED显示数据四、环境监测系统总结所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部