SimpleFOClibrary support for ESP32 boards

Hey @dab,

If I understood correctly your ESP32 is restarting randomly? If so, my first guess is that your power supply is not being able to deliver enough power (this is sometimes typical when using wifi and bluetooth). How are you powering the DevKit?

There a lot quirks with some of the pins. This is a great guide to know which pins to use and which pins to avoid: https://randomnerdtutorials.com/esp32-pinout-reference-gpios/

I’m powering the esp32 via my Dell USB 3.1, which on the papers should give at least 1 Amp. but i didn’t measure that. But the strange thing is that when using INDEX reading, it seems the reset loop depends on the motor position…
I’ve tried different pins, but if there is a “set of pins” which work for sure, it would be nice to put it here, avoiding everyone to read all the esp32 pins behaviour.

Thanks for helping, Davide.

It should be enough powering via USB, but I’ve seen different behavior powering from an external source. When you’re not using the Index reading does it work as expected? What GPIO are you using for the index?

I’d tried to establish if this is a hardware (e.g power) issue or software issue. Not sure if you are using Arduino ide or platformio (i use the latter) but for software issues you typically see a guru meditation error message in the logs + register dump then a reboot.

Can you tell us which pins work and which do not?

I’ve found some spare time to do some testing.

Summary: ESP32 + DRV8302 + AMT102-V + DX2205-2300kv BLMotor.
esp32 is the common devkit, also known as wroom-32.
AMT102 is set at 512 ppr, and powered from VIN pin (5vdc)
Since this motor becomes neatly hot, I’m powering from a lab unit, set at 12V - max 5A.

// DRV8302 pins connections
#define INH_A 25
#define INH_B 26
#define INH_C 27

#define EN_GATE 14
#define M_PWM 18
#define M_OC 19
#define OC_ADJ 21

// AMT102
#define EN_A_pin 23
#define EN_B_pin 22
#define EN_X_pin 5

// motor instance
BLDCMotor motor = BLDCMotor(INH_A, INH_B, INH_C, 7, EN_GATE);

// encoder instance
Encoder encoder = Encoder(EN_A_pin, EN_B_pin, 512, EN_X_pin);

// Settings:
motor.voltage_power_supply = 12;
motor.voltage_sensor_align = 0.5;
motor.velocity_index_search = 3;
motor.PID_velocity.P = 0.01;
motor.PID_velocity.I = 1.0;
motor.voltage_limit = 2.0;
motor.PID_velocity.output_ramp = 50;
motor.P_angle.P = 1.0;
motor.velocity_limit = 50;

RESULT:
With these pin and settings there is a good calibration and in 10 tries no reset loop (guru meditation).
but sometimes, in position mode, after being still in a position for 3-5 seconds, it suddenly try to go somewhere at exagerate speed, asking for exagerate Current (my lab unit clamp it at 5A…) and I can only reset the board to stop it…

I’ve done a Video which reproduce the behaviour.
After calibration i set new position to 62, then to 0, then to 62 and 0 again, then there is an error on the serial, but it doesn’t seem a guru meditation, and the motor flyies away.
I’m looking to how post the video…

EDIT:
here’s the link:

Copy and paste from the terminal (I’m programming via Arduino…)

MOT: Monitor enabled!
MOT: Init pins.
MOT: PWM config.
MOT: Enable.
MOT: Align sensor.
MOT: Absolute zero align.
MOT: Searching...
MOT: Success!
MOT: Motor ready.
Motor ready.
Set the target angle using serial terminal:
Target : 62.00
Target : 0.00
Target : 62.00
Target : 0.00
ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x12 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:10864
load:0x40080400,len:6432
entry 0x400806b8
MOT: Monitor enabled!
MOT: Init pins.
MOT: PWM config.
MOT: Enable.
MOT: Align sensor.
MOT: Absolute zero align.
MOT: Success!
MOT: Motor ready.
Motor ready.
Set the target angle using serial terminal:

I’m starting to think that it could be just some PID setting problem…
now I lowered the I value to 0.1 (from 1.0) while K=20.0. Movement is precise, and it seems the motor doesn’t run away anymore…
so:
P=0.01
I=0.1
K=20.0
R=300
L=50
F=0.01 (I really don’t understand what this changes…)

So now I’m going to try to implement my own up/down acceleration ramps although I think that should be a VERY interesting addon for this library…

Do you have any suggestion on my numbers, or on the esp32 pins I used?
Thanks again, Davide.

2300KV motors do not like to run slowly! They’ll pull a lot of current. I’m using 100-200KV gimbals which have a resistance of 10ohms. I reckon your motors resistance will be about 0.5ohms - hence the high current. It’s not a problem if your power supply and board can handle it.

By the way - I’d recommend tuning in velocity mode and getting that sweet before moving on to angle mode as the angle PID relies on a well tuned velocity PID and it’s hard to do both at the same time.

L=50
F=0.01 (I really don’t understand what this changes…)

What is L? - that isn’t a config value I’m aware of? F is probably Tf - which is the amount of smoothing done on velocity. You’ve only got 512cpr which is quite low so if you ask for instantaneous speed it’ll come out like this 839, 0, 0, 0, 842, 0, 0, 0, 0, 845 as most ‘loops’ in program happen without your encoder ticking over. With this smoothing the speed will look more like 242, 220, 200, 180, 246, 220, 200, 180, 243. The PID loop finds it easier to deal with this smoothed velocity but it is adding lag so you don’t want it to high.

Thanks for your suggestions.

Those letters are for changing values on the fly. Taken from an example:

 List of commands:
    - P: velocity PID controller P gain
    - I: velocity PID controller I gain
    - D: velocity PID controller D gain
    - R: velocity PID controller voltage ramp
    - F: velocity Low pass filter time constant
    - K: angle P controller P gain
    - N: angle P controller velocity limit
    - L: system voltage limit
    - C: control loop
      - 0: voltage
      - 1: velocity
      - 2: angle
    - V: get motor variables
      - 0: currently set voltage
      - 1: current velocity
      - 2: current angle
      - 3: current target value
1 Like

All your pins seem fine. GPIO 5 will output a PWM signal on boot, but this shouldn’t cause you any problems.

Your L (voltage limit) is too high. Specially for motors with a really small winding resistance you want to set this to nice limit as to not draw to much current. I set a value that I know my motor will be able to handle and not get too hot.

You can modify the acceleration ramp by changing R, it’s in termos of voltage over seconds. You can play changing this value and see the different behaviors.

Ops, my fault, I’ve confused L with N…
I’ve set L (voltage limit) to 1.0 (with 12V input) to make all the tests and N=50 which is the “angle velocity limit”.

In Velocity mode, my P and I settings seem to work ok, sudden speed changes are done as expected. the only bed thing happening is sometime, without any special reason, the motor run away, asking for exagerate current, even with the voltage limit set at 1.0
This happens with the INDEX. if I don’t use the index everything is ok…

Hey @dab

What you are describing now might be really a software bug.
Does this happen only when you set the position to 0?

I’ll have to investigate this behavior but it might be that the index handling routine is the one which is responsible for this.

I had tested it extensively but I did not use a motor which is as fast as yours and maybe the vibrations around the 0 (where index is located) are causing it to skip count. I am sure but this might be it.

To verify this:
Could you please include motor.monitor() in your arduino loop() and show us the serial output when this happens.
What should happen is a sudden jump in motor position.

I understand your intuition. I’m trying that right now, and after some movements in which the error doesn’t happen while going back and forth to zero (I can see the first number, which I guess is the current position, slowly oscillating from -0.0xx to +0.0xx), i started it again and made a video, in which at the first movement after calibration, giving 5 as the destination, the motor suddenly run away asking more than 5 Amps from the power supply.
You can see it here, and you can hear the motor when it runs away.

and this is my setup:

Then, another strange thing happens with this setup:
depending on the motor position when starting to calibrate, the ESP32 goes into a reset infinite loop like this:
MOT: Monitor enabled!
MOT: Init pins.
MOT: PWM config.
MOT: Enable.
MOT: Align sensor.
Guru Meditation Error: Core 1 panic’ed (Coprocessor exception)
Core 1 register dump:
PC : 0x400d27e9 PS : 0x00060031 A0 : 0x800d10cd A1 : 0x3ffbeb50
A2 : 0x3ffc1444 A3 : 0x00000001 A4 : 0xfffffffb A5 : 0x00000000
A6 : 0x00000008 A7 : 0x00000001 A8 : 0xfffffffd A9 : 0x3ffbebf0
A10 : 0xfffffffb A11 : 0x00000000 A12 : 0x00000000 A13 : 0x3ffc1de8
A14 : 0x00000003 A15 : 0x00000000 SAR : 0x00000005 EXCCAUSE: 0x00000004
EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000
Core 1 was running in ISR context:
EPC1 : 0x400d27e9 EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x40083835

ELF file SHA256: 0000000000000000000000000000000000000000000000000000000000000000

Backtrace: 0x400d27e9:0x3ffbeb50 0x400d10ca:0x3ffbec40 0x40080f79:0x3ffbec60 0x40081715:0x3ffbec80 0x401059af:0x3ffbc5a0 0x400d87c7:0x3ffbc5c0 0x400915f5:0x3ffbc5e0 0x40090079:0x3ffbc600

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x12 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:10864
load:0x40080400,len:6432
entry 0x400806b8
MOT: Monitor enabled!
MOT: Init pins.
MOT: PWM config.
MOT: Enable.
MOT: Align sensor.
Guru Meditation Error: Core  1 panic'ed (Coprocessor exception)
Core 1 register dump:
PC      : 0x400d27e9  PS      : 0x00060031  A0      : 0x800d10cd  A1      : 0x3ffbeb50  
A2      : 0x3ffc1444  A3      : 0x00000001  A4      : 0xfffffffb  A5      : 0x00000000  
A6      : 0x00000008  A7      : 0x00000001  A8      : 0xfffffffd  A9      : 0x3ffbebf0  
A10     : 0xfffffffb  A11     : 0x00000000  A12     : 0x00000000  A13     : 0x3ffc1de8  
A14     : 0x00000003  A15     : 0x00000000  SAR     : 0x00000005  EXCCAUSE: 0x00000004  
EXCVADDR: 0x00000000  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000  
Core 1 was running in ISR context:
EPC1    : 0x400d27e9  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x40083835

ELF file SHA256: 0000000000000000000000000000000000000000000000000000000000000000

Backtrace: 0x400d27e9:0x3ffbeb50 0x400d10ca:0x3ffbec40 0x40080f79:0x3ffbec60 0x40081715:0x3ffbec80 0x401059af:0x3ffbc5a0 0x400d87c7:0x3ffbc5c0 0x400915f5:0x3ffbc5e0 0x40090079:0x3ffbc600

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x12 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:10864
load:0x40080400,len:6432
entry 0x400806b8
MOT: Monitor enabled!
MOT: Init pins.
MOT: PWM config.
MOT: Enable.
MOT: Align sensor.

until i slightly turn the motor by hand changing the starting position, then the calibration goes as expected…

hey @dab, from what I can see on the video it seems like a problem of the index handling

Here are the docs pages for monitoring and motor commands.

So from what I can see from the video it seems like an index handling problem. But it is very hard to see on the video because it happens so fast.
Could you please dump the contents of your serial monitor to a file and post it here somehow. That would be very helpful!

You could remove motor.monitor(); and put something like this in the loop.

Serial.print(motor.voltage_q);
Serial.print("\t");
Serial.print(motor.target);
Serial.print("\t");
Serial.println(motor.shaft_angle);
Serial.print("\t");
Serial.println(motor.shaft_velocity);

It would be interesting to see the velocity and angle measurement.

The coprocessor exception, from googling seems to be caused by trying to use the coprocessor (fpu) in an interrupt routine.

You can’t do float operations but can do doubles (as that is done in software)
I reckon the cause is this line in encoder.cpp

pulse_counter = round((float)pulse_counter/(float)cpr)*cpr;

Try a double cast instead of float.

Esp32 also gets upset if interrupt takes too long.

Tomorrow I should have more time to test. Thanks.

That’s very interesting. I’m using esp32 since a lot, and never heard about this.
I still didn’t read the source, so I don’t feel yet confortable
at changing it. But I’m ready to do tests, and have 3 very different BLDC motors to test.

Floats use the FPU while doubles are calculated in software. For reasons, using the FPU inside an interrupt handler is currently not supported.

Above quote is from esp32 forum here

I presume you’ve attached encode.handleIndex() to an interrupt on esp32. This function uses floats as I mentioned above.

Mentioned and solved HERE thanks!