ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 위치 센서 (AS5600)
    Motor Control/BLDC 모터 제어 2025. 12. 1. 02:11
    반응형

    AS5600의 현재 각도, 속도 연산

    static PositionSensor_t sensor; static 연산에 주의할 것. static으로 선언되어서 main()에서 PositionSensor_t sensor를 불러 올 수 없음. PositionSensor_t *PositionSensor_GetHandle(void) 함수를 main()에서 이용해야 함. 

     

    • static → internal linkage (only visible inside its own .c file)
    • extern → external linkage (visible to other files)

     

     

    position_sensor.c

     

    #include "position_sensor.h"

    #include <stdlib.h>

    #include <math.h>

     

    #define CPR_12BIT 4096.0f

    #define TWO_PI (2.0f * M_PI)

     

    static PositionSensor_t sensor;

     

    // ------------------------------------------------------------

    // Initialization

    // ------------------------------------------------------------

    int PositionSensor_Init(void)

    {

    sensor.as5600 = AS5600_New();

    sensor.as5600->i2cHandle = &hi2c1;

     

     

    if (AS5600_Init(sensor.as5600) != HAL_OK)

    return 0;

     

    uint16_t init_angle;

    AS5600_GetAngle(sensor.as5600, &init_angle);

     

    sensor.last_angle_raw = init_angle;

    sensor.last_timestamp = __HAL_TIM_GET_COUNTER(&htim6);

     

    sensor.angle_rad = 0.0f;

    sensor.angle_prev_rad = 0.0f;

    sensor.full_rotation_offset = 0.0f;

     

    return 1;

    }

     

    // ------------------------------------------------------------

    // Update angle + velocity

    // ------------------------------------------------------------

    void PositionSensor_Update(void)

    {

    uint16_t angle_raw;

    AS5600_GetAngle(sensor.as5600, &angle_raw);

     

     

    // timestamp handling

    uint16_t now = __HAL_TIM_GET_COUNTER(&htim6);

     

    float dt_us = (now >= sensor.last_timestamp)

    ? (now - sensor.last_timestamp)

    : (0xFFFF - sensor.last_timestamp + now);

     

    float dt_s = dt_us * 1e-6f;

     

    // compute delta angle (raw 0–4095)

    float d_raw = (float)angle_raw - (float)sensor.last_angle_raw;

     

    // detect wrap-around (±0.8*CPR)

    if (fabsf(d_raw) > (0.8f * CPR_12BIT))

    sensor.full_rotation_offset += (d_raw > 0) ? -TWO_PI : TWO_PI;

     

    sensor.last_angle_raw = angle_raw;

     

    // absolute angle (multi-turn)

    float angle_now = sensor.full_rotation_offset +

    ((float)angle_raw / CPR_12BIT) * TWO_PI;

     

    sensor.angle_rad = angle_now;

    sensor.angle_deg = angle_now * (180.0f / M_PI);

     

    // velocity calc

    sensor.velocity_rad = (sensor.angle_rad - sensor.angle_prev_rad) / dt_s;

    sensor.velocity_deg = (sensor.angle_deg - sensor.angle_prev_deg) / dt_s;

     

    sensor.angle_prev_rad = sensor.angle_rad;

    sensor.angle_prev_deg = sensor.angle_deg;

     

    sensor.last_timestamp = now;

     

    }

     

    // ------------------------------------------------------------

    // Getters

    // ------------------------------------------------------------

    float PositionSensor_GetRadians(void)

    {

    return sensor.angle_rad;

    }

     

    float PositionSensor_GetRadiansMultiturn(void)

    {

    return sensor.angle_rad;

    }

     

    float PositionSensor_GetDegrees(void)

    {

    return sensor.angle_deg;

    }

     

    float PositionSensor_GetDegreesMultiturn(void)

    {

    return sensor.angle_deg;

    }

     

    float PositionSensor_GetVelocityRad(void)

    {

    return sensor.velocity_rad;

    }

     

    float PositionSensor_GetVelocityDeg(void)

    {

    return sensor.velocity_deg;

    }

     

    PositionSensor_t *PositionSensor_GetHandle(void)

    {

    return &sensor;

    }

     

     

    position_sensor.h

     

    #ifndef POSITION_SENSOR_H

    #define POSITION_SENSOR_H

     

    #include "stm32g4xx_hal.h"

    #include "as5600.h"

     

    typedef struct

    {

    AS5600_TypeDef *as5600; //as5600 : Pointer to AS5600 low-level driver structure.

     

    uint16_t last_angle_raw; // Previous raw 12-bit angle reading (0–4095).

    uint16_t last_timestamp; // Timestamp (timer ticks) of previous update.

     

    float angle_rad; // Current multi-turn angle in radians.

    float angle_deg; // Current multi-turn angle in degrees.

     

    float angle_prev_rad; // Previous angle in radians (used for velocity).

    float angle_prev_deg; // Previous angle in degrees.

     

    float velocity_rad; // Angular velocity in radians per second.

    float velocity_deg; // Angular velocity in degrees per second.

     

    float full_rotation_offset; // Number of added/subtracted 2π rotations to track multi-turn angle when wrapping occurs.

    } PositionSensor_t;

     

     

    extern I2C_HandleTypeDef hi2c1;

    extern TIM_HandleTypeDef htim6; // us timer

     

    int PositionSensor_Init(void);

    void PositionSensor_Update(void);

     

    // Simple getters for safe read-only API, Simple getters are safe

    float PositionSensor_GetRadians(void);

    float PositionSensor_GetRadiansMultiturn(void);

    float PositionSensor_GetDegrees(void);

    float PositionSensor_GetDegreesMultiturn(void);

    float PositionSensor_GetVelocityRad(void);

    float PositionSensor_GetVelocityDeg(void);

     

    // Pointer getter for advanced code (FOC loop, debugging)

    // Pointer is powerful, but external code can modify pointer values.

    // Pointer is faster than calling simple getters function

    PositionSensor_t* PositionSensor_GetHandle(void);

     

    #endif

    반응형

    'Motor Control > BLDC 모터 제어' 카테고리의 다른 글

    Timer1 for motor control (20kHz)  (0) 2025.12.02
    Uart DMA  (0) 2025.12.02
    Hardware setup for BLDC FOC control with AS5600  (0) 2025.12.02
    V/F Control  (0) 2023.04.08
Designed by Tistory.