ESP32-S3 Module vs Single Chip: Motor Calibration Fails Despite Identical Code

I’m experiencing an issue with motor calibration that has me puzzled. I have two different boards with ESP32-S3:

One with an ESP32-S3 module

One with an ESP32-S3 single chip

The single chip board is based on the module board design and is the next iteration in my development process. I specifically used identical pin assignments to maintain compatibility.

Both boards run identical code using the SimpleFOC library, but I’m seeing completely different behavior during motor calibration. The module version works perfectly, while the single chip version fails to drive the motor during calibration.
What I’ve checked so far:

  1. Compared the schematics - the pinning is identical between both boards

  2. Electrically measured all connections - everything is as it should be

  3. Identified one physical difference: the 100k pull-down resistors on the single chip board are placed about 13mm away from the ESP32-S3, while on the module board they’re directly at the pins

  4. Verified the enable pin has proper high level throughout operation

  5. Confirmed the DIAG pin stays low the entire time (using a TMC6300 motor driver)

  6. The entire initialization of the SimpleFOC library with driver setup completes successfully

The motor briefly moves during initialization on both boards, but fails during the calibration process only on the single chip version. For the calibration, I´m using open loop angle mode to determine CW or CCW in the first step.

Has anyone experienced similar issues with ESP32-S3 single chip vs module implementations? Could the resistor placement be causing this difference in behavior?

ESP32S3 R8 Single Chip schematic:

Hey, I’m happy you got it working!

Hi @inF1704 , welcome to SimpleFOC!

Not usually, no. I’d look elsewhere for the problem first.

The ESP32 module integrates quite a few components… have you added them all to your design when using the chip version?

In particular the oscillator and the power circuit would be things to check carefully:

This is the reference schematic from the S3 hardware design guidelines…
Did you follow this checklist? Schematic Checklist - ESP32-S3 - — ESP Hardware Design Guidelines latest documentation

Hello Richard,

Thank you for your welcome to the SimpleFOC forum/community and for your response.

Yes, I’m familiar with the design guides and have successfully developed other single ESP32-S3 boards previously. All relevant components are present on this board as well. I’m using a 40MHz crystal with 16MB external flash (the 8MB PSRAM is internal).

The rest of my program code (approximately 20,000 lines) runs perfectly fine on both boards, which leads me to believe the ESP32-S3 itself is functioning correctly. The power supply is also identical between boards, with the only difference being a self-resetting fuse instead of a standard SMD fuse.

What’s particularly curious is that the motor does move briefly during driver loading or just before - which is the same behavior observed on the module board. I’ll try a simple sketch with basic open loop angle control without any other functionality this evening.

For reference, I’m using SimpleFOC 2.3.3 in PlatformIO with the Arduino framework and PLATFORM: Espressif 32 (6.10.0) > Espressif ESP32-S3-DevKitM-1. But I’m convinced this must be hardware-related.

I enabled debug log. This is the log from the board with esp32s3 module when no calibration is found:

10:02:52.045 -> [Motor] Initializing motor system
10:02:52.111 -> [Motor] Setting up driver
10:02:52.111 -> [  2136][I][onboarding.cpp:899] process(): [Onboarding] State changed to: 
10:02:52.111 -> [  2137][W][LittleFS.cpp:77] begin(): LittleFS Already Mounted!
10:02:52.111 -> [  2149][I][onboarding.cpp:906] process(): MOTOR_CALIBRATION
10:02:52.111 -> [  2149][E][esp32-hal-spi.c:215] spiAttachMISO(): HSPI Does not have default pins on ESP32S3!
10:02:52.111 -> [  2163][I][event_broker.cpp:73] subscribe(): [EventBroker] New subscriber registered for event type 1
10:02:52.146 -> [  2172][I][event_broker.cpp:73] subscribe(): [EventBroker] New subscriber registered for event type 2
10:02:52.146 -> [  2181][I][power_manager.cpp:158] adjustMotorPower(): [Power] Motor state adjusted - State: 0
10:02:52.146 -> 
10:02:52.146 -> E (2373) ledc: ledc_set_duty(725): LEDC is not initialized
10:02:52.146 -> E (2375) ledc: ledc_update_duty(653): LEDC is not initialized
10:02:52.222 -> [Motor] Enabling driver...
10:02:52.255 -> E (2481) ledc: ledc_set_duty(725): LEDC is not initialized
10:02:52.255 -> E (2481) ledc: ledc_update_duty(653): LEDC is not initialized
10:02:52.323 -> [Motor] Driver initialized successfully
10:02:52.323 -> [Motor] Setting up sensor
10:02:52.323 -> [MT6701] Initializing sensor
10:02:52.323 -> [MT6701] Initialization complete
10:02:52.370 -> E (2581) ledc: ledc_set_duty(725): LEDC is not initialized
10:02:52.370 -> E (2581) ledc: ledc_update_duty(653): LEDC is not initialized
10:02:52.399 -> [Motor] Initial sensor angle: 0.00
10:02:52.399 -> [Motor] Sensor reading 0: 0.00
10:02:52.399 -> [Motor] Sensor reading 1: 0.00
10:02:52.434 -> [Motor] Sensor reading 2: 0.00
10:02:52.434 -> [Motor] Sensor reading 3: 0.00
10:02:52.434 -> [Motor] Sensor reading 4: 0.00
10:02:52.469 -> E (2681) ledc: ledc_set_duty(725): LEDC is not initialized
10:02:52.469 -> E (2681) ledc: ledc_update_duty(653): LEDC is not initialized
10:02:52.469 -> [Motor] Sensor reading 5: 0.00
10:02:52.469 -> [Motor] Sensor reading 6: 0.00
10:02:52.469 -> [Motor] Sensor reading 7: 0.00
10:02:52.505 -> [Motor] Sensor reading 8: 0.00
10:02:52.505 -> [Motor] Sensor reading 9: 0.00
10:02:52.505 -> [Motor] Sensor initialized successfully
10:02:52.505 -> [Motor] Setting up motor
10:02:52.505 -> MOT: Init
10:04:49.358 -> [Motor] Measurement 29: 276.12, 103.13, 187.00
10:04:49.597 -> [Motor] Measurement 30: 253.21, 78.84, 185.63
10:04:49.797 -> [Motor] Measurement 31: 230.29, 53.34, 183.05
10:04:49.985 -> [Motor] Measurement 32: 207.37, 28.33, 180.96
10:04:50.401 -> [Motor] Measurement 33: 184.45, 4.95, 180.50
10:04:50.401 -> [Motor] Measurement 34: 161.53, 340.33, 178.79
10:04:50.584 -> [Motor] Measurement 35: 138.62, 316.43, 177.81
10:04:50.757 -> [Motor] Measurement 36: 115.70, 293.50, 177.80
10:04:50.986 -> [Motor] Measurement 37: 92.78, 269.60, 176.82
10:04:51.168 -> [Motor] Measurement 38: 69.86, 245.47, 175.60
10:04:51.383 -> [Motor] Measurement 39: 46.95, 221.95, 175.00
10:04:51.559 -> [Motor] Measurement 40: 24.03, 198.12, 174.09
10:04:51.559 -> [Motor] Final offset angle: -179.93
10:04:51.559 -> MOT: MOT: Skip dir calib.
10:04:51.559 -> MOT: Skip offset calib.
10:04:51.559 -> MOT: No current sense.
10:04:51.559 -> MOT: Ready.
10:04:53.088 -> [Motor] Validating calibration
10:04:53.088 -> [Motor] Current settings - Direction: CW, Poles: 7, Zero angle: 90.07
10:04:53.583 -> [Motor] Raw start: 1416.67°, Normalized start: 336.67°
10:04:53.583 -> [Motor] Moving right - Raw target: 1506.67°, Normalized target: 66.67° (delta: +90.00°)
10:04:55.759 -> [Motor] Right position - Raw: 1506.66°, Normalized: 66.66°
10:04:55.759 -> [Motor] Right turn error: 0.02°
10:04:55.759 -> [Motor] Right turn check: OK
10:04:55.759 -> [Motor] Moving left - Raw target: 1326.66°, Normalized target: 246.66° (delta: -180.00°)
10:04:58.001 -> [Motor] Left position - Raw: 1326.61°, Normalized: 246.61°
10:04:58.001 -> [Motor] Left turn error: 0.05°
10:04:58.001 -> [Motor] Left turn check: OK
10:04:58.001 -> [Motor] Moving back - Raw target: 1416.67°, Normalized target: 336.67°
10:05:02.165 -> [Motor] End position - Raw: 1416.62°, Normalized: 336.62°
10:05:02.165 -> [Motor] Final position error: 0.05°
10:05:02.165 -> [Motor] Final position check: OK
10:05:02.165 -> [Motor] Calibration validation PASSED
10:05:02.165 -> [CalibrationStorage] Attempting to save calibration data
10:05:02.165 -> [CalibrationStorage] Cleared existing preferences
10:05:02.197 -> [CalibrationStorage] Successfully saved all calibration data
10:05:02.197 ->   Poles: 7
10:05:02.197 ->   Electrical Offset: 1.57
10:05:02.197 -> [Motor] Re-enabled motor after calibration
10:05:02.197 -> [Motor] Calibration completed successfully

And the log from the single chip esp32s3:

10:13:15.315 -> [Motor] Initializing motor system
10:13:15.346 -> [Motor] Setting up driver
10:13:15.346 -> [  2107][I][onboarding.cpp:906] process(): MOTOR_CALIBRATION
10:13:15.386 -> [  2108][W][LittleFS.cpp:77] begin(): LittleFS Already Mounted!
10:13:15.386 -> [  2119][I][event_broker.cpp:73] subscribe(): [EventBroker] New subscriber registered for event type 1
10:13:15.386 -> [  2119][E][esp32-hal-spi.c:215] spiAttachMISO(): HSPI Does not have default pins on ESP32S3!
10:13:15.386 -> [  2136][I][event_broker.cpp:73] subscribe(): [EventBroker] New subscriber registered for event type 2
10:13:15.386 -> [  2146][I][power_manager.cpp:158] adjustMotorPower(): [Power] ME (2326) ledc: ledc_set_duty(725): LEDC is not initialized
10:13:15.419 -> otor state adjusted - State: 0
10:13:15.419 -> 
10:13:15.419 -> E (2326) ledc: ledc_update_duty(653): LEDC is not initialized
10:13:15.457 -> [Motor] Enabling driver...
10:13:15.527 -> E (2435) ledc: ledc_set_duty(725): LEDC is not initialized
10:13:15.527 -> E (2435) ledc: ledc_update_duty(653): LEDC is not initialized
10:13:15.560 -> [Motor] Driver initialized successfully
10:13:15.560 -> [Motor] Setting up sensor
10:13:15.560 -> [MT6701] Initializing sensor
10:13:15.560 -> [MT6701] Initialization complete
10:13:15.627 -> E (2535) ledc: ledc_set_duty(725): LEDC is not initialized
10:13:15.627 -> E (2535) ledc: ledc_update_duty(653): LEDC is not initialized
10:13:15.660 -> [Motor] Initial sensor angle: 0.00
10:13:15.660 -> [Motor] Sensor reading 0: 0.00
10:13:15.660 -> [Motor] Sensor reading 1: 0.00
10:13:15.660 -> [Motor] Sensor reading 2: 0.00
10:13:15.694 -> [Motor] Sensor reading 3: 0.00
10:13:15.694 -> [Motor] Sensor reading 4: 0.00
10:13:15.694 -> [Motor] Sensor reading 5: 0.00
10:13:15.727 -> E (2635) ledc: ledc_set_duty(725): LEDC is not initialized
10:13:15.727 -> E (2635) ledc: ledc_update_duty(653): LEDC is not initialized
10:13:15.727 -> [Motor] Sensor reading 6: 0.00
10:13:15.727 -> [Motor] Sensor reading 7: 0.00
10:13:15.727 -> [Motor] Sensor reading 8: 0.00
10:13:15.761 -> [Motor] Sensor reading 9: 0.00
10:13:15.761 -> [Motor] Sensor initialized successfully
10:13:15.761 -> [Motor] Setting up motor
10:13:15.761 -> MOT: Init
10:13:16.280 -> MOT: Enable driver.
10:13:16.757 -> MOT: Align sensor.
10:13:19.048 -> MOT: Failed to notice movement
10:13:19.048 -> MOT: Init FOC failed.
10:13:19.048 -> [Motor] Motor initialized successfully
10:13:19.048 -> [  5787][V][Preferences.cpp:352] getUChar(): nvs_get_u8 fail: valid NOT_FOUND
10:13:19.048 -> [Motor] No valid calibration found

Ok, there is this difference and it also shows me, that me code is not robust enough and needs improvements: 10:13:19.048 → MOT: Failed to notice movement
10:13:19.048 → MOT: Init FOC failed.

The shown erros regarding ledc are maybe from initializing background brightness control of the display or led`s

Okay, I’ve got it! This is a bit embarrassing, but I had a faulty BLDC motor all along. A couple of days ago, I quickly connected a different motor for testing but didn’t place it correctly over the sensor. Today, I completely swapped the motor, and now everything is working perfectly. It was simply a defective BLDC. I’m relieved that it’s resolved, even if it was a facepalm moment. Thanks for your patience and assistance!