热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ESP32gl9306光流计使用

esp-idf本身已经集成好了uart,我们只需要按照gl9306的数据格式处理即可gl9306_driver.h#includestdint.h***briefDevic

esp-idf 本身已经集成好了uart,我们只需要按照gl9306的数据格式处理即可

gl9306_driver.h

#include "stdint.h"/*** @brief Device descriptor*/
typedef struct{int uart_num;int gpio_num;int refresh_freq;int buf_size;int height;//int16_t delta_x;//int16_t delta_y;int16_t speed_x;int16_t speed_y;int16_t current_x;int16_t current_y;int squal;
}gl9306_uart_t;/*** @brief Initialize device* * @param uart */
void init_uart(gl9306_uart_t *uart);/*** @brief Data process* * @param uart * @return void* */
void* sub_thread_rx(gl9306_uart_t *uart);/*** @brief Get current accumulated x* * @param uart * @return int16_t */
int16_t get_current_x(gl9306_uart_t *uart);/*** @brief Get current accumulated y* * @param uart * @return int16_t */
int16_t get_current_y(gl9306_uart_t *uart);/*** @brief Get speed of x axis* * @param uart * @return int16_t */
int16_t get_speed_x(gl9306_uart_t *uart);/*** @brief Get speed of y axis* * @param uart * @return int16_t */
int16_t get_speed_y(gl9306_uart_t *uart);

gl9306_driver.c

#include "gl9306_driver.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "pthread.h"#define DEFAULT_BUF_SIZE 512
#define DEFAULT_REFRESH_FREQ 50static char* TAG = "GL9306_DRIVER";static int sub_thread_status=0;void init_uart(gl9306_uart_t *uart){uart->current_x = 0;uart->current_y = 0;if(!uart->buf_size){uart->buf_size = DEFAULT_BUF_SIZE;ESP_LOGW(TAG, "Buffer size undefined,using default:%d", DEFAULT_BUF_SIZE);}if(!uart->refresh_freq){uart->refresh_freq = DEFAULT_REFRESH_FREQ;ESP_LOGW(TAG, "Refresh freq undefined,using default:%d", DEFAULT_REFRESH_FREQ);}uart_config_t uart_cOnfig= {.baud_rate = 19200,.data_bits = UART_DATA_8_BITS,.parity = UART_PARITY_DISABLE,.stop_bits = UART_STOP_BITS_1,.flow_ctrl = UART_HW_FLOWCTRL_DISABLE};uart_param_config(uart->uart_num, &uart_config);uart_set_pin(uart->uart_num, UART_PIN_NO_CHANGE, uart->gpio_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);uart_driver_install(uart->uart_num, uart->buf_size * 2, 0, 0, NULL, 0);pthread_t sub_thread;pthread_create(&sub_thread, NULL, sub_thread_rx, uart);
}void* sub_thread_rx(gl9306_uart_t *uart){int time_sleep = 1000/uart->refresh_freq;uint8_t* data = (uint8_t*) malloc(uart->buf_size + 1);while(1){const int rxBytes = uart_read_bytes(uart->uart_num, data, uart->buf_size, 10 / portTICK_RATE_MS);if(rxBytes > 0){data[rxBytes] = 0;//printf("%s\n", data);if(data[0]==0xfe){uint8_t check_sum = data[2] + data[3] + data[4] + data[5];if(check_sum == data[6]){uart->speed_x = data[2] + (data[3]<<8);uart->speed_y = data[4] + (data[5]<<8);uart->current_x = uart->current_x - uart->speed_x;uart->current_y = uart->current_y + uart->speed_y;uart->squal = data[7];}}}//if(data){// free(data);//}vTaskDelay(time_sleep / portTICK_PERIOD_MS);}return &sub_thread_status;
}int16_t get_current_x(gl9306_uart_t *uart){return uart->current_x;
}int16_t get_current_y(gl9306_uart_t *uart){return uart->current_y;
}int16_t get_speed_x(gl9306_uart_t *uart){return - uart->speed_x;
}int16_t get_speed_y(gl9306_uart_t *uart){return uart->speed_y;
}

注意get_speed_x()中return 有负号,这个根据实际模块安装的朝向调整即可.

严格来说get_speed_x()和get_speed_y(),两个函数返回的并非速度,具体参考官方文档

如何使用这个库:

app_main.c

#include "pthread.h"
#include "gl9306_driver.h"//GL9306 定义
#define UART_NUM UART_NUM_1
#define UART_RXD_PIN 15
#define BUF_SIZE 512#define REFRESH_FREQ 50static const char* TAG = "app_imu";static gl9306_uart_t uart;static int sub_thread_status = 0;/*** @brief gl9306 uart initialization*/
void init_gl9306(){uart.uart_num = UART_NUM;uart.gpio_num = UART_RXD_PIN;uart.refresh_freq = REFRESH_FREQ;uart.buf_size = BUF_SIZE;init_uart(&uart);
}void* sub_thread(){int sleep_time = 1000/REFRESH_FREQ;while(1){speed_x = get_speed_x(&uart);speed_y = get_speed_y(&uart);coord_x = get_current_x(&uart);coord_y = get_current_y(&yart);printf("x:%d\ty:%d\tsx:%d\tsy:%d\n",coord_x,coord_y,speed_x,speed_y);vTaskDelay(time_sleep /portTICK_PERIOD_MS);}
}void app_main(){init_gl9306();pthread_t threads;pthread_create(&threads, NULL, sub_thread, NULL);}

可以通过hmc5883l或者mpu6050进行数据融合处理获取任意姿态下的坐标。相关融合根据简单的三角函数和卡尔曼滤波就能实现。

代码没有进过验证,是从在做的项目里抠出来的,可能会报错,按道理应该好修


推荐阅读
  • 该楼层疑似违规已被系统折叠隐藏此楼查看此楼*madebyebhrz*#include#include#include#include#include#include#include ... [详细]
  • 本文介绍了使用C++Builder实现获取USB优盘序列号的方法,包括相关的代码和说明。通过该方法,可以获取指定盘符的USB优盘序列号,并将其存放在缓冲中。该方法可以在Windows系统中有效地获取USB优盘序列号,并且适用于C++Builder开发环境。 ... [详细]
  • Linux 中使用 clone 函数来创建线程
    2019独角兽企业重金招聘Python工程师标准Linux上创建线程一般使用的是pthread库实际上libc也给我们提供了创建线程的函数那就是cloneintclone(i ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 使用C++编写程序实现增加或删除桌面的右键列表项
    本文介绍了使用C++编写程序实现增加或删除桌面的右键列表项的方法。首先通过操作注册表来实现增加或删除右键列表项的目的,然后使用管理注册表的函数来编写程序。文章详细介绍了使用的五种函数:RegCreateKey、RegSetValueEx、RegOpenKeyEx、RegDeleteKey和RegCloseKey,并给出了增加一项的函数写法。通过本文的方法,可以方便地自定义桌面的右键列表项。 ... [详细]
  • 流数据流和IO流的使用及应用
    本文介绍了流数据流和IO流的基本概念和用法,包括输入流、输出流、字节流、字符流、缓冲区等。同时还介绍了异常处理和常用的流类,如FileReader、FileWriter、FileInputStream、FileOutputStream、OutputStreamWriter、InputStreamReader、BufferedReader、BufferedWriter等。此外,还介绍了系统流和标准流的使用。 ... [详细]
  • STM32 IO口模拟串口通讯
    转自:http:ziye334.blog.163.comblogstatic224306191201452833850647前阵子,调项目时需要用到低波 ... [详细]
  • Linux线程的同步和互斥
    目录1、线程的互斥2、可重入VS线程安全3、线程的同步1、线程的互斥 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • tcpdump 4.5.1 crash 深入分析
    tcpdump 4.5.1 crash 深入分析 ... [详细]
  • Question该提问来源于开源项目:react-native-device-info/react-native-device-info ... [详细]
author-avatar
百脑汇惠州店_956
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有