SimpleFOC + ESP32 wiring

Hi, all! got a SimpleFOC arduino shield today!
Actually I’d like to use it with ESP32, but I couldn’t find wiring diagram. Could you share it or just describe the minimal connections I have to make between ESP and the board? The connection to motor wires, encoder and motor Vin seems to be straightforward.
Thanks!

This is a little tricky. The way I’d tackle this is first decide what pins you would use with an imaginary UNO connected. Then select pins on the ESP32

The main aim is to know exactly where your solder pads are pointing at on the UNO. The solder pads are under the board and are described here: https://docs.simplefoc.com/pads_soldering
There is a separade pad guide page for board 1.3 and 2.0

SOLDER PAD PWM A = ?
SOLDER PAD PWM B = ?
SOLDER PAD PWM C = ?
SOLDER PAD ENABLE = ?
SOLDER PAD ENC A = ?
SOLDER PAD ENC B = ?
SOLDER PAD ENC I = ?
GND = ?  // you'll need to connect a ground between board and ESP

Once you have those chosen you are half way there. Then you’ll need to decide what pins to use on your ESP32

ESP PWM A = ?
ESP PWM B = ?
ESP PWM C = ?
ESP ENABLE = ?
ESP ENC A = ?
ESP ENC B = ?
ESP ENC I = ?
GND ?

Not all of the pins on ESP32 are suitable e.g. some are inputs and some are used for flash. In general I use the ones ‘in the middle’ i.e. don’t use below 16 (as some of these are used for flash and boot. and don’t use above 33 as these are inputs. The rest are input/output. I guess you could use inputs for encoders?
Probably worth reading something like this for pin selection: https://randomnerdtutorials.com/esp32-pinout-reference-gpios/

Once you’ve done those steps you just wire between as per your two pin tables

Thanks, I completely missed hardware configuration chapter for the first time.
Seems I’ve figured out how to connect, I’ll share photos when it works.

Should I connect 3.3V or 5V pins on the FOC shield for power supply? Or the only power supply is for the motor?

I also think I won’t be using encoder. I want to track subject by a camera connected to a motor using computer vision algorithms.
I think I’ll be able to implement a Sensor class https://docs.simplefoc.com/sensor_support
But this feedback loop will have a delay about 200ms. Will it be appropriate to control motor smoothly?

P.S. I think MPU6050 can be used as position sensor with fast response, but I didn’t find any examples. It’s gyro sensor can be integrated and provide quite accurate angles. Other projects are using encoders, even though MPU6050 is used here https://github.com/simplefoc/Arduino-FOC-balancer

I wouldn’t connect 3.3v / 5v from simplefoc board to esp32. Power your esp32 through USB. I don’t think simplefoc board has a BEC so you wouldn’t get anything from it.

Someone will probably correct me about the BEC!

Can you explain how you expect to use a vision algorithm instead of a traditional sensor? How will it know where the rotor is with respect to the stator?

200ms loop sounds way too slow.

You could run your motor in openloop without a sensor a bit like a stepper motor but this may run hot.
Is the vision for SLAM? That would be possible openloop but I’d probably want to close the loop with a magnetic sensor

Re. Mpu6050. It is great for balance projects. I’m not sure about using it to provide rotor angle (which is required for simplefoc algorithm). I’d be interested to see someone try this, i suspect it would only work for slow speed robot joints.

computer vision won’t provide angle of course, but it can provide the direction of rotation. But it seems to be suboptimal. I think it can’t be smooth, so stepper motor will be a much better and cheaper option for this.

No, it’s not SLAM, it’s for tracking subject with the camera.

I think I’ll end up using encoder!

By the way, I’ve just implemented sensor class for mpu 6050. The idea was to fix it to the moving part of the motor, and by integrating Gz (gyro measurements along Z-axis, perpendicular to the motor plane) we get rotation angle. Strangely, it doesn’t work, the motor moves erraticaly around initial point. If I detach MPU and lay it still, the motor rotates smoothly as expected (I’ve chosen velocity control and set low speed). I’ve double checked the measurements returned by sensor.getAngle, it seems to be correct (e.g. if I rotate the motor one turn, the angle changes by approximately 2*pi). The problem could have been in the angle direction (or sign), but I tried it both ways. May be I don’t understand what angle should return sensor class… I just do it for the sport of the thing while waiting for a magnetic encoder, but still want to make it work :slight_smile:

Interesting!
Does your new sensor class return a zero angle offset? This is the key to sensor alignment. Essentially the motor locks to a well known phase angle and then calls a few methods to establish whether absolute angle is possible (yes) and whether a search is required (no).

@Antun_Skuric is thinking about simplifying the sensor interface to make it easier for people to add new sensors.

I think sensor interface is quite straightforward already, but I don’t understand these functions, I’ve just copied them form the examples:
initRelativeZero()
initAbsoluteZero()
needsAbsoluteZeroSearch()

I’ve written init(), getAngle and getVelocity functions:

float MpuSensor::getAngle(){
// get the position value directly from the sensor
// for example

accelgyro1.getMotion6(&AccelX, &AccelY, &AccelZ, &GyroX, &GyroY, &GyroZ);
uint32_t Now = micros();
float deltat = ((Now - lastUpdate)/1000000.0f); // set integration time by time elapsed since last filter update
lastUpdate = Now;

velocity = double(GyroZ) / 32768.0 * 2000.0 / 180.0 * 3.141592;

current_angle += velocity * deltat;

return current_angle;

getVelocity is simlar.

Also I don’t understand in which order getVelocity or getAngle is called. My sensor returns velocity and then I calculate angle. Can I get sensor measurements only in getVelocity and calculate the angle in getAngle? But if getVelocity is called after getAngle (or never called at all), getAngle won’t have actual measurments and will return a calculation based on the previous one.

So ansering this question literally: no, it returns current_angle. But current angle is initialized with zero at initial point.

Yes, those functions are the source of confusion and the ones Antun wants to simplify. Did you copy the code from one of the magnetic implementations? Those are probably closest to the mpu6050.

Hey @agt,
We will at some point venture to do the same thing and it would be really cool if we can learn from what you are doing.

I am not sure if the drifting of the gyro will be too much of the issue. For foc we need really precise angle and it can be noisy but it should not drift. I hope not though, but I am pretty sure that if you use complementary filter in combination with gravity that you will be able to have some good results.

Maybe the best way would be for you to share your code, and I’ll try to point out the things that might be problematic. This really should not be a big problem to implement. You should have it running soon. I am not sure about the performance but it should at least calibrate and work for some time before it drifts too much :smiley:

P.S. we will simplify this interface but not right away though. So I would suggest you to keep the same structure. The functions you said you dont understand are a bit more specific and in your case are non needed:

// return 0 - this funciton will not be calles
MySensor::initAbsoluteZero(){
    return 0;
}
// return 0 -  not absolute sensor
MySensor::hasAbsoluteZero(){
    return 0;
}
// return 0 - doesn't need search
MySensor::needsAbsoluteZeroSearch(){
    return 0;
}

Owen, Antun, thank you for quick reply!
My code is here https://yadi.sk/d/vMuz0l2YJIJikQ?w=1
May be it’s not worth spending too much of your time, because using MPU as a sensor seems exotic. The problem is that if you use it to get angle, MPU should be fixed on a moving part of the motor. And MPU is certainly not wireless:) It’s still OK for my application (motor will rotate only ±90 deg), but it is not appropriate for most other applications.
I will be able to try to use return 0 in 3 functions only a week later.

You might be able to get round that ‘rotating’ issue with a slip ring:

Hi! I’ve replaced 3 functions mentioned eralier with return 0. Still no effect. I haven’t got encoder yet due to Chineese New Year.
I’ve got a new hypothesis: the problem could be in ESP32. In my past experience, it doesn’t work well if too many devices are connected to digital ports. 6 ports are in use in this setup. I’ll try replacing it with Arduino later.

Hey @agt,

if you download the dev branch, you will be able to use the refactored and simplified sensor class. The only function you would need to implement is the getAngle()

The dev branch has some chnages and it is not yet well documented, but in your case I think that will nto influence your application :smiley:

Let us know how it goes! :smiley:

P.S. @Owen_Williams and @David_Gonzalez are much more experts in the ESP32 domain, but I would say that esp32 has much better performance than Arduino, so you should have much better results. If you are concerned with wiring issues, this board has recently poped up on the forum, I’ve tested it and it works great :smiley:

Hi! I ended up using magnetic encoder. It was a long journey though, but it works :slight_smile:

Regarding MPU issues I think I’ll test it later, 'cause I think I had errors in motor setup code. I think it should work more or less smoothly for some applications. I’ll share it in case of success.

In my current code ESP reads command from Serial port and moves to the target angle. I faced a problem that communicating with Serial affects main control loop loopFOC severely. So I moved all my code to the second CPU core of ESP32. If my observations are generally true for other cases, it could be stated as a programming guideline that loopFOC should be executed on a dedicated core .

I still have on issue using angle control.In some cases my camera starts oscillating around the target angle: https://disk.yandex.ru/i/o8oli6yI1q5aEw
There is no oscillations without the camera. However, the camera is well balanced.
I have PID parameters set according to the example: https://docs.simplefoc.com/angle_loop
May be this oscillations could be removed by tuning some parameters?

Yeh the PID parameters will need to be tuned (differently) for load/no load.
If you are lucky then reducing the angle P term might fix it. Otherwise you’ll have to tune velocity pi as well.

The FOC and move loops have to be called very often. Great care has to be taken that communication code does not block and does not take too long, or it will interfere with the commutation. Having an ESP32 with multiple cores is a great way to solve this, of course!