McFly Cobothon


Reading time: about 3 minutes

Joined a robotics hackathon with a coworker. 36 hours of embedded development. The end result was a BLDC motor controller.

Magnetic encoder to motor driver

This is some kind of half-step pattern to drive the motor efficiently.

Param 1 Param 2 In-W In-V In-U PWM1 PWM2 PWM3
1 1     0 High    
2 0   1     Low  
3 0 1         Low
1 1     0 High    
2 1   0     High  
3 0 1         Low
1 0     1 Low    
2 1   0     High  
3 0 1         Low
1 0     1 Low    
2 1   0     High  
3 1 0         High
1 0     1 Low    
2 0   1     Low  
3 1 0         High
1 1     0 High    
2 0   1     Low  
3 1 0         High

In our sleep-deprived state, we managed to turn it into this lookup-table based code.

static uint8_t EncoderHallState(void)
{
    // Read C6, C7, C8 as digital
    uint8_t c6 = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_6);
    uint8_t c7 = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7);
    uint8_t c8 = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_8);

    return (c6 << 2) | (c7 << 1) | c8;
}

bool motor_u_lookup[] = { false, false, true, true, true, false };
bool motor_v_lookup[] = { true, false, false, false, true, true };
bool motor_w_lookup[] = { true, true, true, false, false, false };

uint8_t motor_next_lookup[] = { 4, 5, 1, 3, 2, 6 };

static uint8_t ApplyControl(uint8_t enc, uint16_t pwm)
{
    uint8_t u_val = enc >> 2;
    uint8_t v_val = (enc >> 1) & 1;
    uint8_t w_val = enc & 1;

    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, u_val ? GPIO_PIN_SET : GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, v_val ? GPIO_PIN_SET : GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, w_val ? GPIO_PIN_SET : GPIO_PIN_RESET);

    size_t j = pwm;

    TIM1->CCR1 = u_val ? 0 : j;
    TIM1->CCR2 = v_val ? 0 : j;
    TIM1->CCR3 = w_val ? 0 : j;
}

static void MoveNext(uint16_t pwm, bool backwards)
{
    uint8_t current = EncoderHallState();
    uint8_t i = 0;

    if (backwards)
    {
        for (size_t c = 0; c < 6; c++)
        {
            if (motor_next_lookup[c] == current)
            {
                i = (c + 5) % 6;
                break;
            }
        }
    }
    else
    {
        for (size_t c = 0; c < 6; c++)
        {
            if (motor_next_lookup[c] == current)
            {
                i = (c + 1) % 6;
                break;
            }
        }
    }

    uint8_t next = motor_next_lookup[i];
    ApplyControl(next, pwm);
}

Citation

If you find this work useful, please cite it as:
@article{yaltirakli,
  title   = "McFly Cobothon",
  author  = "Yaltirakli, Gokberk",
  journal = "gkbrk.com",
  year    = "2024",
  url     = "https://www.gkbrk.com/mcfly-cobothon"
}
Not using BibTeX? Click here for more citation styles.
IEEE Citation
Gokberk Yaltirakli, "McFly Cobothon", October, 2024. [Online]. Available: https://www.gkbrk.com/mcfly-cobothon. [Accessed Oct. 19, 2024].
APA Style
Yaltirakli, G. (2024, October 19). McFly Cobothon. https://www.gkbrk.com/mcfly-cobothon
Bluebook Style
Gokberk Yaltirakli, McFly Cobothon, GKBRK.COM (Oct. 19, 2024), https://www.gkbrk.com/mcfly-cobothon

Comments

© 2024 Gokberk Yaltirakli