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]))

### STM32读取JY901S陀螺仪数据的方法 为了实现STM32对JY901S陀螺仪数据的有效读取,可以采用串口通信的方式。这是因为JY901S默认通过UART接口发送固定格式的数据包[^2]。以下是具体的实现方法以及示例代码。 #### 数据帧解析 JY901S的返回数据是一个固定的11字节长度数据包。其中前两位分别是`0x55`和`0x53`作为起始标志位,用于确认数据帧的合法性。第7、8字节表示Z轴角度值,可以通过简单的移位运算将其转换为实际的角度值[^3]。 #### 示例代码 以下是一个基于STM32 HAL库的简单示例代码: ```c #include "stm32f1xx_hal.h" #define BUFFER_SIZE 11 uint8_t rx_buffer[BUFFER_SIZE]; float angle_z; void UART_Init(void) { // 初始化USART并设置波特率为115200bps huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&huart1); } void Receive_Data(void) { if (HAL_UART_Receive(&huart1, rx_buffer, BUFFER_SIZE, 100) != HAL_OK) { // 错误处理逻辑 return; } // 验证数据帧头是否合法 if (rx_buffer[0] == 0x55 && rx_buffer[1] == 0x53) { // 计算Z轴角度 int16_t raw_angle = (int16_t)(rx_buffer[7] << 8 | rx_buffer[6]); angle_z = (float)raw_angle / 32768.0 * 180.0; // 转换为度数 } } ``` 上述代码实现了以下几个功能: 1. **初始化UART**:配置USART外设以匹配JY901S的默认波特率。 2. **接收数据**:通过`HAL_UART_Receive()`函数接收完整的11字节数据包。 3. **校验与解码**:验证数据帧头部是否正确,并提取Z轴角度值进行单位转换。 #### 使用注意事项 - 确保STM32的UART引脚连接到JY901S对应的TX/RX端子上。 - 如果使用的是DMA模式,则需调整中断服务程序中的缓冲区管理部分[^4]。 - 对于其他轴(如Roll或Pitch),可参照类似的计算方式分别提取对应位置的数据[^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值