1235|0

156

帖子

1

TA的资源

一粒金砂(中级)

楼主
 

【基于树莓派400的图像识别归类&运动检测&模拟信号处理系统第二帖】使用I2C总线读... [复制链接]

  本帖最后由 donatello1996 于 2022-10-23 21:27 编辑

【基于树莓派400的图像识别归类&运动检测&模拟信号处理系统第二帖】使用I2C总线读取MPU6050/BMP280数据并搭建QT程序进行图形化显示

 

       树莓派自带了一个I2C1的接口,引出到GPIO上,这个I2C接口功能强大,将各类I2C传感器连接,即可使用Linux系统强大的i2cdetect管理软件和ioctl()接口进行读写,检测,非常简单方便,比用单片机去读I2C简单多了,方法如下:

i2cdetect -y 1

i2cdetect管理软件有几个指令,比如i2cdump i2cset等。
 

我这边是用I2C1接口同时连接了MPU6050+BMP280+AHT20,其中AHT20的调试出了问题,温湿度读取偶尔不正常,能正常读取MPU6050和BMP280的数据,非常简单:

void MPU6050_Init()
{
    uint8_t write_data[1];

    write_data[0] = 0x07;
    I2C_Device_Write (0x68 , write_data , 1 , SMPLRT_DIV);
    //Write to sample rate register

    write_data[0] = 0x01;
    I2C_Device_Write (0x68 , write_data , 1 , PWR_MGMT_1);
    // Write to power management register

    write_data[0] = 0;
    I2C_Device_Write (0x68 , write_data , 1 , CONFIG);
    // Write to Configuration register 

    write_data[0] = 24;
    I2C_Device_Write (0x68 , write_data , 1 , GYRO_CONFIG);
    // Write to Gyro Configuration register

    write_data[0] = 0x01;
    I2C_Device_Write (0x68 , write_data , 1 , INT_ENABLE);
    //Write to interrupt enable register

}
int BMP280_Init()
{
    uint8_t ret , i2c_read_data[2];
    I2C_Device_Read(I2C_ADDR_BMP280 , &ret , 1 , 0xd0);
    if (ret == 0x58)
    {

        I2C_Device_Read(I2C_ADDR_BMP280 , i2c_read_data , 2 , 0x88);
        dig_t1 = i2c_read_data[1] << 8 | i2c_read_data[0];

        I2C_Device_Read(I2C_ADDR_BMP280 , i2c_read_data , 2 , 0x8a);
        dig_t2 = i2c_read_data[1] << 8 | i2c_read_data[0];

        I2C_Device_Read(I2C_ADDR_BMP280 , i2c_read_data , 2 , 0x8c);
        dig_t3 = i2c_read_data[1] << 8 | i2c_read_data[0];

        I2C_Device_Read(I2C_ADDR_BMP280 , i2c_read_data , 2 , 0x8e);
        dig_p1 = i2c_read_data[1] << 8 | i2c_read_data[0];

        I2C_Device_Read(I2C_ADDR_BMP280 , i2c_read_data , 2 , 0x90);
        dig_p2 = i2c_read_data[1] << 8 | i2c_read_data[0];

        I2C_Device_Read(I2C_ADDR_BMP280 , i2c_read_data , 2 , 0x92);
        dig_p3 = i2c_read_data[1] << 8 | i2c_read_data[0];

        I2C_Device_Read(I2C_ADDR_BMP280 , i2c_read_data , 2 , 0x94);
        dig_p4 = i2c_read_data[1] << 8 | i2c_read_data[0];

        I2C_Device_Read(I2C_ADDR_BMP280 , i2c_read_data , 2 , 0x96);
        dig_p5 = i2c_read_data[1] << 8 | i2c_read_data[0];
        I2C_Device_Read(I2C_ADDR_BMP280 , i2c_read_data , 2 , 0x98);
        dig_p6 = i2c_read_data[1] << 8 | i2c_read_data[0];

        I2C_Device_Read(I2C_ADDR_BMP280 , i2c_read_data , 2 , 0x9a);
        dig_p7 = i2c_read_data[1] << 8 | i2c_read_data[0];

        I2C_Device_Read(I2C_ADDR_BMP280 , i2c_read_data , 2 , 0x9c);
        dig_p8 = i2c_read_data[1] << 8 | i2c_read_data[0];

        I2C_Device_Read(I2C_ADDR_BMP280 , i2c_read_data , 2 , 0x9e);
        dig_p9 = i2c_read_data[1] << 8 | i2c_read_data[0];

        return 0;
    }
    return -1;
}

 

I2C的读写函数也是可以直接使用ioctl()函数接口的,非常方便:

int I2C_Device_Write(uint8_t i2c_dev_addr , uint8_t s[] , int len , uint8_t reg_addr)
{
    int i;
    if ((i2c2_fd = open(I2C_INTER_DEVICE , O_RDWR))<0)
    {
        qDebug("Fail to open i2c-2 device\n");
        return 1;
    }
    ioctl(i2c2_fd , I2C_TIMEOUT , 2);
	ioctl(i2c2_fd , I2C_RETRIES , 1);

    i2c2.nmsgs = 1;
    i2c2.msgs = (struct i2c_msg*)malloc(i2c2.nmsgs * sizeof(struct i2c_msg));
    if(!i2c2.msgs)
    {
        qDebug("malloc error\n");
        return 2;
    }
        
    i2c2.nmsgs = 1;
    i2c2.msgs[0].len = 1 + len;
    i2c2.msgs[0].addr = i2c_dev_addr;
    i2c2.msgs[0].flags = 0;
    i2c2.msgs[0].buf = (unsigned char*)malloc(1 + len);
    i2c2.msgs[0].buf[0] = reg_addr;
    memcpy(i2c2.msgs[0].buf + 1 , s , len);
    if(ioctl(i2c2_fd , I2C_RDWR , &i2c2) < 0)
    {
        qDebug("Write failed.\n");
        for(i = 0 ; i < i2c2.nmsgs ; i ++)
        {
            free(i2c2.msgs.buf);
        }
        free(i2c2.msgs);
        close(i2c2_fd);
        return 3;
    }
    else 
    {
        qDebug("Write success.\n");
        for(i = 0 ; i < i2c2.nmsgs ; i ++)
        {
            free(i2c2.msgs.buf);
        }
        free(i2c2.msgs);
        close(i2c2_fd);
        return 0;
    }
}

int I2C_Device_Read(uint8_t i2c_dev_addr , uint8_t read_data[] , int len , uint8_t reg_addr)
{
    int i;
    if ((i2c2_fd = open(I2C_INTER_DEVICE , O_RDWR))<0)
    {
        qDebug("Fail to open %s device\n" , I2C_INTER_DEVICE);
        return 1;
    }
    ioctl(i2c2_fd , I2C_TIMEOUT , 2);
	ioctl(i2c2_fd , I2C_RETRIES , 1);

    i2c2.nmsgs = 2;
    i2c2.msgs = (struct i2c_msg*)malloc(i2c2.nmsgs * sizeof(struct i2c_msg));
    if(!i2c2.msgs)
    {
        qDebug("malloc error\n");
        return 2;
    }
    (i2c2.msgs[0]).len = 1;
    (i2c2.msgs[0]).addr = i2c_dev_addr;
    (i2c2.msgs[0]).flags = 0;
    (i2c2.msgs[0]).buf = (unsigned char*)malloc(1);
    (i2c2.msgs[0]).buf[0] = reg_addr;

    (i2c2.msgs[1]).len = len;
    (i2c2.msgs[1]).addr = i2c_dev_addr;
    (i2c2.msgs[1]).flags = I2C_M_RD;
    (i2c2.msgs[1]).buf = (unsigned char*)malloc(len);
    (i2c2.msgs[1]).buf[0] = 0;
    if(ioctl(i2c2_fd , I2C_RDWR , &i2c2) < 0)
    {
        qDebug("Read failed.\n");
        for(i = 0 ; i < i2c2.nmsgs ; i ++)
        {
            free(i2c2.msgs.buf);
        }
        free(i2c2.msgs);
        close(i2c2_fd);
        return 3;
    }
    else 
    {
        memcpy(read_data , i2c2.msgs[1].buf , len);

        for(i = 0 ; i < i2c2.nmsgs ; i ++)
        {
            free(i2c2.msgs.buf);
        }
        free(i2c2.msgs);
        close(i2c2_fd);
        return 0;
    }
}

 

将此代码代入到QT程序中,并使用QVector3D和QPainter实现正立方体和仪表盘:


QVector3D:
Cube3D::Cube3D(QWidget *parent) : QWidget(parent)
{
    //          7------------------4
    //        /                 /  |
    //     3------------------0    |
    //     |                  |    |
    //     |                  |    |
    //     |                  |    |
    //     |                  |    |
    //     |    6             |    5
    //     |                  |  /
    //     2------------------1
    //立方体前后四个顶点,从右上角开始顺时针
    vertexArr = QVector<QVector3D>{
        QVector3D{1, 1, 1},
        QVector3D{1, -1, 1},
        QVector3D{-1, -1, 1},
        QVector3D{-1, 1, 1},

        QVector3D{1, 1, -1},
        QVector3D{1, -1, -1},
        QVector3D{-1, -1, -1},
        QVector3D{-1, 1, -1}};

    //六个面,一个面包含四个顶点
    elementArr = QVector<QVector<int>>{
        {0, 1, 2, 3},
        {4, 5, 6, 7},
        {0, 4, 5, 1},
        {1, 5, 6, 2},
        {2, 6, 7, 3},
        {3, 7, 4, 0}};

    //Widget默认没有焦点,此处设置为点击时获取焦点
    setFocusPolicy(Qt::ClickFocus);
    startTimer(50);
}

 




QPainter:

void TBP::Dashboard(int value1,int value2,int value3,
                    QColor qc1,QColor qc2,QColor qc3)
{
    int i;
    if(value1 < 0)value1 = 0;
    if(value1 > 100)value1 = 100;
    if(value2 < 0)value2 = 0;
    if(value2 > 100)value2 = 100;
    static const QPoint secondHand[3] =
    {
        QPoint(4,17),
        QPoint(-4,17),
        QPoint(0, -100)
    };
    static const QPoint secondHand1[3] =
    {
        QPoint(2,17),
        QPoint(-2,17),
        QPoint(0, -50)
    };
    qpainter->restore();
    qpainter->save();
    qpainter->rotate(0);
    QColor qc4(220 , 220 , 220);
    qpainter->fillRect(-250 , -250 , 500 , 500 , qc4);
    qpainter->restore();
    qpainter->save();
    qpainter->rotate(-156);
    for(i = 0 ; i <= 100 ; i++)
    {
        qpainter->rotate(3);
        if(i % 10 == 0 && i > 0)
        {
            qpainter->setPen(Qt::black);
            qpainter->drawLine(0,-130,1,-110);
            qpainter->drawLine(1,-130,0,-110);
            qpainter->drawLine(0,-130,0,-110);
            qpainter->drawLine(1,-130,1,-110);
        }
        else qpainter->setPen(Qt::blue);
        qpainter->drawLine(0,-130,0,-120);
    }
    qpainter->rotate(0);
    for(i = 0 ; i <= 20 ; i++)
    {
        qpainter->rotate(3);
        qpainter->setPen(QColor(255,255,0));
        qpainter->drawLine(0,-130,0,-110);
    }
    qpainter->setPen(Qt::black);
    QRectF rect1(-130 , -130 , 260, 260);
    qpainter->drawEllipse(rect1);
    QRectF rect2(-129 , -129 , 258, 258);
    qpainter->drawEllipse(rect2);
    QRectF rect3(-131 , -131 , 262, 262);
    qpainter->drawEllipse(rect3);
    QRectF rect4(-131 , -131 , 261, 261);
    qpainter->drawEllipse(rect4);
    QRectF rect5(-129 , -129 , 259, 259);
    qpainter->drawEllipse(rect5);

    qpainter->restore();
    qpainter->save();
    qpainter->rotate(-153 + value1 * 3);
    qpainter->setPen(qc1);
    qpainter->setBrush(qc1);
    qpainter->drawEllipse(-5,-5,10,10);
    qpainter->drawConvexPolygon(secondHand,3);

    qpainter->restore();
    qpainter->save();
    qpainter->rotate(-153+value2*3);
    qpainter->setPen(qc2);
    qpainter->setBrush(qc2);
    qpainter->drawEllipse(-5,-5,10,10);
    qpainter->drawConvexPolygon(secondHand,3);

    qpainter->restore();
    qpainter->save();
    qpainter->rotate((-value3)*3/5+804);
    qpainter->setPen(qc3);
    qpainter->setBrush(qc3);
    qpainter->drawEllipse(-5,-5,10,10);
    qpainter->drawConvexPolygon(secondHand1,3);

    qpainter->restore();
    qpainter->save();
    qpainter->setFont(QFont("Arial",12,QFont::Bold));
    qpainter->drawText(-80,125,"0");
    qpainter->drawText(-135,80,"10");
    qpainter->drawText(-160,13,"20");
    qpainter->drawText(-155,-22,"25");
    qpainter->drawText(-142,-58,"30");
    qpainter->drawText(-90,-113,"40");
    qpainter->drawText(-18,-135,"50");
    qpainter->drawText(125,-40,"75");
    qpainter->drawText(70,122,"100");

    qpainter->setPen(qc3);
    qpainter->setFont(QFont("Arial",8,QFont::Light));
    qpainter->drawText(-60,80,"990");
    qpainter->drawText(-15,100,"1040");
    qpainter->drawText(30,80,"1090");

    qpainter->setPen(Qt::darkBlue);
    qpainter->setBrush(Qt::darkBlue);
    qpainter->rotate(-146);
    for(i = 0 ; i <= 2950 ; i++)
    {
        qpainter->rotate(0.1);
        qpainter->drawLine(0,-180,0,-160);
    }
    QRectF rect9(-10, -180, 20, 20);
    qpainter->drawEllipse(rect9);

    qpainter->setPen(Qt::cyan);
    qpainter->setBrush(Qt::yellow);
    qpainter->rotate(-295);
    QRectF rect10(-10, -180, 20, 20);
    qpainter->drawEllipse(rect10);
    for(i = 0 ; i <= 2000 ; i++)
    {
        qpainter->rotate(0.1);
        qpainter->drawLine(0,-180,0,-160);
    }
    qpainter->drawEllipse(rect10);

    QWidget::update();
}

运行效果:

38fb8c7a9bcdf283f7d894da0830c202

 

点赞 关注
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表