I’ve been working on coding a section of a speed feedback system since Thirsday. We need a way to frequently measure the motor speed for two reasons:
- To adjust the motor speed if it deviates from the target speed
- To compute the precise time at which we need to flash the LEDs
To accomplish this, we have optical and hall sensors (we will use the sensor that gives the best precision) hooked up to our rotating PCB and our bottom fixed PCB. The rotating PCB is the one sending the commands to flash the LEDs, and the bottom is the one sending Dshot to our ESC.
Therefore we need to have code which stores the time difference between each rising edge generated by our sensor (hall or optical). Friday we started coding this for ESP32 with Marc, because at this time we were trying to see if we could do everything with our ESP32 on the bottom PCB, and not use a STM32. Since there was problems sending dshot with the ESP32 (see this post ), we figured we might as well code this on the STM32.
I used the input capture functionality provided by the STM32 timers. It works in a very similar way to PWM:
- We choose a timer and a channel, and connect the input signal coming from the sensor to that channel
- We choose a value for the timer frequency
F, using a prescaler. The prescaler is a value on 16 bits, and will divided the frequency coming from the APB, which was 42MHz in our case.
Fmust divide the APB frequency.
- A 16 bit counter will increment every
- Every time there is a rising edge coming from the channel: the value of the counter gets stored in a register, the counter resets to 0, and a callback is called in which we can fetch the value stored in the register
With a 16 bit counter, the maximum frequency we can use which also divides 42MHz is 600KHz . This is because the minimum RPS (Rotations Per Second) we want to be able to measure is 10 RPS, so the counter must last 0.1s before overflowing. With this frequency, the minimum amount of counter ticks we get is 20000 : this is when we rotate at 30 RPS, which is the maximum speed we want.
A petal covers around 5 degrees, so 20000 ticks per turn means 4000 ticks of precision per petal, which is more than enough.
The timer can also call a callback when the timers overflows: an overflow basically means for us that the motor is spinning at less than 10 RPS, which is enough information.
To test my program, I generated a signal using PWM which simulates a sensor: it changes its period to simulate different motor speed, and has a duty cycle of 100us. I computed the different periods of my signal, and computed the time measured by the input capture, and I got at most a difference of 3us . 3us of error per turn translates to an error of 3 thousands of a petal, which again is more than enough.
Next step is to set up our hall and optical sensors to integrate this with the Dshot signal sender Xavier and Sibille just finished.