1355|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管理软件有几个指令,比如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();
  • }

运行效果:

播放器加载失败: 未检测到Flash Player,请到安装
38fb8c7a9bcdf283f7d894da0830c202

 

点赞 关注
 
 

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

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
福禄克有奖直播:高精度测温赋能电子制造 报名中!
直播时间:2025年2月28日(周五)上午10:00
直播主题:高精度测温赋能电子制造
小伙伴们儿快来报名直播吧~好礼等你拿!

查看 »

 
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
快速回复 返回顶部 返回列表