Code an ESP for STM

I would like to adapt an ESP32 encoder-based speed measurement code for use on an STM microcontroller, integrated with PLECS blocks.

Your question is not clear. Can you better describe what exactly you are trying to accomplish? Do you have an example of the code and a description of what it does?

I can provide the following general guidance. The STM32 Target Support Package includes a Quadrature Encoder Counter block. A description of the block’s outputs, from the STM32 TSP manual:

The block output c represents the current counter value, port i represents the index pulse, and port ic outputs the latched counter value from the previous index pulse.

You can combine these three measurements to determine speed. You can review the motor drive examples in the PLECS C2000 TSP which use sensored based control approaches and include blocks which converter counts to angular speed. It sounds like you can replace this logic with your C code, perhaps in a C-Script block. Again, more information is needed for better guidance.

I’m trying to build a speed sensor using an encoder, but only one of the encoder phases is working. I have an ESP32 code that works, and I’d like to port it to PLECS so it can be used on the STM32. Here is the code.

// Informações para o cálculo de velocidade

volatile unsigned long pulses = 0; // Contador de pulsos do encoder

unsigned long lastTime; // Armazena a última vez que o RPM foi calculado

const int PPR = 1000; // Pulsos por revolução do encoder. Ajuste conforme o seu encoder.

float rpm = 0;

float vk = 0;

const unsigned long interval = 500;

int vm;

// Função para contar pulsos (deve ser chamada pela interrupção)

void countPulse() {

pulses++;

}

void setup() {

Serial.begin(115200);

// Configuração das interrupções para o encoder

// attachInterrupt(digitalPinToInterrupt(12), countPulse, RISING);

attachInterrupt(digitalPinToInterrupt(14), countPulse, RISING);

// lastTime = millis();

}

void loop() {

unsigned long now = millis();

if (now - lastTime >= interval) {

  noInterrupts();

  rpm = (float)pulses / PPR \* 60000 / (float)interval;

  pulses = 0;

  vk = rpm \* 0.104719755;

  interrupts();

  // Exibição dos dados no monitor serial

  

     

  lastTime = now; 

}

Serial.print(“pulses:”);

Serial.println(vk);

// dacWrite(26,map(vk,0,400,0,255));

}

Hello Ranieri!

ESP32-specific code cannot execute on STM32. Generic C code can be integrated in a PLECS model using the C-script block. This is an advanced block that is difficult to use.

Reading signals from a quadrature encoder should necessitate only the QEP block from the STM32 Target Support Package, and not additional code ported from an ESP32. Is this post related to your previous post ( Encoder with stm32 - #14 by Ranieri.Mazzini )? If that is the case, it would probably best to schedule a web meeting to investigate the issue.

That’s right, that was also my topic on the forum. However, the schematic you sent didn’t work with my encoder because I found out that only one channel is working. Is there a way to adapt the schematic, or is it better to buy a new, fully functional encoder and use the original schematic?

encoder-defi-edited.plecs (121.1 KB)

Hi Ranieri!

In general, there is no good alternative to reading both channels in order to determine the rotational velocity and angle of your motor.

The best approach would be to proceed with thorough debugging to isolate the issue.

Replacing your hardware would be necessary if you determine that the hardware is defective through thorough debugging. If the problem is related to something else, replacing the hardware will have no effect.

So this schematic wouldn’t work with an encoder that has both phases. Do you recommend how I should build a speed sensor using an encoder?

Is there any schematic that allows measuring speed using an encoder that has only one operational phase?

The “QEP” block in the TSP library requires two phases. Two phases are always required to determine the direction of rotation.

The “Edge counter” block in the TSP library counts pulses on one phase. If the direction of rotation is not important for your application, you could use that block to build a speed sensor.

Do you have any code or schematic using the Edge Counter block that works as a speed sensor so I can test it with my encoder? I’m having difficulty with this.

Hello Ranieri!

Because the “QEP” block and the “Edge counter” block both count edges, it is actually possible to use the same approach to estimate the speed in both cases. The only thing that needs to be taken into account is that the “Edge counter” will count four times slower if it is counting edges on one phase from a QEP. I have attached an example of a PLECS model that exemplifies how this can be accomplished.

Note: Building this PLECS model unveiled a bug in the offline simulation model of the “Edge counter” block that is triggered under very particular circumstances. A fix for that bug will be released with STM32 TSP 1.5.5 next week. Thank you for your help in uncovering that bug!

speed_estimate_using_edge_counter.plecs (123.9 KB)

When I rotate my encoder manually, I am getting these signals on the scope. I’m also attaching a photo of the connections I made.

Hello Ranieri!

That is indeed a wrong result!

It looks to me like the position and speed calculation block that I sent you (which originally came from one of our demo models) only calculates speeds between -pi and pi [rad/s].

Aside from this speed calculation subsystem in one of our demo models, we don’t provide a ready-made block that will convert the QEP or Edge Counter count value to speed. That is something that engineers need to build themselves using the blocks available in PLECS.

To calculate the angular velocity, you will need to transform the pulse count to an angle and then calculate a discrete-time derivative of that value. Because you are using a discrete counter to determine the angle, you may also consider introducing low-pass filtering in your sensor readout (that needs to be designed carefully though!).

To implement the derivative, I would recommend using the Delay (z^-1) block.

Do you have any additional tips on how to convert these signals into speed? I’m out of ideas and unable to figure it out.

Hello Ranieri,

I attached a PLECS model that implements rudimentary angular speed computation.

We also released STM32 TSP 1.5.5 today, which includes a fix for the offline model of the Edge Counter block.

basic_speed_caculator.plecs (105.9 KB)

So by combining these two codes, will I be able to measure the speed? Because when I use this new schematic you sent, the values read from the encoder are strange

Hello Ranieri

Designing a PLECS schematic to measure the speed is the responsibility of the user. Converting edge counts to speed is not built-in feature of PLECS.

The second circuit simply converts counter ticks to an angle, takes the difference of the angle and the angle delayed by a period T, and divides that difference by the delay period T in order to compute the slope (which mimics the derivative). This is a very rudimentary approach, and deviations from the true speed will be noticeable if the counter incrementation is small in the time period T, or when the counter wraps back to zero.

Since the position is varying from π to -π, I thought about using a simple derivative block to obtain the speed from it, but it didn’t work. Do you have any idea how to go from position to speed?