华为云IoT智慧物流案例08 | QT应用开发(C++)如何添加调用C开发的IIC设备(思路篇)

举报
实柏 发表于 2021/08/04 02:36:31 2021/08/04
【摘要】 在03章节我通过查找BH1750的Datasheet和E53拓展板原理图用i2c tools工具验证BH1750 IIC的地址编写了驱动BH1750的C代码块点击查看:华为云IoT智慧物流案例03 | 传感器、LCD屏调试 第三章 | 调试BH1750光强度传感器(题外)在04章节我通过IIC可以同时挂载多个设备的条件将温湿度传感器(SHT30)、光强度传感器(BH1750)都挂载并驱动打印...

在03章节我通过查找

现在,打开QT Creator进行开发

1. 首先我们进行UI界面上的改动,添加LabelTextEdit控件将获取到的数据显示到控件上
然后选择要显示数据控件TextEdit右键“转到槽”,选择第一个后然后在widget.cpp进行编辑
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 因为开发板STM32MP157使用的Linux系统设备树已经集成了IIC通讯协议,在QT中先添加好IIC通讯地址设备地址
与C程序对比:除了定义uint→quint外其余无改动

#define SHT30_Address                               0x44                  //SHT30地址
#define BH1750_Address                              0x23                  //0100011
#define I2C_RETRIES                                 0x0701
#define I2C_TIMEOUT                                 0x0702
#define I2C_SLAVE                                   0x0703                //IIC从器件的地址设置
#define I2C_BUS_MODE                                0x0780

unsigned int msg_flag =0;
int fd = -1;
double temperature;
double humidity;
quint8 light;
quint8 testbuf[100];
QString receive_str;

在这里插入图片描述
3. 因为设备树已经有了IIC设备的驱动程序,我们在QT开发中也可以用打开IIC设备文件的方式进行驱动。
与C程序对比:

  • 函数名格式 (类型 Widget::函数名(参数))
  • 退出线程 (exit(1); → return -1;)
//IIC_dev 初始化函数
int Widget::dev_Init(void)
{
    fd  = open("/dev/i2c-0", O_RDWR);               // open file and enable read and  write

    if (fd < 0)
    {
        perror("Can't open /dev/BH1750 \n");       // open i2c dev file fail
        return -1;
    }

    printf("open /dev/i2c-0 success !\n");          // open i2c dev file succes
}

在这里插入图片描述
4. 因为是挂载多个IIC设备,所以我分别写了两个设备初始化驱动程序让它们不在调用的相互干扰。(顺带BH1750计算光强度值的代码块)

与C程序对比:

  • 函数名格式 (类型 Widget::函数名(参数))
  • 关闭线程 ( close(fd); → ::close(fd);)
int Widget::BH1750_IIC(void)
{
    if (ioctl(fd, I2C_SLAVE,BH1750_Address) < 0)
    { //set i2c address
        printf("fail to set i2c device slave address!\n");
        ::close(fd);
        return - 1;
    }

    printf("set slave address to 0x%x success!\n", BH1750_Address);
    return (1);
}
int Widget::SHT30_IIC(void)
{
    if (ioctl(fd, I2C_SLAVE,SHT30_Address) < 0)
    { //set i2c address
        printf("fail to set i2c device slave address!\n");
        ::close(fd);
        return - 1;
    }

    printf("set slave address to 0x%x success!\n", SHT30_Address);
    return (1);
}
int Widget::BH1750_Dat_To_Lux(quint8* buf)
{
    quint16 lux = 0;
    lux = buf[0];
    lux <<=8;
    lux += buf[1];
    lux = (int)(lux / 1.2);
    return lux;
}

在这里插入图片描述
5. 最后 将main函数改写成Get_data函数,用一个QT的定时器循环调用并更新数值到UI界面中的对应控件块

与C程序对比:

  • 函数名格式 (类型 Widget::函数名(参数))
  • 没有while 由定时器定时调用
ui->temperature_text->setText(QString::number(temperature));
    ui->humidity_text->setText(QString::number(humidity));
    ui->light_text->setText(QString::number(light));
    return  0;
  • 将获取到的数据通过 ui->temperature_text->setText 设置控件进行显示
int Widget::SHT30_Get_data(void)
{
    quint8 buf[8] = {0};
    BH1750_IIC();
    usleep(1000 * 100);
    buf[0] = 0x20;
    if ( write(fd, buf, 1) != 1 ) {
        perror("faile to write config.\n");
        return -1;
    }
    buf[0] = 0;
    if (read(fd, buf, 2) != 2 ) {
        perror("faile to read back configure data.\n");
        return -1;
    }
    printf("BH1750 0x%x 0x%x \n", buf[0], buf[1] );
    light = BH1750_Dat_To_Lux(buf);
    printf("light: %5d lux\r\n",light);
    usleep(1000 * 200);
    SHT30_IIC();
    usleep(1000 * 100);
    buf[0] = 0x2C;
    buf[1] = 0x0D;
    if ( write(fd, buf, 2) != 2 ) {
        perror("faile to write config.\n");
        return -1;
    }
    buf[0] = 0;
    buf[1] = 0;
    if (read(fd, buf, 6) != 6 ) {
        perror("faile to read back configure data.\n");
        return -1;
    }
    printf("SHT30---->: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x \n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5] );
    temperature = ((float)((buf[0]<<8)+buf[1]))*175/65535-45;
    humidity = ((float)((buf[3]<<8)+buf[4]))*100/65535;
    printf("temperature:%f   humidity:%f\r\n",temperature,humidity);
    ui->temperature_text->setText(QString::number(temperature));
    ui->humidity_text->setText(QString::number(humidity));
    ui->light_text->setText(QString::number(light));
    return  0;
}

在这里插入图片描述

6. 最后我们编译构建看看,QT应用成功运行并读取到多个传感器的数值并在屏幕上显示
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

技术指导:
华为云社区与华为云学院:https://edu.huaweicloud.cn/

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。