ESP32、MicroPython、JY901S

        上接 ESP32、MicroPython、MPU6050,ESP32、MicroPython、MPU6050-优快云博客,主要是从硬件方面解决MPU6050的温漂问题,简单起见,直接更换了一款比较高级的IMU——JY901S。

一、JY901S

        JY901S是维特智能公司生产的一款基于MEMS技术的高性能三维运动姿态测量系统。包含三轴陀螺仪、三轴加速度计,三轴电子罗盘等运动传感器。该传感器集成高性能传感器和自主研发的姿态动力学核心算法引擎以及高动态卡尔曼滤波融合算法,提供了高精度、高动态、实时补偿的三轴姿态角度,通过对各类数据的灵活选择配置,满足不同的应用场景。
        模块内部自带电压稳定电路,工作电压3.3~5V,引脚电平兼容3.3V/5V的嵌入式系统,连接方便。支持串口和IIC两种数字接口。方便用户选择最佳的连接方式。串口速率4800bps~230400bps可调,IIC接口支持全速400K速率。保留4路扩展端口,可以分别配置为模拟输入,数字输入,数字输出等功能。

引脚序号引脚名称引脚功能
1D0模拟输入、数字输入输出,拉高唤醒
2Vcc电源3.3~5V
3RX串行数据输入
4TX

串行数据输出

5GND

接地

6D1模拟输入、数字输入输出、设置角度参考
7D3模拟输入、数字输入输出、角度报警输出、X-角度报警输出
8GND接地
9SDAI2C数据线、Y-角度报警输出
10SCLI2C时钟线、Y+角度报警输出
11Vcc电源3.3~5V
12D2模拟输入、数字输入输出、硬件复位、X+角度报警输出

资料来源:JY901S产品资料 · 深圳维特智能科技有限公司

二、硬件连接

JY901SESP32-S3
Vcc(2)3V3
RX(3)TX(17)
TX(4)RX(18)
GND(5)GND

三、主要程序

参考链接:树莓派4B-用串口读取JY901S陀螺仪数据-优快云博客

from machine import UART
import time

acceleration_data = [0] * 8
gyroscope_data = [0] * 8
angle_data = [0] * 8
frame_state = 0
byte_count = 0
checksum = 0

acceleration = [0.0] * 3
gyroscope = [0.0] * 3
angle = [0.0] * 3

# 加速度数据
def parse_acceleration(data):
    ax_low, ax_high = data[0], data[1]
    ay_low, ay_high = data[2], data[3]
    az_low, az_high = data[4], data[5]

    scale_acceleration = 16.0
    acc_x = (ax_high << 8 | ax_low) / 32768.0 * scale_acceleration
    acc_y = (ay_high << 8 | ay_low) / 32768.0 * scale_acceleration
    acc_z = (az_high << 8 | az_low) / 32768.0 * scale_acceleration
    if acc_x >= scale_acceleration:
        acc_x -= 2 * scale_acceleration
    if acc_y >= scale_acceleration:
        acc_y -= 2 * scale_acceleration
    if acc_z >= scale_acceleration:
        acc_z -= 2 * scale_acceleration

    return acc_x, acc_y, acc_z

# 陀螺仪数据
def parse_gyroscope(data):
    gx_low, gx_high = data[0], data[1]
    gy_low, gy_high = data[2], data[3]
    gz_low, gz_high = data[4], data[5]

    scale_gyroscope = 2000.0
    gyro_x = (gx_high << 8 | gx_low) / 32768.0 * scale_gyroscope
    gyro_y = (gy_high << 8 | gy_low) / 32768.0 * scale_gyroscope
    gyro_z = (gz_high << 8 | gz_low) / 32768.0 * scale_gyroscope
    if gyro_x >= scale_gyroscope:
        gyro_x -= 2 * scale_gyroscope
    if gyro_y >= scale_gyroscope:
        gyro_y -= 2 * scale_gyroscope
    if gyro_z >= scale_gyroscope:
        gyro_z -= 2 * scale_gyroscope

    return gyro_x, gyro_y, gyro_z

# 角度数据
def parse_angle(data):
    roll_low, roll_high = data[0], data[1]
    pitch_low, pitch_high = data[2], data[3]
    yaw_low, yaw_high = data[4], data[5]

    scale_angle = 180.0
    angle_x = (roll_high << 8 | roll_low) / 32768.0 * scale_angle
    angle_y = (pitch_high << 8 | pitch_low) / 32768.0 * scale_angle
    angle_z = (yaw_high << 8 | yaw_low) / 32768.0 * scale_angle
    if angle_x >= scale_angle:
        angle_x -= 2 * scale_angle
    if angle_y >= scale_angle:
        angle_y -= 2 * scale_angle
    if angle_z >= scale_angle:
        angle_z -= 2 * scale_angle

    return angle_x, angle_y, angle_z

# 数据处理
def process_data(input_data):
    global frame_state, byte_count, checksum, acceleration, gyroscope, angle
    global acceleration_data, gyroscope_data, angle_data

    for byte in input_data:
        if frame_state == 0:
            if byte == 0x55 and byte_count == 0:
                checksum = byte
                byte_count = 1
            elif byte in (0x51, 0x52, 0x53) and byte_count == 1:
                checksum += byte
                frame_state = byte - 0x50
                byte_count = 2
        elif frame_state in (1, 2, 3):
            if byte_count < 10:
                if frame_state == 1:
                    acceleration_data[byte_count - 2] = byte
                elif frame_state == 2:
                    gyroscope_data[byte_count - 2] = byte
                elif frame_state == 3:
                    angle_data[byte_count - 2] = byte
                checksum += byte
                byte_count += 1
            else:
                if byte == (checksum & 0xFF):
                    if frame_state == 1:
                        acceleration = parse_acceleration(acceleration_data)
                    elif frame_state == 2:
                        gyroscope = parse_gyroscope(gyroscope_data)
                    elif frame_state == 3:
                        angle = parse_angle(angle_data)
                checksum = 0
                byte_count = 0
                frame_state = 0

if __name__ == '__main__':
    uart = UART(1, baudrate=9600, tx=17, rx=18) 
    print('开始读取JY901s数据...')
    while True:
        data_buffer = uart.read(33)
        if data_buffer:
            process_data(data_buffer)
            print("角度 (度): X=%10.3f Y=%10.3f Z=%10.3f" % (angle[0], angle[1], angle[2]))

为了实现STM32F103系列微控制器驱动JY901S传感器,以下是详细的接线图和相关说明: ### 接线方式 JY901S传感器与STM32F103C8T6之间的连接主要通过串口通信(UART)实现。以下是具体的引脚连接方式: | JY901S 引脚 | STM32F103C8T6 引脚 | 说明 | |-------------|---------------------|--------------------------| | VCC | 5V | 电源正极 | | GND | GND | 电源负极、接地 | | TXD | RX1 (PA10) 或 PA3 | 发送数据线,JY901S发送数据到STM32 | | RXD | TX1 (PA9) 或 PA2 | 接收数据线,STM32接收JY901S的数据 | #### 通信引脚说明 - **TXD**:JY901S的发送引脚,用于将传感器数据发送到STM32。 - **RXD**:JY901S的接收引脚,用于接收STM32发送的指令或配置信息。 - **STM32 UART配置**:使用STM32的UART1接口(PA9为TX,PA10为RX),也可以选择其他可用的UART接口,如UART2或UART3,但需确保引脚功能与通信协议兼容。 - **电源要求**:JY901S模块需要5V电源供电,而STM32F103C8T6的I/O引脚通常支持3.3V逻辑电平。尽管JY901S的TXD输出信号可以直接连接到STM32的RX引脚,但为了确保信号完整性,建议在RXD引脚上使用电平转换电路或限流电阻[^1]。 ### 硬件连接示例 - 使用杜邦线将JY901S的VCC引脚连接到STM32F103C8T6的5V电源引脚。 - 将JY901S的GND引脚连接到STM32F103C8T6的GND引脚。 - 将JY901S的TXD引脚连接到STM32的RX1(PA10)或PA3。 - 将JY901S的RXD引脚连接到STM32的TX1(PA9)或PA2。 ### 软件配置 - 在STM32的程序中,需要配置UART通信参数,例如波特率为9600或115200(具体取决于JY901S的出厂设置)。 - 接收中断或DMA可用于高效处理JY901S发送的数据流。 - 如果需要发送配置命令到JY901S(例如调整输出频率或数据格式),可以通过UART发送相应的指令。 ### 注意事项 - **电磁干扰**:JY901S的Z轴容易受到磁场干扰,因此应将其远离电机或其他强磁场源,以确保数据的准确性[^2]。 - **电源稳定性**:确保JY901S和STM32F103C8T6的电源稳定,避免电压波动影响通信和传感器数据的准确性。 - **通信协议**:JY901S通常使用自定义的二进制协议进行数据传输,需解析数据包以获取姿态角度等信息。 ### 示例代码 以下是一个简单的UART初始化代码片段,用于STM32F103C8T6与JY901S通信: ```c #include "stm32f10x.h" void UART1_Init(void) { // 使能GPIO和UART1时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE); // 配置PA9为TX,PA10为RX GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStruct); // 配置UART1 USART_InitTypeDef USART_InitStruct; USART_InitStruct.USART_BaudRate = 9600; USART_InitStruct.USART_WordLength = USART_WordLength_8b; USART_InitStruct.USART_StopBits = USART_StopBits_1; USART_InitStruct.USART_Parity = USART_Parity_No; USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_Init(USART1, &USART_InitStruct); // 使能UART1 USART_Cmd(USART1, ENABLE); } // 接收数据中断处理函数 void USART1_IRQHandler(void) { if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { uint8_t data = USART_ReceiveData(USART1); // 处理接收到的数据 } } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值