Moving code from ESP8266 to ESP32

A while ago I made a mashup of Dan Royer's code CNC 2 Axis Demo with my own code for trapezoidal motion stepper and servo control for ESP8266.

I assumed porting the code to the ESP32 would be trivial, and that was true for the most part: changes like library name being Wifi.h instead of Wifi8266.h were not a problem. UDP now does not like multicharacter writes but you can use print instead. So far so good.

However, when it came to the interrupt code I was stuck with the stepper interrupt causing an exception sometimes. And to make things weirder, the servo interrupt worked flawlessly (both of them had the IRAM_ATTR directive if you ask me).

Going little by little, I could narrow down the culprit to a floating point operation during the interrupt, that would cause problems sometimes but not always. Browsing around I found this post. Where the solution was simple: do not use floats within the interrupt routines but doubles. The reason was the float calculation would be performed by…

Better accuracy from your encoder without more interrupts

Since I published my DC motor control project on youmagine I have got some feedback from users with 2000 PPR (pulses per revolution) encoders or more where they end up having trouble above 3000 RPM. The reason is that the poor Arduino cannot process the interrupts fast enough and the system becomes unreliably.

While optical encoders are available quite cheaply, some of the magnetic sensors from AMS are very competitive and offer very good accuracy (from 12 to 16 bits). One interesting model (due to its low price) is the AS5600, that provides a 12bit angle measurement for less than $2. Measurement data is read by means of an I2C serial bus and needs no interrupts.

Hopefully those having trouble with interrupts can switch to this type of sensor, but model AS5600 is most likely a bad choice as it is intended to replace manual knobs in hi-fi equipment and it will not work at high RPMs (in fact the manufacturer does not provide the max RPM at all).

But for position control applications maximum speed will not reach more than a few hundred RPM tops and for those this cheap sensor maybe a good fit.

I contacted moti project developer who is using this same sensor for his intelligent servo and he was pleased with it.

While chip manufacturer provided an Arduino library I cut the only piece of code I was interested and copy it to my project as a simple function. Time measurement showed that a standard I2C speed (100Khz) took 0.92 milliseconds, but after pumping up the I2C clock speed I lower it to 0.22 milliseconds.

One additional thing to address if your application uses multiple turns is how you manage the wrap around of the angle measurement. It took me a while to figure it out, but within a certain bound of rotational speeds checking for a gap between previous and current value larger than 3500 did the trick for me.

Below you can see a piece of code to get you started, providing a measurement between 0 and 4095 representing an angle between 0 and 360 degrees.


The AS5600 is much cheaper than the AS5045B I used. Nice, I will buy a few :)
Miguel Sánchez said…
PLease bear in mind that max RPM is quite low (manufacturer does not provide a number). For my application this is not a problem but for other uses it may be.

Popular posts from this blog

VFD control with Arduino using RS485 link

4xiDraw: Another pen plotter

Software I2C for Arduino