当前位置: 首页 > news >正文

姿态传感器(学习笔记上)

上节我们学的是温湿传感器,这节我们学的是姿态传感器,虽然都是传感器,但是它们还是有很大的区别的,这节的传感器我们通过学习可知,开发板上的姿态传感器型号是QMI8658C,内部集成3轴加速度传感器和3轴陀螺仪传感器,支持SPI和I2C通信,在我们的开发板上使用的是I2C通信,ESP32-C3只有1个I2C外设,我们开发板上的所有I2C设备,都使用一个I2C通信接口,通过I2C设备的地址,来决定和谁通信,QMI8658C的I2C地址是0x6A,这个项目,我们将最终完成测量XYZ三个轴的角度,把角度数据通过串口传输到终端

接着,我们要进行编写QMI8658C驱动程序

这个和温湿传感器大致相似,也是使用sample project作为模板,们复制esp-idf-v5.1.3\examples\get-started\sample_project这个工程到我们的实验文件夹,然后把这个文件夹的名称修改为attitude,attitude是姿态的意思。

接着,进行我们经常的操作,在vscode中打开attitude文件夹,我们先点击打开attitude工程目录下的CMakeList.txt文件,修改工程的名称为attitude,然后保存关闭此文件(这步一般来说是我们的第一步,也就是我们的文件名)

project(attitude)

我们这个项目需要用到I2C通信,现在我们把温湿度例程里面的myi2c.h和myi2c.c文件复制到attitude工程中的main目录下,然后我们点开main目录下的CMakeLists.txt文件,可以看到myi2c.c文件已经添加到编译路径

idf_component_register(SRCS "myi2c.c" "main.c"INCLUDE_DIRS ".")

点击打开qmi8658c.h文件,在最上面添加#pragma once

#pragma once

点击打开qmi8658c.c文件,在最上面添加包含qmi8658c.h文件

#include "qmi8658c.h"

点击打开main.c文件,添加头文件

#include "myi2c.h"
#include "qmi8658c.h"

在app_main函数中,先调用I2C初始化函数

void app_main(void)
{ESP_ERROR_CHECK(i2c_master_init());ESP_LOGI(TAG, "I2C initialized successfully");
}

函数里使用到了ESP_LOGI,需要包含esp_log.h头文件

#include "esp_log.h"

还需要给ESP_LOGI里面的TAG定义一下

static const char *TAG = "MAIN";

接下来,开始写qmi8658c的驱动函数,通过课程视频学习,我们先写两个读取qmi8658c寄存器的函数和写入qmi8658c寄存器的函数,写入函数用于配置传感器的参数,读取函数用于读取传感器的寄存器数据,例如ID号,状态等,这两个函数放入qmi8658c.c文件中

esp_err_t qmi8658c_register_read(uint8_t reg_addr, uint8_t *data, size_t len)
{return i2c_master_write_read_device(I2C_MASTER_NUM, QMI8658C_SENSOR_ADDR,  &reg_addr, 1, data, len, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
}esp_err_t qmi8658c_register_write_byte(uint8_t reg_addr, uint8_t data)
{uint8_t write_buf[2] = {reg_addr, data};return i2c_master_write_to_device(I2C_MASTER_NUM, QMI8658C_SENSOR_ADDR, write_buf, sizeof(write_buf), I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
}

然后我们在qmi8658c.c文件中添加这两个函数需要的头文件

#include "driver/i2c.h"
#include "myi2c.h"

函数里面用到了QMI8658C_SENSOR_ADD,我们在qmi8658c.h文件中定义一下

#define  QMI8658C_SENSOR_ADDR       0x6A

接下来,我们需要写一个qmi8658c初始化函数,用于读取ID号,配置加速度、陀螺仪范围等参数。这个函数涉及到了qmi8658c的寄存器,所以我们先用枚举类型定义寄存器,放到qmi8658c.h文件中

enum qmi8658c_reg
{QMI8658C_WHO_AM_I,QMI8658C_REVISION_ID,QMI8658C_CTRL1,QMI8658C_CTRL2,QMI8658C_CTRL3,QMI8658C_CTRL4,QMI8658C_CTRL5,QMI8658C_CTRL6,QMI8658C_CTRL7,QMI8658C_CTRL8,QMI8658C_CTRL9,QMI8658C_CATL1_L,QMI8658C_CATL1_H,QMI8658C_CATL2_L,QMI8658C_CATL2_H,QMI8658C_CATL3_L,QMI8658C_CATL3_H,QMI8658C_CATL4_L,QMI8658C_CATL4_H,QMI8658C_FIFO_WTM_TH,QMI8658C_FIFO_CTRL,QMI8658C_FIFO_SMPL_CNT,QMI8658C_FIFO_STATUS,QMI8658C_FIFO_DATA,QMI8658C_I2CM_STATUS = 44,QMI8658C_STATUSINT,QMI8658C_STATUS0,QMI8658C_STATUS1,QMI8658C_TIMESTAMP_LOW,QMI8658C_TIMESTAMP_MID,QMI8658C_TIMESTAMP_HIGH,QMI8658C_TEMP_L,QMI8658C_TEMP_H,QMI8658C_AX_L,QMI8658C_AX_H,QMI8658C_AY_L,QMI8658C_AY_H,QMI8658C_AZ_L,QMI8658C_AZ_H,QMI8658C_GX_L,QMI8658C_GX_H,QMI8658C_GY_L,QMI8658C_GY_H,QMI8658C_GZ_L,QMI8658C_GZ_H,QMI8658C_MX_L,QMI8658C_MX_H,QMI8658C_MY_L,QMI8658C_MY_H,QMI8658C_MZ_L,QMI8658C_MZ_H,QMI8658C_dQW_L = 73,QMI8658C_dQW_H,QMI8658C_dQX_L,QMI8658C_dQX_H,QMI8658C_dQY_L,QMI8658C_dQY_H,QMI8658C_dQZ_L,QMI8658C_dQZ_H,QMI8658C_dVX_L,QMI8658C_dVX_H,QMI8658C_dVY_L,QMI8658C_dVY_H,QMI8658C_dVZ_L,QMI8658C_dVZ_H,QMI8658C_AE_REG1,QMI8658C_AE_REG2,QMI8658C_RESET = 96
};

结合QMI8658C的数据手册中的寄存器定义表格,写出这个枚举定义。枚举类型的第一个值默认是0,和寄存器WHO_AM_I的地址一样,所以不用标出,然后依次递增,遇到地址不连续的寄存器地址时,单独标出,最后的结果如上代码所示

接下来写qmi8658c初始化函数到qmi8658c.c文件

void qmi8658c_init(void)
{uint8_t id = 0;qmi8658c_register_read(QMI8658C_WHO_AM_I, &id ,1);while (id != 0x05){vTaskDelay(1000 / portTICK_PERIOD_MS);qmi8658c_register_read(QMI8658C_WHO_AM_I, &id ,1);}ESP_LOGI(TAG, "QMI8658C OK!");qmi8658c_register_write_byte(QMI8658C_RESET, 0xb0);  // 复位vTaskDelay(10 / portTICK_PERIOD_MS);qmi8658c_register_write_byte(QMI8658C_CTRL1, 0x40); // CTRL1 设置地址自动增加qmi8658c_register_write_byte(QMI8658C_CTRL7, 0x03); // CTRL7 允许加速度和陀螺仪qmi8658c_register_write_byte(QMI8658C_CTRL2, 0x95); // CTRL2 设置ACC 4g 250Hzqmi8658c_register_write_byte(QMI8658C_CTRL3, 0xd5); // CTRL3 设置GRY 512dps 250Hz
}

初始化函数里面,首先读取qmi8658c的ID号,如果不正确,就继续读,如果正确,往下执行。确定qmi8658c没有问题,先复位芯片,然后进行配置。CTRL1,配置地址自动增加后,我们读取一连串的加速度和陀螺仪数据,只写个首地址就可以连续读了。CTRL2配置加速度的量程和输出速率,CTRL3配置陀螺仪的量程和输出速率,CTRL7配置允许加速度和陀螺仪

函数里面用到了ESP_LOGI,用来输出信息,这里的TAG,需要定义。我们把这个TAG定义,放到qmi8658c.c文件中的包含头文件的下面

static const char *TAG = "QMI8658C";

函数里面使用了freeRTOS的延时函数,所以需要包含freeRTOS头文件

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

函数中也用到了ESP_LOGI宏,所以需要再添加它的头文件

#include "esp_log.h"

现在我们把这个函数的声明写到qmi8658c.h文件

extern void qmi8658c_init(void);

接下来我们在main.c文件中的app_main函数中调用这个初始化函数

void app_main(void)
{ESP_ERROR_CHECK(i2c_master_init());ESP_LOGI(TAG, "I2C initialized successfully");qmi8658c_init();
}

我们可以试编译一下,看看运行结果,依次配置VSCode左下角的配置选项,串口号、目标芯片、下载方式、menuconfig里面,把FLASH大小修改为8MB,其它不做修改。

好了,到这儿我们的姿态传感器上半部分结束!

相关文章:

姿态传感器(学习笔记上)

上节我们学的是温湿传感器,这节我们学的是姿态传感器,虽然都是传感器,但是它们还是有很大的区别的,这节的传感器我们通过学习可知,开发板上的姿态传感器型号是QMI8658C,内部集成3轴加速度传感器和3轴陀螺仪…...

labelimg使用教程

快捷键 W:调出标注的十字架,开始标注 A:切换到上一张图片 D:切换到下一张图片 del:删除标注的矩形框 CtrlS:保存标注好的标签 Ctrl鼠标滚轮:按住Ctrl,然后滚动鼠标滚轮,…...

力扣21 : 合并两个有序链表

链表style 描述: 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例: 节点大小相同时,l1的节点在前 何解? 1,遍历两个链表,挨个比较节点大小 同时遍…...

【Spring】Spring Boot 配置文件(7)

本系列共涉及4个框架:Sping,SpringBoot,Spring MVC,Mybatis。 博客涉及框架的重要知识点,根据序号学习即可。 有什么不懂的都可以问我,看到消息会回复的,可能会不及时,请见谅!! 1、配置文件作…...

《向量数据库指南》——解锁Wikipedia文章向量的跨语言搜索秘籍

嘿,各位向量数据库和AI应用的小伙伴们,我是你们的老朋友王帅旭,大禹智库的向量数据库高级研究员,也是《向量数据库指南》的作者。今天,咱们来聊聊一个超棒的数据集——百万条 Wikipedia 文章向量,这可是我在研究过程中发现的一个宝藏啊! 首先,咱们得说说这个数据集的来…...

【力扣 + 牛客 | SQL题 | 每日5题】牛客SQL热题204,201,215

1. 力扣1126:查询活跃业务 1.1 题目: 事件表:Events ------------------------ | Column Name | Type | ------------------------ | business_id | int | | event_type | varchar | | occurrences | int | --------…...

下载数据集用于图像分类并自动分为训练集和测试集方法

一、背景 最近需要用Vision Transformer(ViT)完成图像分类任务,因此查到了WZMIAOMIAO的GitHub,里面有各种图像处理的方法。而图像处理的前期工作就是获取大量的数据集,用于训练模型参数,以准确识别或分类我…...

Python xlrd库介绍

一、简介 xlrd是一个用于读取Excel文件(.xls和.xlsx格式)的Python库。它提供了一系列函数来访问Excel文件中的数据,如读取工作表、单元格的值等。 二、安装 可以使用以下命令安装xlrd库: pip install xlrd 三、使用方法 1. 导入库: 示例…...

Javascript立即执行函数

//立即执行函数 把函数的声明看作一个整体声明结束就立即调用 // (function(){console.log(hello) // })(); console.log((function (){ return 0; })()); // let afunction(){ console.log(hello) }; console.log(typeof a);//function,数组:objeck...

Linux相关概念和易错知识点(17)(文件、文件的系统调用接口、C语言标准流)

目录 1.文件 (1)文件组成和访问 (2)文件的管理 (3)C语言标准流 (4)struct file ①文件操作表 ②文件内核缓冲区 (5)Linux下一切皆文件 (…...

三防加固工业平板国产化的现状与展望

在当今全球科技竞争日益激烈的背景下,工业4.0和智能制造的浪潮推动了工业自动化设备的迅速发展,其中,三防加固工业平板电脑作为连接物理世界与数字世界的桥梁,其重要性不言而喻。所谓“三防”,即防水、防尘、防震&…...

3.1.3 看对于“肮脏”页面的处理

3.1.3 看对于“肮脏”页面的处理 文章目录 3.1.3 看对于“肮脏”页面的处理再看对于“肮脏”页面的处理MmPageOutVirtualMemory() 再看对于“肮脏”页面的处理 MmPageOutVirtualMemory() NTSTATUS NTAPI MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,PMEMORY_AREA Me…...

学 Python 还是学 Java?——来自程序员的世纪困惑!

文章目录 1. Python:我就是简单,so what?2. Java:严谨到让你头疼,但大佬都在用!3. 到底谁更香?——关于学哪门语言的百思不得姐结论——到底该选谁?推荐阅读文章 每个程序员都可能面…...

Spring Web MVC 入门

1. 什么是 Spring Web MVC Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从从⼀开始就包含在Spring框架中。它的 正式名称“SpringWebMVC”来⾃其源模块的名称(Spring-webmvc),但它通常被称为"Spring MVC". 什么是Servlet呢? Ser…...

吃牛羊肉的季节来了,快来看看怎么陈列与销售!

一、肉品陈列基本原则 (一)新鲜卫生 1、保证商品在正确的温度、正确的方式下陈列 (1)正确的温度:冷藏柜-2℃-2℃;冷冻柜库-20℃-18℃ (2)正确的方式: 商品不遮挡冷气出风口&…...

租房业务全流程管理:Spring Boot系统应用

摘要 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了租房管理系统的开发全过程。通过分析租房管理系统管理的不足,创建了一个计算机管理租房管理系统的方案。文章介绍了租房管理系统的系统分析部分&…...

GCC之编译(7)Linker链接脚本

GCC之(7)Linker链接脚本 Author: Once Day Date: 2024年10月25日 一位热衷于Linux学习和开发的菜鸟,试图谱写一场冒险之旅,也许终点只是一场白日梦… 漫漫长路,有人对你微笑过嘛… 本文档翻译自GNU LD链接脚本官方手册 参考文章: GNU LD …...

【设计模式系列】适配器模式(九)

目录 一、什么是适配器模式 二、适配器模式的角色 三、适配器模式的典型应用 四、适配器模式在InputStreamReader中的应用 一、什么是适配器模式 适配器模式(Adapter Pattern)是一种结构型设计模式,它允许将不兼容的接口转换为一个客户端…...

C# 文档打印详解与示例

文章目录 一、概述二、PrintDocument 类的使用三、PrintDialog 类的使用四、PageSetupDialog 类的使用五、PrintPreviewDialog 类的使用六、完整示例七、总结 在软件开发过程中,文档打印是一个常见的功能需求。本文将详细介绍如何在C#中实现文档打印,并给…...

Spring Cloud --- Sentinel 熔断规则

熔断规则 慢调用比例 发送10个请求,每个请求理想响应时长为200毫秒。统计1秒钟,如果10个请求响应时间超过200毫秒的比例大于等于10%,则触发熔断,熔断5秒。 异常比例 1秒内,发送请求出现异常率为20%,则触…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 ​…...

Web中间件--tomcat学习

Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...