跳转至

劳动实践(BearPi)笔记

劳动实践(BearPi)笔记

环境配置

依赖安装

参考给定的虚拟机镜像的版本

nvm install 14.15.1

npm install -g @ohos/hpm-cli@1.0.2

pip install pycryptodome

pip install ecdsa

驱动安装

必须在插上开发板才能安装驱动

烧录

  1. 文档建议Baud选择 921600, 参考其他人博客 可以设置为3000000, 速度更快
  2. 烧录过程似乎要跑两轮进度条, 直到界面显示Connecting...后断开

Hello World

编译依然是

hpm dist

BUILD.gn

static_library("myapp") {
    sources = [
        "hello.c"
    ]

    include_dirs = [
        "//utils/native/lite/include",
        "//kernel/liteos_m/components/cmsis/2.0",
        "//base/iot_hardware/interfaces/kits/wifiiot_lite",
    ]
}

hello.c

#include <stdio.h>
#include <ohos_init.h>

void led(void)
{
    printf("Hello, BearPi!\r\n");
}
APP_FEATURE_INIT(led);

不知道什么缘故 开始烧录需要等待2~3秒, 要耐心XD, 别以为代码出问题了

image-20240617150331809

image-20240617150205097

LED

build.gn

static_library("myled") {
    sources = [
        "led.c"
    ]

    include_dirs = [
        "//utils/native/lite/include",
        "//base/iot_hardware/interfaces/kits/wifiiot_lite",
    ]
}

led.c

#include <stdio.h>
#include <ohos_init.h>
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
#include <unistd.h>

void led(void)
{
    int cnt = 0;
    while (1)
    {
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, WIFI_IOT_GPIO_VALUE1);
        printf("%d led on\n", cnt);
        usleep(1000000);
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, WIFI_IOT_GPIO_VALUE0);
        printf("%d led off\n", cnt++);
        usleep(1000000);
    }
}
APP_FEATURE_INIT(led);

image-20240617162459277

button

example使用的引脚是WIFI_IOT_IO_NAME_GPIO_11课程例子用的是WIFI_IOT_GPIO_IDX_11

二者等效

实现的是一个按键反转

#include <stdio.h>
#include <ohos_init.h>
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"

// 反转value
static void reverse_value(WifiIotGpioValue *value)
{
    if (*value == WIFI_IOT_GPIO_VALUE1)
    {
        *value = WIFI_IOT_GPIO_VALUE0;
    }
    else
    {
        *value = WIFI_IOT_GPIO_VALUE1;
    }
}

void f1_pressed(char *arg)
{
    (void)arg;
    WifiIotGpioValue value;
    GpioGetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, &value);
    printf("[key1] pressed; LED status: [%d]\n", value);
    reverse_value(&value);
    GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, value);
}

void key_init(void)
{
    hello();
    GpioInit();

    // 初始化LED灯
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_2, WIFI_IOT_IO_FUNC_GPIO_2_GPIO);
    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_2, WIFI_IOT_GPIO_DIR_OUT);

    // 初始化F1按键,设置为下降沿触发中断
    IoSetFunc(WIFI_IOT_GPIO_IDX_11, WIFI_IOT_IO_FUNC_GPIO_11_GPIO);

    GpioSetDir(WIFI_IOT_GPIO_IDX_11, WIFI_IOT_GPIO_DIR_IN);
    IoSetPull(WIFI_IOT_GPIO_IDX_11, WIFI_IOT_IO_PULL_UP);
    GpioRegisterIsrFunc(WIFI_IOT_GPIO_IDX_11, WIFI_IOT_INT_TYPE_EDGE, WIFI_IOT_GPIO_EDGE_FALL_LEVEL_LOW, f1_pressed, NULL);

    // IoSetFunc(WIFI_IOT_GPIO_IDX_11, WIFI_IOT_IO_FUNC_GPIO_11_GPIO);
    // GpioSetDir(WIFI_IOT_GPIO_IDX_11, WIFI_IOT_GPIO_DIR_IN);
    // GpioRegisterIsrFunc(WIFI_IOT_GPIO_IDX_11, WIFI_IOT_INT_TYPE_EDGE, WIFI_IOT_GPIO_EDGE_FALL_LEVEL_LOW, f1_pressed, NULL);
}

APP_FEATURE_INIT(key_init);

image-20240618103458840

E53 IA1拓展板

motor

main.c

#include <stdio.h>
#include <stdint.h>
#include <ohos_init.h>
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"

#define MOTOR_ON 1
#define MOTOR_OFF 0

#define DEBOUNCE_TIME 50 // 去抖动时间,单位:毫秒

void set_motor(int value)
{
    if (value == 0)
    {
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_GPIO_VALUE0);
    }
    else
    {
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_GPIO_VALUE1);
    }
}

void f1_pressed(char *arg)
{
    (void)arg;

    WifiIotGpioValue value = WIFI_IOT_GPIO_VALUE1;
    GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, value);
    set_motor(MOTOR_ON);
    printf("Motor ON\n");
    // 去抖动
    usleep(DEBOUNCE_TIME * 1000);
}

void f2_pressed(char *arg)
{
    (void)arg;

    WifiIotGpioValue value = WIFI_IOT_GPIO_VALUE0;
    GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, value);
    set_motor(MOTOR_OFF);
    printf("Motor OFF\n");
    // 去除抖动
    usleep(DEBOUNCE_TIME * 1000);
}

void key_init(void)
{
    GpioInit();

    // 初始化LED灯
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_2, WIFI_IOT_IO_FUNC_GPIO_2_GPIO);
    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_2, WIFI_IOT_GPIO_DIR_OUT);

    // 初始化电机
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_IO_FUNC_GPIO_8_GPIO);
    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_GPIO_DIR_OUT);

    // 初始化F1按键,设置为下降沿触发中断
    IoSetFunc(WIFI_IOT_GPIO_IDX_11, WIFI_IOT_IO_FUNC_GPIO_11_GPIO);

    GpioSetDir(WIFI_IOT_GPIO_IDX_11, WIFI_IOT_GPIO_DIR_IN);
    IoSetPull(WIFI_IOT_GPIO_IDX_11, WIFI_IOT_IO_PULL_UP);
    GpioRegisterIsrFunc(WIFI_IOT_GPIO_IDX_11, WIFI_IOT_INT_TYPE_EDGE, WIFI_IOT_GPIO_EDGE_FALL_LEVEL_LOW, f1_pressed, NULL);

    // 初始化F2按键,设置为下降沿触发中断
    IoSetFunc(WIFI_IOT_GPIO_IDX_12, WIFI_IOT_IO_FUNC_GPIO_12_GPIO);

    GpioSetDir(WIFI_IOT_GPIO_IDX_12, WIFI_IOT_GPIO_DIR_IN);
    IoSetPull(WIFI_IOT_GPIO_IDX_12, WIFI_IOT_IO_PULL_UP);
    GpioRegisterIsrFunc(WIFI_IOT_GPIO_IDX_12, WIFI_IOT_INT_TYPE_EDGE, WIFI_IOT_GPIO_EDGE_FALL_LEVEL_LOW, f2_pressed, NULL);
}

APP_FEATURE_INIT(key_init);

image-20240618113707410

紫外线灯

    // 紫外线灯
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_IO_FUNC_GPIO_14_GPIO);
    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_GPIO_DIR_OUT);
    GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_GPIO_VALUE1);
    // 检查是否设置成功
    WifiIotGpioValue value;
    GpioGetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, &value);
    assert(value == WIFI_IOT_GPIO_VALUE1);

光敏传感器

可以参考sample中的C2_e53_ia1_temp_humi_pls

头文件封装
#ifndef __E53_IA1_H__
#define __E53_IA1_H__

#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <ohos_init.h>
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
#include "wifiiot_i2c.h"
#include "wifiiot_i2c_ex.h"
#include <stdlib.h>

// #define assert(e) ((e) ? (void)0 : assert_fail(__FILE__, __LINE__, #e))

// inline void assert_fail(const char *file, int line, const char *expr)
// {
//     printf("assertion \"%s\" failed: file \"%s\", line %d\n", expr, file, line);
//     abort();
// }

#define BH1750_Addr 0x23

typedef enum
{
    OFF = 0,
    ON
} E53_IA1_Status_ENUM;

/* E53_IA1传感器数据类型定义*/
typedef struct
{
    float Lux;         // 光照强度
    float Humidity;    // 湿度
    float Temperature; // 温度
} E53_IA1_Data_TypeDef;

/**
 * @brief 启动BH1750, 开始采集数据
 */
void E53_IA1_Read_Data(E53_IA1_Data_TypeDef *E53_IA1_Data);

/**
 * @brief 设置紫外线灯状态
 */
void Light_StatusSet(E53_IA1_Status_ENUM status);
/**
 * @brief 设置马达状态
*/
void Motor_StatusSet(E53_IA1_Status_ENUM status);

/**
 * @brief E53_IA1 IO接口初始化
 */
void E53_IA1_IO_Init(void);

/**
 * @brief 初始化BH1750
 */
void Init_BH1750(void);

/**
 * @brief E53_IA1传感器初始化
 */
void E53_IA1_Init(void);


#endif // __E53_IA1_H__
具体实现
#include "e53_ia1.h"

void E53_IA1_IO_Init(void)
{
    GpioInit();

    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_IO_FUNC_GPIO_8_GPIO); // 设置GPIO_2的复用功能为普通GPIO
    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_GPIO_DIR_OUT);       // 设置GPIO_2为输出模式

    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_IO_FUNC_GPIO_14_GPIO); // 设置GPIO_2的复用功能为普通GPIO
    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_GPIO_DIR_OUT);        // 设置GPIO_2为输出模式

    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_0, WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA); // GPIO_0复用为I2C1_SDA
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_1, WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL); // GPIO_1复用为I2C1_SCL
    I2cInit(WIFI_IOT_I2C_IDX_1, 400000);                                  /* baudrate: 400kbps */
    I2cSetBaudrate(WIFI_IOT_I2C_IDX_1, 400000);
}

void Init_BH1750(void)
{
    WifiIotI2cData bh1750_i2c_data = {0};
    uint8_t send_data[1] = {0x01};
    bh1750_i2c_data.sendBuf = send_data;
    bh1750_i2c_data.sendLen = 1;
    I2cWrite(WIFI_IOT_I2C_IDX_1, (BH1750_Addr << 1) | 0x00, &bh1750_i2c_data);
}

void Start_BH1750(void)
{
    WifiIotI2cData bh1750_i2c_data = {0};
    uint8_t send_data[1] = {0x10};
    bh1750_i2c_data.sendBuf = send_data;
    bh1750_i2c_data.sendLen = 1;
    I2cWrite(WIFI_IOT_I2C_IDX_1, (BH1750_Addr << 1) | 0x00, &bh1750_i2c_data);
}

void E53_IA1_Read_Data(E53_IA1_Data_TypeDef *E53_IA1_Data)
{
    Start_BH1750(); // 启动传感器采集数据
    usleep(180000);
    WifiIotI2cData bh1750_i2c_data = {0};
    uint8_t recv_data[2] = {0};
    bh1750_i2c_data.receiveBuf = recv_data;
    bh1750_i2c_data.receiveLen = 2;
    I2cRead(WIFI_IOT_I2C_IDX_1, (BH1750_Addr << 1) | 0x01, &bh1750_i2c_data); // 读取传感器数据
    E53_IA1_Data->Lux = (float)(((recv_data[0] << 8) + recv_data[1]) / 1.2);
}

void Light_StatusSet(E53_IA1_Status_ENUM status)
{
    if (status == ON)
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, 1); // 设置GPIO_2输出高电平点亮灯
    if (status == OFF)
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, 0); // 设置GPIO_2输出低电平关闭灯
}

void Motor_StatusSet(E53_IA1_Status_ENUM status)
{
    if (status == ON)
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 1); // 设置GPIO_8输出高电平打开电机
    if (status == OFF)
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 0); // 设置GPIO_8输出低电平关闭电机
}

void E53_IA1_Init(void)
{
    E53_IA1_IO_Init();
    Init_BH1750();
}
Main
#include "e53_ia1.h"

#define MIN_LUX 20

E53_IA1_Data_TypeDef E53_IA1_Data;

void init(void)
{
    E53_IA1_Init();
    while (1)
    {
        E53_IA1_Read_Data(&E53_IA1_Data);
        printf("Lux:%.2f\r\n", E53_IA1_Data.Lux);

        if (E53_IA1_Data.Lux < MIN_LUX)
        {
            Light_StatusSet(ON);
            Motor_StatusSet(ON);
        }
        else
        {
            Light_StatusSet(OFF);
            Motor_StatusSet(OFF);
        }

        usleep(1000000);
    }
}

APP_FEATURE_INIT(init);
光敏传感器-运行结果

image-20240618163321421

温度传感器

e53_ia1.h
#ifndef __E53_IA1_H__
#define __E53_IA1_H__

#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <ohos_init.h>
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
#include "wifiiot_i2c.h"
#include "wifiiot_i2c_ex.h"
#include <stdlib.h>

#define SHT30_Addr 0x44
#define BH1750_Addr 0x23

typedef enum
{
    OFF = 0,
    ON
} E53_IA1_Status_ENUM;

/* E53_IA1传感器数据类型定义*/
typedef struct
{
    float Lux;         // 光照强度
    float Humidity;    // 湿度
    float Temperature; // 温度
} E53_IA1_Data_TypeDef;

/**
 * @brief 启动BH1750, 开始采集数据
 */
void E53_IA1_Read_Data(E53_IA1_Data_TypeDef *E53_IA1_Data);

/**
 * @brief 设置紫外线灯状态
 */
void Light_StatusSet(E53_IA1_Status_ENUM status);
/**
 * @brief 设置马达状态
 */
void Motor_StatusSet(E53_IA1_Status_ENUM status);

/**
 * @brief E53_IA1传感器初始化
 */
void E53_IA1_Init(void);

#endif // __E53_IA1_H__
e53_ia1.c
#include "e53_ia1.h"

void E53_IA1_IO_Init(void)
{
    GpioInit();

    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_IO_FUNC_GPIO_8_GPIO); // 设置GPIO_2的复用功能为普通GPIO
    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_GPIO_DIR_OUT);       // 设置GPIO_2为输出模式

    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_IO_FUNC_GPIO_14_GPIO); // 设置GPIO_2的复用功能为普通GPIO
    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_GPIO_DIR_OUT);        // 设置GPIO_2为输出模式

    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_0, WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA); // GPIO_0复用为I2C1_SDA
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_1, WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL); // GPIO_1复用为I2C1_SCL
    I2cInit(WIFI_IOT_I2C_IDX_1, 400000);                                  /* baudrate: 400kbps */
    I2cSetBaudrate(WIFI_IOT_I2C_IDX_1, 400000);
}

/**
 * @brief 初始化BH1750
 */
void Init_BH1750(void)
{
    WifiIotI2cData bh1750_i2c_data = {0};
    uint8_t send_data[1] = {0x01};
    bh1750_i2c_data.sendBuf = send_data;
    bh1750_i2c_data.sendLen = 1;
    I2cWrite(WIFI_IOT_I2C_IDX_1, (BH1750_Addr << 1) | 0x00, &bh1750_i2c_data);
}

/**
 * @brief 初始化SHT30
 */
void Init_SHT30(void)
{
    WifiIotI2cData sht30_i2c_data = {0};
    uint8_t send_data[2] = {0x22, 0x36};
    sht30_i2c_data.sendBuf = send_data;
    sht30_i2c_data.sendLen = 2;
    I2cWrite(WIFI_IOT_I2C_IDX_1, (SHT30_Addr << 1) | 0x00, &sht30_i2c_data);
}

void Start_BH1750(void)
{
    WifiIotI2cData bh1750_i2c_data = {0};
    uint8_t send_data[1] = {0x10};
    bh1750_i2c_data.sendBuf = send_data;
    bh1750_i2c_data.sendLen = 1;
    I2cWrite(WIFI_IOT_I2C_IDX_1, (BH1750_Addr << 1) | 0x00, &bh1750_i2c_data);
}

/**
 * @brief 数据校验
 * @param data 数据
 * @param nbrOfBytes 数据长度
 * @param checksum 校验和
 */
static uint8_t SHT3x_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum)
{

    uint8_t crc = 0xFF;
    uint8_t bit = 0;
    uint8_t byteCtr;
    const int16_t POLYNOMIAL = 0x131;
    // calculates 8-Bit checksum with given polynomial
    for (byteCtr = 0; byteCtr < nbrOfBytes; ++byteCtr)
    {
        crc ^= (data[byteCtr]);
        for (bit = 8; bit > 0; --bit)
        {
            if (crc & 0x80)
                crc = (crc << 1) ^ POLYNOMIAL;
            else
                crc = (crc << 1);
        }
    }

    if (crc != checksum)
        return 1;
    else
        return 0;
}
/**
 * @brief 计算温度
 */
static float SHT3x_CalcTemperatureC(uint16_t u16sT)
{

    float temperatureC = 0; // variable for result

    u16sT &= ~0x0003; // clear bits [1..0] (status bits)
    //-- calculate temperature [℃] --
    temperatureC = (175 * (float)u16sT / 65535 - 45); // T = -45 + 175 * rawValue / (2^16-1)

    return temperatureC;
}

/**
 * @brief 计算湿度
 */
static float SHT3x_CalcRH(uint16_t u16sRH)
{

    float humidityRH = 0; // variable for result

    u16sRH &= ~0x0003; // clear bits [1..0] (status bits)
    //-- calculate relative humidity [%RH] --
    humidityRH = (100 * (float)u16sRH / 65535); // RH = rawValue / (2^16-1) * 10

    return humidityRH;
}

void E53_IA1_Read_Data(E53_IA1_Data_TypeDef *E53_IA1_Data)
{
    Start_BH1750(); // 启动传感器采集数据
    usleep(180000);
    WifiIotI2cData bh1750_i2c_data = {0};
    uint8_t recv_data[2] = {0};
    bh1750_i2c_data.receiveBuf = recv_data;
    bh1750_i2c_data.receiveLen = 2;
    I2cRead(WIFI_IOT_I2C_IDX_1, (BH1750_Addr << 1) | 0x01, &bh1750_i2c_data); // 读取传感器数据
    E53_IA1_Data->Lux = (float)(((recv_data[0] << 8) + recv_data[1]) / 1.2);

    uint8_t data[3]; // data array for checksum verification
    uint16_t dat, tmp;
    uint8_t SHT3X_Data_Buffer[6]; // byte 0,1 is temperature byte 4,5 is humidity

    WifiIotI2cData sht30_i2c_data = {0};
    uint8_t send_data[2] = {0xE0, 0x00};
    sht30_i2c_data.sendBuf = send_data;
    sht30_i2c_data.sendLen = 2;
    sht30_i2c_data.receiveBuf = SHT3X_Data_Buffer;
    sht30_i2c_data.receiveLen = 6;
    I2cWriteread(WIFI_IOT_I2C_IDX_1, (SHT30_Addr << 1) | 0x00, &sht30_i2c_data); // Read bh1750 sensor data

    //    /* check tem */
    data[0] = SHT3X_Data_Buffer[0];
    data[1] = SHT3X_Data_Buffer[1];
    data[2] = SHT3X_Data_Buffer[2];

    tmp = SHT3x_CheckCrc(data, 2, data[2]);
    if (!tmp) /* value is ture */
    {
        dat = ((uint16_t)data[0] << 8) | data[1];
        E53_IA1_Data->Temperature = SHT3x_CalcTemperatureC(dat);
    }

    //    /* check humidity */
    data[0] = SHT3X_Data_Buffer[3];
    data[1] = SHT3X_Data_Buffer[4];
    data[2] = SHT3X_Data_Buffer[5];

    tmp = SHT3x_CheckCrc(data, 2, data[2]);
    if (!tmp) /* value is ture */
    {
        dat = ((uint16_t)data[0] << 8) | data[1];
        E53_IA1_Data->Humidity = SHT3x_CalcRH(dat);
    }
}

void Light_StatusSet(E53_IA1_Status_ENUM status)
{
    if (status == ON)
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, 1); // 设置GPIO_2输出高电平点亮灯
    if (status == OFF)
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, 0); // 设置GPIO_2输出低电平关闭灯
}

void Motor_StatusSet(E53_IA1_Status_ENUM status)
{
    if (status == ON)
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 1); // 设置GPIO_8输出高电平打开电机
    if (status == OFF)
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 0); // 设置GPIO_8输出低电平关闭电机
}

void E53_IA1_Init(void)
{
    E53_IA1_IO_Init();
    Init_BH1750();
    Init_SHT30();
}
main.c
#include "e53_ia1.h"

#define MIN_LUX 20

E53_IA1_Data_TypeDef E53_IA1_Data;

void init(void)
{
    int i = 0;
    E53_IA1_Init();
    while (1)
    {
        E53_IA1_Read_Data(&E53_IA1_Data);
        printf("==================i[%d]=====================\r\n", i++);
        printf("Lux:%.2f\r\n", E53_IA1_Data.Lux);
        printf("Humidity:%.2f\r\n", E53_IA1_Data.Humidity);
        printf("Temperature:%.2f\r\n", E53_IA1_Data.Temperature);

        if (E53_IA1_Data.Lux < MIN_LUX)
        {
            Light_StatusSet(ON);
        }
        else
        {
            Light_StatusSet(OFF);
        }

        if (E53_IA1_Data.Temperature > 30 || E53_IA1_Data.Humidity > 65)
        {
            Motor_StatusSet(ON);
        }
        else
        {
            Motor_StatusSet(OFF);
        }

        usleep(1000000);
    }
}

APP_FEATURE_INIT(init);
温度传感器-运行结果

image-20240619095707009

WIFI

BUILD.gn

static_library("wifi_connect") {
    sources = [
        "wifi_sta_connect.c"
    ]

    cflags = [ "-Wno-unused-variable" ]
    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",
        "//vendor/hisi/hi3861/hi3861/third_party/lwip_sack/include/",
    ]
}

wifi.c

#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "lwip/netif.h"
#include "lwip/netifapi.h"
#include "lwip/ip4_addr.h"
#include "lwip/api_shell.h"

#include "cmsis_os2.h"
#include "hos_types.h"
#include "wifi_device.h"
#include "wifiiot_errno.h"
#include "ohos_init.h"

#define DEF_TIMEOUT 15
#define ONE_SECOND 1

static void WiFiInit(void);
static void WaitSacnResult(void);
static int WaitConnectResult(void);
static void OnWifiScanStateChangedHandler(int state, int size);
static void OnWifiConnectionChangedHandler(int state, WifiLinkedInfo *info);
static void OnHotspotStaJoinHandler(StationInfo *info);
static void OnHotspotStateChangedHandler(int state);
static void OnHotspotStaLeaveHandler(StationInfo *info);

static int g_staScanSuccess = 0;
static int g_ConnectSuccess = 0;
static int ssid_count = 0;
WifiEvent g_wifiEventHandler = {0};
WifiErrorCode error;

#define SELECT_WLAN_PORT "wlan0"

#define SELECT_WIFI_SSID "gjwgjwgjw"
#define SELECT_WIFI_PASSWORD "gjw2653066535"
#define SELECT_WIFI_SECURITYTYPE WIFI_SEC_TYPE_PSK

static BOOL WifiSTATask(void)
{
    WifiScanInfo *info = NULL;
    unsigned int size = WIFI_SCAN_HOTSPOT_LIMIT;
    static struct netif *g_lwip_netif = NULL;
    WifiDeviceConfig select_ap_config = {0};

    osDelay(200);
    printf("<--System Init-->\r\n");

    // 初始化WIFI
    WiFiInit();

    // 使能WIFI
    if (EnableWifi() != WIFI_SUCCESS)
    {
        printf("EnableWifi failed, error = %d\n", error);
        return -1;
    }

    // 判断WIFI是否激活
    if (IsWifiActive() == 0)
    {
        printf("Wifi station is not actived.\n");
        return -1;
    }

    // 分配空间,保存WiFi信息
    info = malloc(sizeof(WifiScanInfo) * WIFI_SCAN_HOTSPOT_LIMIT);
    if (info == NULL)
    {
        return -1;
    }

    // 轮询查找WiFi列表
    do
    {
        // 重置标志位
        ssid_count = 0;
        g_staScanSuccess = 0;

        // 开始扫描
        Scan();

        // 等待扫描结果
        WaitSacnResult();

        // 获取扫描列表
        error = GetScanInfoList(info, &size);

    } while (g_staScanSuccess != 1);

    // 打印WiFi列表
    printf("********************\r\n");
    for (uint8_t i = 0; i < ssid_count; i++)
    {
        printf("no:%03d, ssid:%-30s, rssi:%5d\r\n", i + 1, info[i].ssid, info[i].rssi / 100);
    }
    printf("********************\r\n");

    // 连接指定的WiFi热点
    for (uint8_t i = 0; i < ssid_count; i++)
    {
        if (strcmp(SELECT_WIFI_SSID, info[i].ssid) == 0)
        {
            int result;

            printf("Select:%3d wireless, Waiting...\r\n", i + 1);

            // 拷贝要连接的热点信息
            strcpy(select_ap_config.ssid, info[i].ssid);
            strcpy(select_ap_config.preSharedKey, SELECT_WIFI_PASSWORD);
            select_ap_config.securityType = SELECT_WIFI_SECURITYTYPE;

            if (AddDeviceConfig(&select_ap_config, &result) == WIFI_SUCCESS)
            {
                if (ConnectTo(result) == WIFI_SUCCESS && WaitConnectResult() == 1)
                {
                    printf("WiFi connect succeed!\r\n");
                    g_lwip_netif = netifapi_netif_find(SELECT_WLAN_PORT);
                    break;
                }
            }
        }

        if (i == ssid_count - 1)
        {
            printf("ERROR: No wifi as expected\r\n");
            while (1)
                osDelay(100);
        }
    }

    // 启动DHCP
    if (g_lwip_netif)
    {
        dhcp_start(g_lwip_netif);
        printf("begain to dhcp");
    }

    // 等待DHCP
    for (;;)
    {
        if (dhcp_is_bound(g_lwip_netif) == ERR_OK)
        {
            printf("<-- DHCP state:OK -->\r\n");

            // 打印获取到的IP信息
            netifapi_netif_common(g_lwip_netif, dhcp_clients_info_show, NULL);
            break;
        }

        printf("<-- DHCP state:Inprogress -->\r\n");
        osDelay(100);
    }

    // 执行其他操作
    for (;;)
    {
        osDelay(100);
    }
}

static void WiFiInit(void)
{
    printf("<--Wifi Init-->\r\n");
    g_wifiEventHandler.OnWifiScanStateChanged = OnWifiScanStateChangedHandler;
    g_wifiEventHandler.OnWifiConnectionChanged = OnWifiConnectionChangedHandler;
    g_wifiEventHandler.OnHotspotStaJoin = OnHotspotStaJoinHandler;
    g_wifiEventHandler.OnHotspotStaLeave = OnHotspotStaLeaveHandler;
    g_wifiEventHandler.OnHotspotStateChanged = OnHotspotStateChangedHandler;
    error = RegisterWifiEvent(&g_wifiEventHandler);
    if (error != WIFI_SUCCESS)
    {
        printf("register wifi event fail!\r\n");
    }
    else
    {
        printf("register wifi event succeed!\r\n");
    }
}

static void OnWifiScanStateChangedHandler(int state, int size)
{
    (void)state;
    if (size > 0)
    {
        ssid_count = size;
        g_staScanSuccess = 1;
    }
    return;
}

static void OnWifiConnectionChangedHandler(int state, WifiLinkedInfo *info)
{
    (void)info;

    if (state > 0)
    {
        g_ConnectSuccess = 1;
        printf("callback function for wifi connect\r\n");
    }
    else
    {
        printf("connect error,please check password\r\n");
    }
    return;
}

static void OnHotspotStaJoinHandler(StationInfo *info)
{
    (void)info;
    printf("STA join AP\n");
    return;
}

static void OnHotspotStaLeaveHandler(StationInfo *info)
{
    (void)info;
    printf("HotspotStaLeave:info is null.\n");
    return;
}

static void OnHotspotStateChangedHandler(int state)
{
    printf("HotspotStateChanged:state is %d.\n", state);
    return;
}

static void WaitSacnResult(void)
{
    int scanTimeout = DEF_TIMEOUT;
    while (scanTimeout > 0)
    {
        sleep(ONE_SECOND);
        scanTimeout--;
        if (g_staScanSuccess == 1)
        {
            printf("WaitSacnResult:wait success[%d]s\n", (DEF_TIMEOUT - scanTimeout));
            break;
        }
    }
    if (scanTimeout <= 0)
    {
        printf("WaitSacnResult:timeout!\n");
    }
}

static int WaitConnectResult(void)
{
    int ConnectTimeout = DEF_TIMEOUT;
    while (ConnectTimeout > 0)
    {
        sleep(1);
        ConnectTimeout--;
        if (g_ConnectSuccess == 1)
        {
            printf("WaitConnectResult:wait success[%d]s\n", (DEF_TIMEOUT - ConnectTimeout));
            break;
        }
    }
    if (ConnectTimeout <= 0)
    {
        printf("WaitConnectResult:timeout!\n");
        return 0;
    }

    return 1;
}

static void WifiClientSTA(void)
{
    osThreadAttr_t attr;

    attr.name = "WifiSTATask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 10240;
    attr.priority = 24;

    if (osThreadNew((osThreadFunc_t)WifiSTATask, NULL, &attr) == NULL)
    {
        printf("Falied to create WifiSTATask!\n");
    }
}

APP_FEATURE_INIT(WifiClientSTA);

wifi太多了 扫不到

image-20240619153945713

Another note

sudo与文件权限

有同学在下载时, 在命令前误加了sudo, 这会导致文件/目录的权限被设置为root用户, 在vscode以bearpi普通用户登录时, 没有访问.h头文件的权限, 编写代码不能识别到头文件&&编译要加sudo

可以通过修改文件权限的方式解决

# 给所有用户可读可执行权限
sudo chmod -R 755 /path/to/your/directory