├── Hardware └── MKS ESP32 FOC V2.0_SCH.pdf ├── README.md ├── Test Code ├── 10_Hall_Motor_close_loop_position_example │ └── 10_Hall_Motor_close_loop_position_example.ino ├── 11_close_loop_velocity_example │ └── 11_close_loop_velocity_example.ino ├── 12_close_loop_position_example │ └── 12_close_loop_position_example.ino ├── 13_SimpleFOCStudio_M0_bluetooth │ ├── 13_SimpleFOCStudio_M0_bluetooth.ino │ ├── simpleFOCStudio_dist.7z.001 │ ├── simpleFOCStudio_dist.7z.002 │ └── simpleFOCStudio_dist.7z.003 ├── 14_dual_inline_current_sense_test │ └── 14_dual_inline_current_sense_test.ino ├── 1_open_loop_velocity_example │ └── 1_open_loop_velocity_example.ino ├── 2_open_loop_position_example │ └── 2_open_loop_position_example.ino ├── 3_dual_as5600_test │ └── 3_dual_as5600_test.ino ├── 4_close_loop_velocity_example │ └── 4_close_loop_velocity_example.ino ├── 5_close_loop_position_example │ └── 5_close_loop_position_example.ino ├── 6_AS5047P_ABI_example │ └── 6_AS5047P_ABI_example.ino ├── 7_AS5047P_SPI_example │ └── 7_AS5047P_SPI_example.ino ├── 8_hallsensor_test │ ├── 8_hallsensor_test │ └── 8_hallsensor_test.ino ├── 9_Hall_Motor_close_loop_velocity_example │ └── 9_Hall_Motor_close_loop_velocity_example.ino └── Read Before You Begin.txt ├── User Manual └── User Manual └── image ├── FireShot Capture 874 - MKS ESP32 FOC EN v2.png ├── MKS ESP32 FOC V2.0.png └── image /Hardware/MKS ESP32 FOC V2.0_SCH.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makerbase-motor/MKS-ESP32FOC/23525e415933be639629f6fef85e250789b69289/Hardware/MKS ESP32 FOC V2.0_SCH.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MKS ESP32 FOC V2.0 2 | ## This page is for MKS ESC32 FOC V2.0, which is different from MKS ESC32 FOC V1.0, please be careful to distinguish. 3 | ### [If your motherboard is MKS ESP32 FOC V1.0, please click here to jump.](https://github.com/makerbase-motor/MKS-ESP32FOC/tree/MKS-ESP32-FOC-V1.0) 4 | MKS ESP32 FOC is an integrated motherboard designed based on simple FOC, which supports dual motor control. 5 | 6 | ![mks ESP32 FOC V2.0](https://github.com/makerbase-motor/MKS-ESP32FOC/blob/MKS-ESP32-FOC-V2.0/image/MKS%20ESP32%20FOC%20V2.0.png) 7 | 8 | ![Compare](https://github.com/makerbase-motor/MKS-ESP32FOC/blob/MKS-ESP32-FOC-V2.0/image/FireShot%20Capture%20874%20-%20MKS%20ESP32%20FOC%20EN%20v2.png) 9 | 10 | ## How to buy 11 | [Aliexpress Store](https://vi.aliexpress.com/item/3256805324882671.html?gatewayAdapt=glo2vnm) 12 | 13 | 14 | -------------------------------------------------------------------------------- /Test Code/10_Hall_Motor_close_loop_position_example/10_Hall_Motor_close_loop_position_example.ino: -------------------------------------------------------------------------------- 1 | // MKS ESP32 FOC V2.0 | Hall Motor Close Loop Position Example | Library:SimpleFOC 2.2.1 | Hardware:MKS ESP32 FOC V2.0 2 | 3 | // !!!Notice!!! 4 | //①Enter T+position in the serial port window to make the two motors rotate in a closed loop. For example, if you want both motors to rotate 180°, enter the radian system: T3.14 5 | //②When using your own motor, please remember to modify the default pole pair number, that is, the value in BLDCMotor() and HallSensor(), and set it to your own pole pair number. 6 | //③The default power supply voltage of the program is 24V. If you use other voltages, please remember to modify the values ​​in the voltage_power_supply and voltage_limit variables. 7 | //④If you want to achieve better results or use other motors, please adjust the PID parameters yourself 8 | 9 | #include 10 | //18——Corresponding to the pin SCL_0 11 | //19——Corresponding to the pin SDA_0 12 | //15——Corresponding to the pin I_0 13 | //1——Pole pairs 14 | HallSensor sensor = HallSensor(18, 19, 15, 1);// U V W Pole pairs 15 | void doA(){sensor.handleA();} 16 | void doB(){sensor.handleB();} 17 | void doC(){sensor.handleC();} 18 | //5——Corresponding to the pin SCL_0 19 | //23——Corresponding to the pin SDA_0 20 | //13——Corresponding to the pin I_0 21 | //1——Pole pairs 22 | HallSensor sensor1 = HallSensor(5, 23, 13, 1); // U V W Pole pairs 23 | void doA1(){sensor1.handleA();} 24 | void doB1(){sensor1.handleB();} 25 | void doC1(){sensor1.handleC();} 26 | 27 | //Motor parameters Set the number of pole pairs according to the motor 28 | BLDCMotor motor = BLDCMotor(1); 29 | BLDCDriver3PWM driver = BLDCDriver3PWM(32, 33, 25, 22); 30 | 31 | BLDCMotor motor1 = BLDCMotor(1); 32 | BLDCDriver3PWM driver1 = BLDCDriver3PWM(26, 27, 14, 21); 33 | 34 | //Command settings 35 | float target_velocity = 0; 36 | Commander command = Commander(Serial); 37 | void doTarget(char* cmd) { command.scalar(&target_velocity, cmd); } 38 | 39 | void setup() { 40 | sensor.init(); 41 | sensor1.init(); 42 | sensor.enableInterrupts(doA, doB, doC); 43 | sensor1.enableInterrupts(doA1, doB1, doC1); 44 | 45 | 46 | //Connect the motor object and the sensor object 47 | motor.linkSensor(&sensor); 48 | motor1.linkSensor(&sensor1); 49 | 50 | //Supply voltage setting [V] 51 | driver.voltage_power_supply = 24; 52 | driver.init(); 53 | 54 | driver1.voltage_power_supply = 24; 55 | driver1.init(); 56 | //Connect the motor and driver objects 57 | motor.linkDriver(&driver); 58 | motor1.linkDriver(&driver1); 59 | 60 | // aligning voltage [V] 61 | motor.voltage_sensor_align = 3; 62 | // index search velocity [rad/s] 63 | motor.velocity_index_search = 3; 64 | 65 | //Motion control mode settings 66 | motor.controller = MotionControlType::angle; 67 | motor1.controller = MotionControlType::angle; 68 | 69 | //Speed ​​PI loop settings 70 | motor.PID_velocity.P = 0.005; 71 | motor1.PID_velocity.P = 0.005; 72 | motor.PID_velocity.I = 0.1; 73 | motor1.PID_velocity.I = 0.1; 74 | motor.PID_velocity.D = 0; 75 | motor1.PID_velocity.D = 0; 76 | //Angle P loop setting 77 | motor.P_angle.P = 20; 78 | motor1.P_angle.P = 20; 79 | //Maximum motor limiting voltage 80 | motor.voltage_limit = 6; 81 | motor1.voltage_limit = 6; 82 | 83 | motor.PID_velocity.output_ramp = 1000; 84 | motor1.PID_velocity.output_ramp = 1000; 85 | 86 | //速度低通滤波时间常数 87 | motor.LPF_velocity.Tf = 0.01f; 88 | motor1.LPF_velocity.Tf = 0.01f; 89 | 90 | //设置最大速度限制 91 | motor.velocity_limit = 45; 92 | motor1.velocity_limit = 45; 93 | 94 | Serial.begin(115200); 95 | motor.useMonitoring(Serial); 96 | motor1.useMonitoring(Serial); 97 | 98 | 99 | //初始化电机 100 | motor.init(); 101 | motor1.init(); 102 | //初始化 FOC 103 | motor.initFOC(); 104 | motor1.initFOC(); 105 | command.add('T', doTarget, "target velocity"); 106 | 107 | Serial.println(F("Motor ready.")); 108 | Serial.println(F("Set the target velocity using serial terminal:")); 109 | } 110 | 111 | 112 | 113 | void loop() { 114 | motor.loopFOC(); 115 | motor1.loopFOC(); 116 | 117 | motor.move(target_velocity); 118 | motor1.move(target_velocity); 119 | 120 | command.run(); 121 | // sensor.update(); 122 | // sensor1.update(); 123 | 124 | // Serial.print(sensor1.getAngle()); 125 | // Serial.print("\t"); 126 | // Serial.println(sensor1.getVelocity()); 127 | } 128 | -------------------------------------------------------------------------------- /Test Code/11_close_loop_velocity_example/11_close_loop_velocity_example.ino: -------------------------------------------------------------------------------- 1 | // MKS ESP32 FOC V2.0 | Current Close Loop Velocity Example | Library:SimpleFOC 2.2.1 | Hardware:MKS ESP32 FOC V2.0 & MKS AS5600 2 | 3 | // !!!Notice!!! 4 | // ①Enter "A+number" in the serial port to set the speed of the M0 motor. For example, if you enter "A10", the speed of the M0 motor will be set to 10rad/s. Enter "B+number" to set the speed of the M1 motor. 5 | // ②When using your own motor, be sure to modify the default number of pole pairs, that is, the value in BLDCMotor(7), to the number of pole pairs of your own motor. 6 | // ③Please set the correct voltage_limit and current_limit values ​​according to the selected motor. It is recommended to set the values ​​between 0.5 and 1.0 for the aircraft model motor and below 4 for the gimbal motor. Excessive voltage and current may burn out the driver board! 7 | // ④The pid parameters of this routine can control the 2808 model aircraft motor. If you want to achieve better results or use other motors, please adjust the pid parameters yourself. 8 | 9 | #include 10 | 11 | //Motor Instance 12 | BLDCMotor motor1 = BLDCMotor(7); 13 | BLDCDriver3PWM driver1 = BLDCDriver3PWM(32, 33, 25, 12); 14 | 15 | BLDCMotor motor2 = BLDCMotor(7); 16 | BLDCDriver3PWM driver2 = BLDCDriver3PWM(26, 27, 14, 12); 17 | 18 | //Encoder Instance 19 | MagneticSensorI2C sensor1 = MagneticSensorI2C(AS5600_I2C); 20 | TwoWire I2Cone = TwoWire(0); 21 | MagneticSensorI2C sensor2 = MagneticSensorI2C(AS5600_I2C); 22 | TwoWire I2Ctwo = TwoWire(1); 23 | 24 | // Inline Current sensing Instance 25 | InlineCurrentSense current_sense1 = InlineCurrentSense(0.01, 50.0, 39, 36); 26 | InlineCurrentSense current_sense2 = InlineCurrentSense(0.01, 50.0, 35, 34); 27 | 28 | // commander command Instance 29 | Commander command = Commander(Serial); 30 | void doMotor1(char* cmd) { 31 | command.motor(&motor1, cmd); 32 | } 33 | void doMotor2(char* cmd) { 34 | command.motor(&motor2, cmd); 35 | } 36 | 37 | //Setting the alarm voltage 38 | #define UNDERVOLTAGE_THRES 11.1 39 | void board_init(); 40 | float get_vin_Volt(); 41 | 42 | void setup() { 43 | Serial.begin(115200); 44 | board_init(); 45 | 46 | // Encoder Settings 47 | I2Cone.begin(19, 18, 400000UL); // AS5600_M0 48 | I2Ctwo.begin(23, 5, 400000UL); // AS5600_M1 49 | sensor1.init(&I2Cone); 50 | sensor2.init(&I2Ctwo); 51 | 52 | //Connect the motor object and the sensor object 53 | motor1.linkSensor(&sensor1); 54 | motor2.linkSensor(&sensor2); 55 | 56 | // Drive Settings 57 | driver1.voltage_power_supply = get_vin_Volt(); 58 | driver1.init(); 59 | motor1.linkDriver(&driver1); 60 | driver2.voltage_power_supply = get_vin_Volt(); 61 | driver2.init(); 62 | motor2.linkDriver(&driver2); 63 | 64 | // Current Limitation 65 | motor1.current_limit = 0.5; 66 | motor2.current_limit = 0.5; 67 | 68 | // Voltage Limitation 69 | motor1.voltage_limit = 0.5; 70 | motor2.voltage_limit = 0.5; 71 | 72 | 73 | // Current Sensing 74 | current_sense1.init(); 75 | // current_sense1.gain_b *= 1; 76 | // current_sense1.gain_a *= 1; 77 | // current_sense1.skip_align = true; 78 | motor1.linkCurrentSense(¤t_sense1); 79 | 80 | // current sense init and linking 81 | current_sense2.init(); 82 | // current_sense2.gain_b *= 1; 83 | // current_sense2.gain_a *= 1; 84 | // current_sense2.skip_align = true; 85 | motor2.linkCurrentSense(¤t_sense2); 86 | 87 | // Control loop 88 | // Other modes TorqueControlType::voltage TorqueControlType::dc_current 89 | motor1.torque_controller = TorqueControlType::foc_current; 90 | motor1.controller = MotionControlType::velocity; 91 | motor2.torque_controller = TorqueControlType::foc_current; 92 | motor2.controller = MotionControlType::velocity; 93 | 94 | motor1.voltage_sensor_align = 5; 95 | motor2.voltage_sensor_align = 5; 96 | 97 | // FOC current control PID parameters 98 | motor1.PID_current_q.P = 1; 99 | motor1.PID_current_q.I = 500; 100 | motor1.PID_current_d.P = 1; 101 | motor1.PID_current_d.I = 500; 102 | motor1.LPF_current_q.Tf = 0.002; // 1ms default 103 | motor1.LPF_current_d.Tf = 0.002; // 1ms default 104 | 105 | motor2.PID_current_q.P = 1; 106 | motor2.PID_current_q.I = 500; 107 | motor2.PID_current_d.P = 1; 108 | motor2.PID_current_d.I = 500; 109 | motor2.LPF_current_q.Tf = 0.002; // 1ms default 110 | motor2.LPF_current_d.Tf = 0.002; // 1ms default 111 | 112 | // Speed ​​loop PID parameters 113 | motor1.PID_velocity.P = 0.021; 114 | motor1.PID_velocity.I = 0.12; 115 | motor1.PID_velocity.D = 0; 116 | 117 | motor2.PID_velocity.P = 0.021; 118 | motor2.PID_velocity.I = 0.12; 119 | motor2.PID_velocity.D = 0; 120 | // default voltage_power_supply 121 | 122 | // Speed ​​Limit 123 | motor1.velocity_limit = 20; 124 | motor2.velocity_limit = 20; 125 | 126 | // Monitor interface settings 127 | // comment out if not needed 128 | motor1.useMonitoring(Serial); 129 | motor2.useMonitoring(Serial); 130 | 131 | // Monitor related settings 132 | motor1.monitor_downsample = 0; 133 | motor1.monitor_variables = _MON_TARGET | _MON_VEL | _MON_ANGLE | _MON_CURR_Q; 134 | motor2.monitor_downsample = 0; 135 | motor2.monitor_variables = _MON_TARGET | _MON_VEL | _MON_ANGLE | _MON_CURR_Q; 136 | 137 | //Motor initialization 138 | motor1.init(); 139 | // align encoder and start FOC 140 | motor1.initFOC(); 141 | 142 | motor2.init(); 143 | // align encoder and start FOC 144 | motor2.initFOC(); 145 | 146 | // Initial target value 147 | motor1.target = 0.0; 148 | motor2.target = 0.0; 149 | 150 | // Mapping motors to commanders 151 | command.add('A', doMotor1, "motor 1"); 152 | command.add('B', doMotor2, "motor 2"); 153 | 154 | Serial.println(F("Double motor sketch ready.")); 155 | 156 | _delay(1000); 157 | } 158 | 159 | 160 | void loop() { 161 | motor1.loopFOC(); 162 | motor2.loopFOC(); 163 | 164 | motor1.move(); 165 | motor2.move(); 166 | 167 | command.run(); 168 | } 169 | 170 | void board_init() { 171 | pinMode(32, INPUT_PULLUP); 172 | pinMode(33, INPUT_PULLUP); 173 | pinMode(25, INPUT_PULLUP); 174 | pinMode(26, INPUT_PULLUP); 175 | pinMode(27, INPUT_PULLUP); 176 | pinMode(14, INPUT_PULLUP); 177 | 178 | analogReadResolution(12); //12bit 179 | 180 | float VIN_Volt = get_vin_Volt(); 181 | while (VIN_Volt <= UNDERVOLTAGE_THRES) { 182 | VIN_Volt = get_vin_Volt(); 183 | delay(100); 184 | Serial.printf("Waiting for power on, current voltage%.2f\n", VIN_Volt); 185 | } 186 | Serial.printf("Calibrating motor...Current voltage%.2f\n", VIN_Volt); 187 | } 188 | 189 | float get_vin_Volt() { 190 | return analogReadMilliVolts(13) * 8.5 / 1000; 191 | } 192 | -------------------------------------------------------------------------------- /Test Code/12_close_loop_position_example/12_close_loop_position_example.ino: -------------------------------------------------------------------------------- 1 | // MKS ESP32 FOC V2.0 | Current Close Loop Velocity Example | Library:SimpleFOC 2.2.1 | Hardware:MKS ESP32 FOC V2.0 & MKS AS5600 2 | 3 | // !!!Notice!!! 4 | // ①Enter "A+number" in the serial port to set the position of the M0 motor. For example, enter "A3.14" to rotate the M0 motor to 180° (radians). Enter "B+number" to set the speed of the M1 motor. 5 | // ②When using your own motor, be sure to modify the default number of pole pairs, that is, the value in BLDCMotor(7), to the number of pole pairs of your own motor. 6 | // ③Please set the correct voltage_limit and current_limit values ​​according to the selected motor. It is recommended to set the values ​​between 0.5 and 1.0 for the aircraft model motor and below 4 for the gimbal motor. Excessive voltage and current may burn out the driver board! 7 | // ④The pid parameters of this routine can control the 2808 model aircraft motor. If you want to achieve better results or use other motors, please adjust the pid parameters yourself. 8 | 9 | #include 10 | 11 | //Motor Instance 12 | BLDCMotor motor1 = BLDCMotor(7); 13 | BLDCDriver3PWM driver1 = BLDCDriver3PWM(32, 33, 25, 12); 14 | 15 | BLDCMotor motor2 = BLDCMotor(7); 16 | BLDCDriver3PWM driver2 = BLDCDriver3PWM(26, 27, 14, 12); 17 | 18 | //Encoder Instance 19 | MagneticSensorI2C sensor1 = MagneticSensorI2C(AS5600_I2C); 20 | TwoWire I2Cone = TwoWire(0); 21 | MagneticSensorI2C sensor2 = MagneticSensorI2C(AS5600_I2C); 22 | TwoWire I2Ctwo = TwoWire(1); 23 | 24 | // Inline Current sensing Instance 25 | InlineCurrentSense current_sense1 = InlineCurrentSense(0.01, 50.0, 39, 36); 26 | InlineCurrentSense current_sense2 = InlineCurrentSense(0.01, 50.0, 35, 34); 27 | 28 | // commander Communication Instance 29 | Commander command = Commander(Serial); 30 | void doMotor1(char* cmd) { 31 | command.motor(&motor1, cmd); 32 | } 33 | void doMotor2(char* cmd) { 34 | command.motor(&motor2, cmd); 35 | } 36 | 37 | //Setting the alarm voltage 38 | #define UNDERVOLTAGE_THRES 11.1 39 | void board_init(); 40 | float get_vin_Volt(); 41 | 42 | void setup() { 43 | Serial.begin(115200); 44 | board_init(); 45 | 46 | // Encoder Settings 47 | I2Cone.begin(19, 18, 400000UL); // AS5600_M0 48 | I2Ctwo.begin(23, 5, 400000UL); // AS5600_M1 49 | 50 | sensor1.init(&I2Cone); 51 | sensor2.init(&I2Ctwo); 52 | 53 | //Connect the motor object and the sensor object 54 | motor1.linkSensor(&sensor1); 55 | motor2.linkSensor(&sensor2); 56 | 57 | // Drive Settings 58 | driver1.voltage_power_supply = get_vin_Volt(); 59 | driver1.init(); 60 | motor1.linkDriver(&driver1); 61 | driver2.voltage_power_supply = get_vin_Volt(); 62 | driver2.init(); 63 | motor2.linkDriver(&driver2); 64 | 65 | // Current Limitation 66 | motor1.current_limit = 0.5; 67 | motor2.current_limit = 0.5; 68 | 69 | // Voltage Limitation 70 | motor1.voltage_limit = 0.5; 71 | motor2.voltage_limit = 0.5; 72 | 73 | 74 | // Current Sensing 75 | current_sense1.init(); 76 | // current_sense1.gain_b *= 1; 77 | // current_sense1.gain_a *= 1; 78 | // current_sense1.skip_align = true; 79 | motor1.linkCurrentSense(¤t_sense1); 80 | 81 | // current sense init and linking 82 | current_sense2.init(); 83 | // current_sense2.gain_b *= 1; 84 | // current_sense2.gain_a *= 1; 85 | // current_sense2.skip_align = true; 86 | motor2.linkCurrentSense(¤t_sense2); 87 | 88 | // Control loop 89 | // Other modes TorqueControlType::voltage TorqueControlType::dc_current 90 | motor1.torque_controller = TorqueControlType::foc_current; 91 | motor1.controller = MotionControlType::angle; 92 | motor2.torque_controller = TorqueControlType::foc_current; 93 | motor2.controller = MotionControlType::angle; 94 | 95 | motor1.voltage_sensor_align = 5; 96 | motor2.voltage_sensor_align = 5; 97 | 98 | // FOC current control PID parameters 99 | motor1.PID_current_q.P = 1; 100 | motor1.PID_current_q.I = 500; 101 | motor1.PID_current_d.P = 1; 102 | motor1.PID_current_d.I = 500; 103 | motor1.LPF_current_q.Tf = 0.002; // 1ms default 104 | motor1.LPF_current_d.Tf = 0.002; // 1ms default 105 | 106 | motor2.PID_current_q.P = 1; 107 | motor2.PID_current_q.I = 500; 108 | motor2.PID_current_d.P = 1; 109 | motor2.PID_current_d.I = 500; 110 | motor2.LPF_current_q.Tf = 0.002; // 1ms default 111 | motor2.LPF_current_d.Tf = 0.002; // 1ms default 112 | 113 | // Speed ​​loop PID parameters 114 | motor1.PID_velocity.P = 0.021; 115 | motor1.PID_velocity.I = 0.12; 116 | motor1.PID_velocity.D = 0; 117 | 118 | motor2.PID_velocity.P = 0.021; 119 | motor2.PID_velocity.I = 0.12; 120 | motor2.PID_velocity.D = 0; 121 | // default voltage_power_supply 122 | motor1.P_angle.P = 20; 123 | motor2.P_angle.P = 20; 124 | // Speed ​​Limit 125 | motor1.velocity_limit = 20; 126 | motor2.velocity_limit = 20; 127 | 128 | 129 | // monitor Interface Settings 130 | // comment out if not needed 131 | motor1.useMonitoring(Serial); 132 | motor2.useMonitoring(Serial); 133 | 134 | // monitor Related settings 135 | motor1.monitor_downsample = 0; 136 | motor1.monitor_variables = _MON_TARGET | _MON_VEL | _MON_ANGLE | _MON_CURR_Q; 137 | motor2.monitor_downsample = 0; 138 | motor2.monitor_variables = _MON_TARGET | _MON_VEL | _MON_ANGLE | _MON_CURR_Q; 139 | 140 | //Motor initialization 141 | motor1.init(); 142 | // align encoder and start FOC 143 | motor1.initFOC(); 144 | 145 | motor2.init(); 146 | // align encoder and start FOC 147 | motor2.initFOC(); 148 | 149 | // Initial target value 150 | motor1.target = 0.0; 151 | motor2.target = 0.0; 152 | 153 | // Mapping motors to commanders 154 | command.add('A', doMotor1, "motor 1"); 155 | command.add('B', doMotor2, "motor 2"); 156 | 157 | Serial.println(F("Double motor sketch ready.")); 158 | 159 | _delay(1000); 160 | } 161 | 162 | 163 | void loop() { 164 | motor1.loopFOC(); 165 | motor2.loopFOC(); 166 | 167 | motor1.move(); 168 | motor2.move(); 169 | 170 | command.run(); 171 | } 172 | 173 | void board_init() { 174 | pinMode(32, INPUT_PULLUP); 175 | pinMode(33, INPUT_PULLUP); 176 | pinMode(25, INPUT_PULLUP); 177 | pinMode(26, INPUT_PULLUP); 178 | pinMode(27, INPUT_PULLUP); 179 | pinMode(14, INPUT_PULLUP); 180 | 181 | analogReadResolution(12); //12bit 182 | 183 | float VIN_Volt = get_vin_Volt(); 184 | while (VIN_Volt <= UNDERVOLTAGE_THRES) { 185 | VIN_Volt = get_vin_Volt(); 186 | delay(100); 187 | Serial.printf("Waiting for power on, current voltage%.2f\n", VIN_Volt); 188 | } 189 | Serial.printf("Calibrating motor...Current voltage%.2f\n", VIN_Volt); 190 | } 191 | 192 | float get_vin_Volt() { 193 | return analogReadMilliVolts(13) * 8.5 / 1000; 194 | } 195 | -------------------------------------------------------------------------------- /Test Code/13_SimpleFOCStudio_M0_bluetooth/13_SimpleFOCStudio_M0_bluetooth.ino: -------------------------------------------------------------------------------- 1 | // MKS ESP32 FOC V2.0 | Bluetooth Control M0 Example | Library:SimpleFOC 2.2.1 | Hardware:MKS ESP32 FOC V2.0 & MKS AS5600 2 | 3 | // !!!Notice!!! 4 | // ①Enter "M+number" in the serial port to make the M0 motor rotate to the specified position. For example, enter "M3.14" to make the M0 motor rotate to 180° (radians). 5 | // ②When using your own motor, be sure to modify the default number of pole pairs, that is, the value in BLDCMotor(7), to the number of pole pairs of your own motor. 6 | // ③Please set the correct voltage_limit and current_limit values ​​according to the selected motor. It is recommended to set the values ​​between 0.5 and 1.0 for the aircraft model motor and below 4 for the gimbal motor. Excessive voltage and current may burn out the driver board! 7 | // ④The pid parameters of this routine can control the 2808 model aircraft motor. If you want to achieve better results or use other motors, please adjust the pid parameters yourself. 8 | 9 | #include 10 | #include "BluetoothSerial.h" 11 | 12 | #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED) 13 | #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it 14 | #endif 15 | 16 | BluetoothSerial SerialBT; 17 | // BLDC motor & driver instance 18 | BLDCMotor motor = BLDCMotor(7); 19 | BLDCDriver3PWM driver = BLDCDriver3PWM(32,33,25,12); 20 | 21 | // encoder instance 22 | MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C); 23 | TwoWire I2Cone = TwoWire(0); 24 | 25 | 26 | // inline current sensor instance 27 | // check if your board has R010 (0.01 ohm resistor) or R006 (0.006 mOhm resistor) 28 | InlineCurrentSense current_sense = InlineCurrentSense(0.01, 50.0, 39, 36); 29 | 30 | // commander communication instance 31 | Commander command = Commander(SerialBT); 32 | void doMotor(char* cmd){ command.motor(&motor, cmd); } 33 | 34 | //I2C Initialization 35 | void I2C_init(); 36 | 37 | void setup() { 38 | I2C_init(); 39 | // driver config 40 | // power supply voltage [V] 41 | //driver.pwm_frequency = 100000; 42 | driver.voltage_power_supply = 12; 43 | driver.init(); 44 | // link driver 45 | motor.linkDriver(&driver); 46 | 47 | // TorqueControlType::foc_current 48 | // Other modes TorqueControlType::voltage TorqueControlType::dc_current 49 | motor.torque_controller = TorqueControlType::foc_current; 50 | // set control loop type to be used 51 | motor.controller = MotionControlType::torque; 52 | 53 | // contoller configuration based on the controll type 54 | motor.PID_velocity.P = 0.021; 55 | motor.PID_velocity.I = 0.12; 56 | motor.PID_velocity.D = 0; 57 | 58 | // Voltage Limitation 59 | motor.voltage_limit = 0.5; 60 | // Current Limitation 61 | //motor.current_limit = 0.5; 62 | 63 | // velocity low pass filtering time constant 64 | motor.LPF_velocity.Tf = 0.01; 65 | 66 | // angle loop controller 67 | motor.P_angle.P = 20; 68 | // angle loop velocity limit 69 | motor.velocity_limit = 20; 70 | 71 | // use monitoring with serial for motor init 72 | // monitoring port 73 | //Serial.begin(115200); 74 | SerialBT.begin("MKS ESP32 FOC"); //Bluetooth device name 75 | // comment out if not needed 76 | motor.useMonitoring(SerialBT); 77 | motor.monitor_downsample = 0; // disable intially 78 | motor.monitor_variables = _MON_TARGET | _MON_VEL | _MON_ANGLE; // monitor target velocity and angle 79 | 80 | // current sense init and linking 81 | current_sense.init(); 82 | current_sense.gain_b *= 1; 83 | current_sense.gain_a *= 1; 84 | motor.linkCurrentSense(¤t_sense); 85 | 86 | // initialise motor 87 | motor.init(); 88 | // align encoder and start FOC 89 | motor.initFOC(); 90 | 91 | // set the inital target value 92 | motor.target = 0.05; 93 | 94 | // subscribe motor to the commander 95 | command.add('M', doMotor, "motor"); 96 | 97 | // Run user commands to configure and the motor (find the full command list in docs.simplefoc.com) 98 | SerialBT.println(F("Motor commands sketch | Initial motion control > torque/voltage : target 2V.")); 99 | 100 | _delay(1000); 101 | } 102 | 103 | 104 | void loop() { 105 | //SerialBT.println(F("111")); 106 | // iterative setting FOC phase voltage 107 | motor.loopFOC(); 108 | 109 | // iterative function setting the outter loop target 110 | motor.move(); 111 | 112 | // motor monitoring 113 | motor.monitor(); 114 | 115 | // user communication 116 | command.run(); 117 | } 118 | 119 | 120 | 121 | void I2C_init(){ 122 | pinMode(32, INPUT_PULLUP); 123 | pinMode(33, INPUT_PULLUP); 124 | pinMode(25, INPUT_PULLUP); 125 | pinMode(26, INPUT_PULLUP); 126 | pinMode(27, INPUT_PULLUP); 127 | pinMode(14, INPUT_PULLUP); 128 | 129 | I2Cone.begin(19, 18, 400000UL); // AS5600_M0 130 | sensor.init(&I2Cone); 131 | motor.linkSensor(&sensor); 132 | } 133 | -------------------------------------------------------------------------------- /Test Code/13_SimpleFOCStudio_M0_bluetooth/simpleFOCStudio_dist.7z.001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makerbase-motor/MKS-ESP32FOC/23525e415933be639629f6fef85e250789b69289/Test Code/13_SimpleFOCStudio_M0_bluetooth/simpleFOCStudio_dist.7z.001 -------------------------------------------------------------------------------- /Test Code/13_SimpleFOCStudio_M0_bluetooth/simpleFOCStudio_dist.7z.002: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makerbase-motor/MKS-ESP32FOC/23525e415933be639629f6fef85e250789b69289/Test Code/13_SimpleFOCStudio_M0_bluetooth/simpleFOCStudio_dist.7z.002 -------------------------------------------------------------------------------- /Test Code/13_SimpleFOCStudio_M0_bluetooth/simpleFOCStudio_dist.7z.003: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makerbase-motor/MKS-ESP32FOC/23525e415933be639629f6fef85e250789b69289/Test Code/13_SimpleFOCStudio_M0_bluetooth/simpleFOCStudio_dist.7z.003 -------------------------------------------------------------------------------- /Test Code/14_dual_inline_current_sense_test/14_dual_inline_current_sense_test.ino: -------------------------------------------------------------------------------- 1 | //MKS ESP32 FOC V2.0 | Inline Current Sensing Example | Library:SimpleFOC 2.2.1 | Hardware:MKS ESP32 FOC V2.0 2 | 3 | #include 4 | 5 | // Current Sensing 6 | // Sampling Resistor Value Gain ADC Pin 7 | InlineCurrentSense current_sense0 = InlineCurrentSense(0.01, 50.0, 39, 36); 8 | InlineCurrentSense current_sense1 = InlineCurrentSense(0.01, 50.0, 35, 34); 9 | 10 | 11 | void setup() { 12 | // Current Sensing 13 | current_sense0.init(); 14 | current_sense1.init(); 15 | 16 | Serial.begin(115200); 17 | Serial.println("Current sense ready."); 18 | } 19 | 20 | int count; 21 | void loop() { 22 | 23 | PhaseCurrent_s currents0 = current_sense0.getPhaseCurrents(); 24 | float current_magnitude0 = current_sense0.getDCCurrent(); 25 | PhaseCurrent_s currents1 = current_sense1.getPhaseCurrents(); 26 | float current_magnitude1 = current_sense1.getDCCurrent(); 27 | 28 | count++; 29 | if (count >= 50) { 30 | 31 | //Use the serial port assistant to draw waveforms 32 | Serial.printf("%.2f,%.2f,%.2f,%.2f\n", currents0.a * 1000, currents0.b * 1000, currents0.c * 1000, current_magnitude0 * 1000); // milli Amps 33 | // Serial.printf("%.2f,%.2f,%.2f,%.2f\n", currents1.a * 1000, currents1.b * 1000, currents1.c * 1000, current_magnitude1 * 1000); // milli Amps 34 | 35 | count = 0; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Test Code/1_open_loop_velocity_example/1_open_loop_velocity_example.ino: -------------------------------------------------------------------------------- 1 | // MKS ESP32 FOC V2.0 | Open Loop Velocity Example | Library:SimpleFOC 2.2.1 | Hardware:MKS ESP32 FOC V2.0 2 | 3 | // !!!Notice!!! 4 | // ①Enter "T+number" in the serial port to set the speed of the two motors. For example, if you want to set the motor to rotate at 10 rad/s, enter "T10". The motor will rotate at 5 rad/s by default when powered on. 5 | // ②When using your own motor, be sure to modify the default number of pole pairs, that is, the value in BLDCMotor(7), to the number of pole pairs of your own motor. 6 | // ③Please set the correct voltage_limit value according to the selected motor. It is recommended to set it between 0.5 and 1.0 for the aircraft model motor and below 4 for the gimbal motor. Excessive voltage and current may burn out the driver board! 7 | // ④Open-loop control inevitably causes heating, so do not run this routine for more than one minute, otherwise overheating will cause the motor or driver board to burn out! 8 | 9 | #include 10 | 11 | BLDCMotor motor = BLDCMotor(7); 12 | BLDCDriver3PWM driver = BLDCDriver3PWM(32, 33, 25, 12); 13 | 14 | // BLDC motor & driver instance 15 | BLDCMotor motor1 = BLDCMotor(7); 16 | BLDCDriver3PWM driver1 = BLDCDriver3PWM(26, 27, 14, 12); 17 | 18 | //Target variable 19 | float target_velocity = 5; 20 | uint32_t prev_millis; 21 | 22 | //Setting the alarm voltage 23 | #define UNDERVOLTAGE_THRES 11.1 24 | 25 | //Serial port command settings 26 | Commander command = Commander(Serial); 27 | void doTarget(char* cmd) { 28 | command.scalar(&target_velocity, cmd); 29 | } 30 | 31 | void board_check(); 32 | float get_vin_Volt(); 33 | void board_init(); 34 | bool flag_under_voltage = false; 35 | 36 | 37 | void setup() { 38 | Serial.begin(115200); 39 | board_init(); 40 | 41 | driver.voltage_power_supply = get_vin_Volt(); 42 | driver.init(); 43 | motor.linkDriver(&driver); 44 | motor.voltage_limit = 0.5; // [V] Please modify and check this value carefully, excessive voltage and current may cause the driver board to burn out!!! 45 | motor.velocity_limit = 30; // [rad/s] 46 | 47 | driver1.voltage_power_supply = get_vin_Volt(); 48 | driver1.init(); 49 | motor1.linkDriver(&driver1); 50 | motor1.voltage_limit = 0.5; // [V] Please modify and check this value carefully, excessive voltage and current may cause the driver board to burn out!!! 51 | motor1.velocity_limit = 30; // [rad/s] 52 | 53 | //Open loop control mode setting 54 | motor.controller = MotionControlType::velocity_openloop; 55 | motor1.controller = MotionControlType::velocity_openloop; 56 | 57 | //Initialize the hardware 58 | motor.init(); 59 | motor1.init(); 60 | 61 | //Add T command 62 | command.add('T', doTarget, "target velocity"); 63 | 64 | Serial.println("Motor ready!"); 65 | Serial.println("Set target velocity [rad/s]"); 66 | _delay(1000); 67 | } 68 | 69 | void loop() { 70 | motor.move(target_velocity); 71 | motor1.move(target_velocity); 72 | 73 | //When the voltage is lower than the set value, the motor will be disabled. 74 | board_check(); 75 | 76 | //User Communications 77 | if (!flag_under_voltage) 78 | command.run(); 79 | } 80 | 81 | void board_init() { 82 | pinMode(32, INPUT_PULLUP); 83 | pinMode(33, INPUT_PULLUP); 84 | pinMode(25, INPUT_PULLUP); 85 | pinMode(26, INPUT_PULLUP); 86 | pinMode(27, INPUT_PULLUP); 87 | pinMode(14, INPUT_PULLUP); 88 | 89 | analogReadResolution(12); //12bit 90 | 91 | float VIN_Volt = get_vin_Volt(); 92 | while (VIN_Volt <= UNDERVOLTAGE_THRES) { 93 | VIN_Volt = get_vin_Volt(); 94 | delay(500); 95 | Serial.printf("Waiting for power on, current voltage%.2f\n", VIN_Volt); 96 | } 97 | Serial.printf("Calibrating motor...Current voltage%.2f\n", VIN_Volt); 98 | } 99 | 100 | float get_vin_Volt() { 101 | return analogReadMilliVolts(13) * 8.5 / 1000; 102 | } 103 | 104 | void board_check() { 105 | 106 | uint32_t curr_millis = millis(); 107 | static uint8_t enableState = 0; 108 | 109 | if (curr_millis - prev_millis >= 1000) { 110 | float vin_Volt = get_vin_Volt(); 111 | 112 | if (vin_Volt < UNDERVOLTAGE_THRES) { 113 | flag_under_voltage = true; 114 | enableState = 0; 115 | uint8_t count = 5; 116 | while (count--) { 117 | vin_Volt = get_vin_Volt(); 118 | if (vin_Volt > UNDERVOLTAGE_THRES) { 119 | flag_under_voltage = false; 120 | break; 121 | } 122 | } 123 | } else { 124 | flag_under_voltage = false; 125 | } 126 | if (flag_under_voltage) { 127 | motor.disable(); 128 | motor1.disable(); 129 | } else if (0 == enableState && flag_under_voltage == false) { 130 | enableState = 1; 131 | motor.enable(); 132 | motor1.enable(); 133 | } 134 | prev_millis = curr_millis; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /Test Code/2_open_loop_position_example/2_open_loop_position_example.ino: -------------------------------------------------------------------------------- 1 | // MKS ESP32 FOC V2.0 | Open Loop Position Example | Library:SimpleFOC 2.2.1 | Hardware:MKS ESP32 FOC V2.0 2 | 3 | // !!!Notice!!! 4 | // ①Enter "T+number" in the serial port to set the position of the two motors. For example, if you want the motor to rotate to 180°, enter "T3.14" (180° in radians) 5 | // ②When using your own motor, be sure to modify the default number of pole pairs, that is, the value in BLDCMotor(7), to the number of pole pairs of your own motor. 6 | // ③Please set the correct voltage_limit value according to the selected motor. It is recommended to set it between 0.5 and 1.0 for the aircraft model motor and below 4 for the gimbal motor. Excessive voltage and current may burn out the driver board! 7 | // ④Open-loop control inevitably causes heating, so do not run this routine for more than one minute, otherwise overheating will cause the motor or driver board to burn out! 8 | 9 | #include 10 | 11 | BLDCMotor motor = BLDCMotor(7); 12 | BLDCDriver3PWM driver = BLDCDriver3PWM(32, 33, 25, 12); 13 | 14 | BLDCMotor motor1 = BLDCMotor(7); 15 | BLDCDriver3PWM driver1 = BLDCDriver3PWM(26, 27, 14, 12); 16 | 17 | //Target variable 18 | float target_angle = 0; 19 | uint32_t prev_millis; 20 | 21 | //Setting the alarm voltage 22 | #define UNDERVOLTAGE_THRES 11.1 23 | 24 | //Serial port command settings 25 | Commander command = Commander(Serial); 26 | void doTarget(char* cmd) { 27 | command.scalar(&target_angle, cmd); 28 | } 29 | 30 | void board_check(); 31 | float get_vin_Volt(); 32 | void board_init(); 33 | bool flag_under_voltage = false; 34 | 35 | void setup() { 36 | Serial.begin(115200); 37 | board_init(); 38 | 39 | driver.voltage_power_supply = get_vin_Volt(); 40 | driver.init(); 41 | motor.linkDriver(&driver); 42 | motor.voltage_limit = 0.5; // [V] Please modify and check this value carefully, excessive voltage and current may cause the driver board to burn out!!! 43 | motor.velocity_limit = 20; // [rad/s] 44 | 45 | driver1.voltage_power_supply = get_vin_Volt(); 46 | driver1.init(); 47 | motor1.linkDriver(&driver1); 48 | motor1.voltage_limit = 0.5; // [V] Please modify and check this value carefully, excessive voltage and current may cause the driver board to burn out!!! 49 | motor1.velocity_limit = 20; // [rad/s] 50 | 51 | 52 | //Open loop control mode setting 53 | motor.controller = MotionControlType::angle_openloop; 54 | motor1.controller = MotionControlType::angle_openloop; 55 | 56 | //Initialize the hardware 57 | motor.init(); 58 | motor1.init(); 59 | 60 | 61 | //Add T command 62 | command.add('T', doTarget, "target angle"); 63 | 64 | Serial.println("Motor ready!"); 65 | Serial.println("Set target angle [rad]"); 66 | _delay(1000); 67 | } 68 | 69 | void loop() { 70 | motor.move(target_angle); 71 | motor1.move(target_angle); 72 | 73 | //When the voltage is lower than the set value, the motor will be disabled. 74 | board_check(); 75 | 76 | //User Communications 77 | if (!flag_under_voltage) 78 | command.run(); 79 | } 80 | 81 | void board_init() { 82 | pinMode(32, INPUT_PULLUP); 83 | pinMode(33, INPUT_PULLUP); 84 | pinMode(25, INPUT_PULLUP); 85 | pinMode(26, INPUT_PULLUP); 86 | pinMode(27, INPUT_PULLUP); 87 | pinMode(14, INPUT_PULLUP); 88 | 89 | analogReadResolution(12); //12bit 90 | 91 | float VIN_Volt = get_vin_Volt(); 92 | while (VIN_Volt <= UNDERVOLTAGE_THRES) { 93 | VIN_Volt = get_vin_Volt(); 94 | delay(100); 95 | Serial.printf("Waiting for power on, current voltage%.2f\n", VIN_Volt); 96 | } 97 | Serial.printf("Calibrating motor...Current voltage%.2f\n", VIN_Volt); 98 | } 99 | 100 | float get_vin_Volt() { 101 | return analogReadMilliVolts(13) * 8.5 / 1000; 102 | } 103 | 104 | void board_check() { 105 | 106 | uint32_t curr_millis = millis(); 107 | static uint8_t enableState = 0; 108 | 109 | if (curr_millis - prev_millis >= 1000) { 110 | float vin_Volt = get_vin_Volt(); 111 | 112 | if (vin_Volt < UNDERVOLTAGE_THRES) { 113 | flag_under_voltage = true; 114 | enableState = 0; 115 | uint8_t count = 5; 116 | while (count--) { 117 | vin_Volt = get_vin_Volt(); 118 | if (vin_Volt > UNDERVOLTAGE_THRES) { 119 | flag_under_voltage = false; 120 | break; 121 | } 122 | } 123 | } else { 124 | flag_under_voltage = false; 125 | } 126 | if (flag_under_voltage) { 127 | motor.disable(); 128 | motor1.disable(); 129 | } else if (0 == enableState && flag_under_voltage == false) { 130 | enableState = 1; 131 | motor.enable(); 132 | motor1.enable(); 133 | } 134 | prev_millis = curr_millis; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /Test Code/3_dual_as5600_test/3_dual_as5600_test.ino: -------------------------------------------------------------------------------- 1 | // MKS ESP32 FOC V2.0 | AS5600 Encoder Example | Library:SimpleFOC 2.2.1 | Hardware:MKS ESP32 FOC V2.0 & MKS AS5600 2 | #include 3 | 4 | MagneticSensorI2C sensor0 = MagneticSensorI2C(AS5600_I2C); 5 | MagneticSensorI2C sensor1 = MagneticSensorI2C(AS5600_I2C); 6 | TwoWire I2Cone = TwoWire(0); 7 | TwoWire I2Ctwo = TwoWire(1); 8 | 9 | 10 | void setup() { 11 | Serial.begin(115200); 12 | 13 | I2Cone.begin(19, 18, 400000UL); // AS5600_M0 14 | I2Ctwo.begin(23, 5, 400000UL); // AS5600_M1 15 | 16 | sensor0.init(&I2Cone); 17 | sensor1.init(&I2Ctwo); 18 | } 19 | 20 | void loop() { 21 | sensor0.update(); // If the simplefoc library version is 2.20 and above, uncomment these two lines 22 | sensor1.update(); 23 | Serial.print(sensor0.getAngle()); 24 | Serial.print(" - "); 25 | Serial.println(sensor1.getAngle()); 26 | Serial.println(); 27 | } 28 | -------------------------------------------------------------------------------- /Test Code/4_close_loop_velocity_example/4_close_loop_velocity_example.ino: -------------------------------------------------------------------------------- 1 | // MKS ESP32 FOC V2.0 | Close Loop Velocity Example | Library:SimpleFOC 2.2.1 | Hardware:MKS ESP32 FOC V2.0 & MKS AS5600 2 | 3 | // !!!Notice!!! 4 | // ①Enter "T+number" in the serial port to set the speed of the motor. For example, if you enter "T10", the motor speed will be set to 10rad/s. 5 | // ②When using your own motor, be sure to modify the default number of pole pairs, that is, the value in BLDCMotor(7), to the number of pole pairs of your own motor. 6 | // ③Please set the correct voltage_limit value according to the selected motor. It is recommended to set it between 0.5 and 1.0 for the aircraft model motor and below 4 for the gimbal motor. Excessive voltage and current may burn out the driver board! 7 | // ④The pid parameters of this routine can control the 2808 model aircraft motor. If you want to achieve better results or use other motors, please adjust the pid parameters yourself. 8 | 9 | #include 10 | 11 | MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C); 12 | MagneticSensorI2C sensor1 = MagneticSensorI2C(AS5600_I2C); 13 | TwoWire I2Cone = TwoWire(0); 14 | TwoWire I2Ctwo = TwoWire(1); 15 | 16 | //Motor parameters 17 | BLDCMotor motor = BLDCMotor(7); 18 | BLDCDriver3PWM driver = BLDCDriver3PWM(32, 33, 25, 12); 19 | 20 | BLDCMotor motor1 = BLDCMotor(7); 21 | BLDCDriver3PWM driver1 = BLDCDriver3PWM(26, 27, 14, 12); 22 | 23 | //Command settings 24 | float target_velocity = 0; 25 | uint32_t prev_millis; 26 | 27 | //Setting the alarm voltage 28 | #define UNDERVOLTAGE_THRES 11.1 29 | 30 | void board_check(); 31 | float get_vin_Volt(); 32 | void board_init(); 33 | bool flag_under_voltage = false; 34 | 35 | Commander command = Commander(Serial); 36 | void doTarget(char* cmd) { command.scalar(&target_velocity, cmd); } 37 | 38 | void setup() { 39 | Serial.begin(115200); 40 | board_init(); 41 | 42 | I2Cone.begin(19, 18, 400000UL); // AS5600_M0 43 | I2Ctwo.begin(23, 5, 400000UL); // AS5600_M1 44 | sensor.init(&I2Cone); 45 | sensor1.init(&I2Ctwo); 46 | //Connect the motor object and the sensor object 47 | motor.linkSensor(&sensor); 48 | motor1.linkSensor(&sensor1); 49 | 50 | //Supply voltage setting [V] 51 | driver.voltage_power_supply = get_vin_Volt(); 52 | driver.init(); 53 | 54 | driver1.voltage_power_supply = get_vin_Volt(); 55 | driver1.init(); 56 | //Connect the motor and driver objects 57 | motor.linkDriver(&driver); 58 | motor1.linkDriver(&driver1); 59 | 60 | //FOC model selection 61 | motor.foc_modulation = FOCModulationType::SpaceVectorPWM; 62 | motor1.foc_modulation = FOCModulationType::SpaceVectorPWM; 63 | //Motion control mode settings 64 | motor.controller = MotionControlType::velocity; 65 | motor1.controller = MotionControlType::velocity; 66 | 67 | 68 | //Speed ​​PI loop settings 69 | motor.PID_velocity.P = 0.021; 70 | motor1.PID_velocity.P = 0.021; 71 | motor.PID_velocity.I = 0.12; 72 | motor1.PID_velocity.I = 0.12; 73 | //Maximum motor limiting voltage 74 | motor.voltage_limit = 0.5; // [V] Please modify and check this value carefully, excessive voltage and current may cause the driver board to burn out!!! 75 | motor1.voltage_limit = 0.5; // [V] Please modify and check this value carefully, excessive voltage and current may cause the driver board to burn out!!! 76 | 77 | //Speed ​​low pass filter time constant 78 | motor.LPF_velocity.Tf = 0.01; 79 | motor1.LPF_velocity.Tf = 0.01; 80 | 81 | //Set a maximum speed limit 82 | motor.velocity_limit = 40; 83 | motor1.velocity_limit = 40; 84 | 85 | motor.useMonitoring(Serial); 86 | motor1.useMonitoring(Serial); 87 | 88 | //Initialize the motor 89 | motor.init(); 90 | motor1.init(); 91 | //Initialize FOC 92 | motor.initFOC(); 93 | motor1.initFOC(); 94 | command.add('T', doTarget, "target velocity"); 95 | 96 | Serial.println(F("Motor ready.")); 97 | Serial.println(F("Set the target velocity using serial terminal:")); 98 | 99 | } 100 | 101 | void loop() { 102 | motor.loopFOC(); 103 | motor1.loopFOC(); 104 | 105 | motor.move(target_velocity); 106 | motor1.move(target_velocity); 107 | 108 | //When the voltage is lower than the set value, the motor will be disabled. 109 | board_check(); 110 | 111 | //User Communications 112 | if (!flag_under_voltage) 113 | command.run(); 114 | } 115 | 116 | void board_init() { 117 | pinMode(32, INPUT_PULLUP); 118 | pinMode(33, INPUT_PULLUP); 119 | pinMode(25, INPUT_PULLUP); 120 | pinMode(26, INPUT_PULLUP); 121 | pinMode(27, INPUT_PULLUP); 122 | pinMode(14, INPUT_PULLUP); 123 | 124 | analogReadResolution(12); //12bit 125 | 126 | float VIN_Volt = get_vin_Volt(); 127 | while (VIN_Volt <= UNDERVOLTAGE_THRES) { 128 | VIN_Volt = get_vin_Volt(); 129 | delay(500); 130 | Serial.printf("Waiting for power on, current voltage%.2f\n", VIN_Volt); 131 | } 132 | Serial.printf("Calibrating motor...Current voltage%.2f\n", VIN_Volt); 133 | } 134 | 135 | float get_vin_Volt() { 136 | return analogReadMilliVolts(13) * 8.5 / 1000; 137 | } 138 | 139 | void board_check() { 140 | 141 | uint32_t curr_millis = millis(); 142 | static uint8_t enableState = 0; 143 | 144 | if (curr_millis - prev_millis >= 1000) { 145 | float vin_Volt = get_vin_Volt(); 146 | 147 | if (vin_Volt < UNDERVOLTAGE_THRES) { 148 | flag_under_voltage = true; 149 | enableState = 0; 150 | uint8_t count = 5; 151 | while (count--) { 152 | vin_Volt = get_vin_Volt(); 153 | if (vin_Volt > UNDERVOLTAGE_THRES) { 154 | flag_under_voltage = false; 155 | break; 156 | } 157 | } 158 | } else { 159 | flag_under_voltage = false; 160 | } 161 | if (flag_under_voltage) { 162 | motor.disable(); 163 | motor1.disable(); 164 | } else if (0 == enableState && flag_under_voltage == false) { 165 | enableState = 1; 166 | motor.enable(); 167 | motor1.enable(); 168 | } 169 | prev_millis = curr_millis; 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /Test Code/5_close_loop_position_example/5_close_loop_position_example.ino: -------------------------------------------------------------------------------- 1 | // MKS ESP32 FOC V2.0 | Open Loop Position Example | Library:SimpleFOC 2.2.1 | Hardware:MKS ESP32 FOC V2.0 & MKS AS5600 2 | 3 | // !!!Notice!!! 4 | // ①Enter "T+number" in the serial port to set the position of the two motors. For example, if you want the motor to rotate to 180°, enter "T3.14" (180° in radians) 5 | // ②When using your own motor, be sure to modify the default number of pole pairs, that is, the value in BLDCMotor(7), to the number of pole pairs of your own motor. 6 | // ③Please set the correct voltage_limit value according to the selected motor. It is recommended to set it between 0.5 and 1.0 for the aircraft model motor and below 4 for the gimbal motor. Excessive voltage and current may burn out the driver board! 7 | // ④The pid parameters of this routine can control the 2808 model aircraft motor. If you want to achieve better results or use other motors, please adjust the pid parameters yourself. 8 | 9 | #include 10 | 11 | MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C); 12 | MagneticSensorI2C sensor1 = MagneticSensorI2C(AS5600_I2C); 13 | TwoWire I2Cone = TwoWire(0); 14 | TwoWire I2Ctwo = TwoWire(1); 15 | 16 | //Motor parameters 17 | BLDCMotor motor = BLDCMotor(7); 18 | BLDCDriver3PWM driver = BLDCDriver3PWM(32, 33, 25, 12); 19 | 20 | BLDCMotor motor1 = BLDCMotor(7); 21 | BLDCDriver3PWM driver1 = BLDCDriver3PWM(26, 27, 14, 12); 22 | 23 | //Command settings 24 | float target_angle = 0; 25 | uint32_t prev_millis; 26 | 27 | //Setting the alarm voltage 28 | #define UNDERVOLTAGE_THRES 11.1 29 | 30 | Commander command = Commander(Serial); 31 | void doTarget(char *cmd) 32 | { 33 | command.scalar(&target_angle, cmd); 34 | } 35 | 36 | void board_check(); 37 | float get_vin_Volt(); 38 | void board_init(); 39 | bool flag_under_voltage = false; 40 | 41 | void setup() 42 | { 43 | Serial.begin(115200); 44 | board_init(); 45 | 46 | I2Cone.begin(19, 18, 400000UL); // AS5600_M0 47 | I2Ctwo.begin(23, 5, 400000UL); // AS5600_M1 48 | sensor.init(&I2Cone); 49 | sensor1.init(&I2Ctwo); 50 | //Connect the motor object and the sensor object 51 | motor.linkSensor(&sensor); 52 | motor1.linkSensor(&sensor1); 53 | 54 | //Supply voltage setting [V] 55 | driver.voltage_power_supply = get_vin_Volt(); 56 | driver.init(); 57 | 58 | driver1.voltage_power_supply = get_vin_Volt(); 59 | driver1.init(); 60 | //Connect the motor and driver objects 61 | motor.linkDriver(&driver); 62 | motor1.linkDriver(&driver1); 63 | 64 | // FOC model selection 65 | motor.foc_modulation = FOCModulationType::SpaceVectorPWM; 66 | motor1.foc_modulation = FOCModulationType::SpaceVectorPWM; 67 | //Motion control mode settings 68 | motor.controller = MotionControlType::angle; 69 | motor1.controller = MotionControlType::angle; 70 | 71 | //Speed ​​PI loop settings 72 | motor.PID_velocity.P = 0.021; 73 | motor1.PID_velocity.P = 0.021; 74 | motor.PID_velocity.I = 0.12; 75 | motor1.PID_velocity.I = 0.12; 76 | //Angle P ring setting 77 | motor.P_angle.P = 30; 78 | motor1.P_angle.P = 30; 79 | //Maximum motor limiting voltage 80 | motor.voltage_limit = 1; // [V] Please modify and check this value carefully, excessive voltage and current may cause the driver board to burn out!!! 81 | motor1.voltage_limit = 1; // [V] Please modify and check this value carefully, excessive voltage and current may cause the driver board to burn out!!! 82 | 83 | //Speed ​​low pass filter time constant 84 | motor.LPF_velocity.Tf = 0.01; 85 | motor1.LPF_velocity.Tf = 0.01; 86 | 87 | //Set a maximum speed limit 88 | motor.velocity_limit = 20; 89 | motor1.velocity_limit = 20; 90 | 91 | motor.useMonitoring(Serial); 92 | motor1.useMonitoring(Serial); 93 | 94 | //Initialize the motor 95 | motor.init(); 96 | motor1.init(); 97 | //Initialize FOC 98 | motor.initFOC(); 99 | motor1.initFOC(); 100 | command.add('T', doTarget, "target angle"); 101 | 102 | Serial.println(F("Motor ready.")); 103 | Serial.println(F("Set the target velocity using serial terminal:")); 104 | } 105 | 106 | void loop() 107 | { 108 | 109 | motor.loopFOC(); 110 | motor1.loopFOC(); 111 | 112 | motor.move(target_angle); 113 | motor1.move(target_angle); 114 | 115 | //When the voltage is lower than the set value, the motor will be disabled. 116 | board_check(); 117 | 118 | //User Communications 119 | if (!flag_under_voltage) 120 | command.run(); 121 | 122 | // Serial.print(sensor.getAngle()); 123 | // Serial.print(" - "); 124 | // Serial.print(sensor1.getAngle()); 125 | // Serial.println(); 126 | } 127 | 128 | void board_init() 129 | { 130 | pinMode(32, INPUT_PULLUP); 131 | pinMode(33, INPUT_PULLUP); 132 | pinMode(25, INPUT_PULLUP); 133 | pinMode(26, INPUT_PULLUP); 134 | pinMode(27, INPUT_PULLUP); 135 | pinMode(14, INPUT_PULLUP); 136 | 137 | analogReadResolution(12); // 12bit 138 | 139 | float VIN_Volt = get_vin_Volt(); 140 | while (VIN_Volt <= UNDERVOLTAGE_THRES) 141 | { 142 | VIN_Volt = get_vin_Volt(); 143 | delay(100); 144 | Serial.printf("Waiting for power on, current voltage%.2f\n", VIN_Volt); 145 | } 146 | Serial.printf("Calibrating motor...Current voltage%.2f\n", VIN_Volt); 147 | } 148 | 149 | float get_vin_Volt() 150 | { 151 | return analogReadMilliVolts(13) * 8.5 / 1000; 152 | } 153 | 154 | void board_check() 155 | { 156 | 157 | uint32_t curr_millis = millis(); 158 | static uint8_t enableState = 0; 159 | 160 | if (curr_millis - prev_millis >= 1000) 161 | { 162 | float vin_Volt = get_vin_Volt(); 163 | 164 | if (vin_Volt < UNDERVOLTAGE_THRES) 165 | { 166 | flag_under_voltage = true; 167 | enableState = 0; 168 | uint8_t count = 5; 169 | while (count--) 170 | { 171 | vin_Volt = get_vin_Volt(); 172 | if (vin_Volt > UNDERVOLTAGE_THRES) 173 | { 174 | flag_under_voltage = false; 175 | break; 176 | } 177 | } 178 | } 179 | else 180 | { 181 | flag_under_voltage = false; 182 | } 183 | if (flag_under_voltage) 184 | { 185 | motor.disable(); 186 | motor1.disable(); 187 | } 188 | else if (0 == enableState && flag_under_voltage == false) 189 | { 190 | enableState = 1; 191 | motor.enable(); 192 | motor1.enable(); 193 | } 194 | prev_millis = curr_millis; 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /Test Code/6_AS5047P_ABI_example/6_AS5047P_ABI_example.ino: -------------------------------------------------------------------------------- 1 | // MKS ESP32 FOC V2.0 | AS5047P Encoder ABI Example | Library:SimpleFOC 2.2.1 | Hardware:MKS ESP32 FOC V2.0 & MKS AS5047P 2 | // Test encoder AS5047P,CPR=4000 3 | // Driver board corresponding interface sequence:3.3V GND A B I 4 | 5 | 6 | #include 7 | 8 | //For ABI interface (0) number 9 | //Encoder encoder = Encoder(19,18,1000,15); //A0;B0;EncoderPPR,PPR=CPR/4;I0 10 | 11 | //For ABI interface (1) 12 | Encoder encoder = Encoder(23,5,1000,13); //A1;B1;EncoderPPR,PPR=CPR/4;I1 13 | 14 | void doA(){encoder.handleA();} 15 | void doB(){encoder.handleB();} 16 | 17 | void setup() { 18 | Serial.begin(115200); 19 | encoder.quadrature = Quadrature::ON; 20 | encoder.pullup = Pullup::USE_EXTERN; 21 | 22 | encoder.init(); 23 | // Hardware interrupt enable 24 | encoder.enableInterrupts(doA, doB); 25 | 26 | Serial.println("Encoder ready"); 27 | _delay(1000); 28 | } 29 | 30 | void loop() { 31 | // Output angle and angular velocity 32 | Serial.print(encoder.getAngle()); 33 | Serial.print("\t"); 34 | Serial.println(encoder.getVelocity()); 35 | } 36 | -------------------------------------------------------------------------------- /Test Code/7_AS5047P_SPI_example/7_AS5047P_SPI_example.ino: -------------------------------------------------------------------------------- 1 | // MKS ESP32 FOC V2.0 | AS5047P Encoder SPI Example | Library:SimpleFOC 2.2.1 | Hardware:MKS ESP32 FOC V2.0 & MKS AS5047P 2 | // Test Encoder AS5047P,SPI Interface 3 | 4 | 5 | #include 6 | 7 | #define HSPI_MISO 19 // Corresponding to the SDA_0 pin on the dual line 8 | #define HSPI_MOSI 23 // Corresponding to the SDA_1 pin on the dual line 9 | #define HSPI_SCLK 18 // Corresponding to the SCL_0 pin on the dual line 10 | #define HSPI_SS 5 // Corresponding to the SCL_1 pin on the dual line 11 | 12 | 13 | MagneticSensorSPI sensor = MagneticSensorSPI(AS5147_SPI, HSPI_SS); 14 | SPIClass SPI_2(HSPI); 15 | 16 | 17 | void setup() { 18 | Serial.begin(115200); 19 | SPI_2.begin(HSPI_SCLK, HSPI_MISO, HSPI_MOSI, HSPI_SS); //SCLK, MISO, MOSI, SS 20 | sensor.init(&SPI_2); 21 | 22 | 23 | Serial.println("Encoder ready"); 24 | _delay(1000); 25 | } 26 | 27 | 28 | void loop() { 29 | // sensor.update(); // If the simpleFOC library version is 2.2.0 or above, you need to uncomment this line 30 | // Output angle and angular velocity 31 | Serial.print(sensor.getAngle()); 32 | Serial.print("\t"); 33 | Serial.println(sensor.getVelocity()); 34 | } 35 | -------------------------------------------------------------------------------- /Test Code/8_hallsensor_test/8_hallsensor_test: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Test Code/8_hallsensor_test/8_hallsensor_test.ino: -------------------------------------------------------------------------------- 1 | // MKS ESP32 FOC V2.0 | Five-wire Hallsensor Example | Library:SimpleFOC 2.2.1 | Hardware:MKS ESP32 FOC V2.0 2 | 3 | #include 4 | 5 | //Encoder Example 6 | //18——Corresponding to the pin SCL_0 7 | //19——Corresponding to the pin SDA_0 8 | //15——Corresponding to the pin GH 9 | //1——Pole pairs 10 | HallSensor sensor1 = HallSensor(18, 19, 15, 1); 11 | //5——Corresponding to the pin SCL_0 12 | //23——Corresponding to the pin SDA_0 13 | //14——Corresponding to the pin GH 14 | //1——Pole pairs 15 | HallSensor sensor2 = HallSensor(5, 23, 14, 1); 16 | 17 | void doA(){sensor1.handleA();} 18 | void doB(){sensor1.handleB();} 19 | void doC(){sensor1.handleC();} 20 | void doA1(){sensor2.handleA();} 21 | void doB1(){sensor2.handleB();} 22 | void doC1(){sensor2.handleC();} 23 | 24 | void setup() { 25 | // // Encoder Settings 26 | // sensor1.pullup = Pullup::USE_EXTERN; 27 | 28 | // Initialize the magnetic sensor hardware 29 | sensor1.init(); 30 | sensor2.init(); 31 | // Enable hardware interrupts 32 | sensor1.enableInterrupts(doA, doB, doC); 33 | sensor2.enableInterrupts(doA1, doB1, doC1); 34 | 35 | 36 | Serial.begin(115200); 37 | 38 | 39 | Serial.println("Sensor ready"); 40 | _delay(1000); 41 | 42 | 43 | } 44 | 45 | void loop() { 46 | 47 | Serial.print(sensor1.getAngle()); 48 | Serial.print("\t"); 49 | Serial.println(sensor2.getAngle()); 50 | 51 | } 52 | -------------------------------------------------------------------------------- /Test Code/9_Hall_Motor_close_loop_velocity_example/9_Hall_Motor_close_loop_velocity_example.ino: -------------------------------------------------------------------------------- 1 | //MKS ESP32 FOC V2.0 | Hall Motor Close Loop Velocity Example | Library:SimpleFOC 2.2.1 | Hardware:MKS ESP32 FOC V2.0 2 | 3 | // !!!Notice!!! 4 | //①Enter T+speed in the serial port window to make the two motors rotate in a closed loop. For example, if you want both motors to rotate at a speed of 20 rad/s, enter T20. 5 | //②When using your own motor, please remember to modify the default pole pair number, that is, the value in BLDCMotor() and HallSensor(), and set it to your own pole pair number. 6 | //③The default power supply voltage of the program is 24V. If you use other voltages, please remember to modify the values ​​in the voltage_power_supply and voltage_limit variables. 7 | //④If you want to achieve better results or use other motors, please adjust the PID parameters yourself 8 | 9 | #include 10 | //18——Corresponding to the pin SCL_0 11 | //19——Corresponding to the pin SDA_0 12 | //15——Corresponding to the pin I_0 13 | //1——Pole pairs 14 | HallSensor sensor = HallSensor(18, 19, 15, 1);// U V W Pole pairs 15 | void doA(){sensor.handleA();} 16 | void doB(){sensor.handleB();} 17 | void doC(){sensor.handleC();} 18 | //5——Corresponding to the pin SCL_0 19 | //23——Corresponding to the pin SDA_0 20 | //13——Corresponding to the pin I_0 21 | //1——Pole pairs 22 | HallSensor sensor1 = HallSensor(5, 23, 13, 1); // U V W Pole pairs 23 | void doA1(){sensor1.handleA();} 24 | void doB1(){sensor1.handleB();} 25 | void doC1(){sensor1.handleC();} 26 | 27 | //Motor parameters Set the number of pole pairs according to the motor 28 | BLDCMotor motor = BLDCMotor(1); 29 | BLDCDriver3PWM driver = BLDCDriver3PWM(32, 33, 25, 22); 30 | 31 | BLDCMotor motor1 = BLDCMotor(1); 32 | BLDCDriver3PWM driver1 = BLDCDriver3PWM(26, 27, 14, 21); 33 | 34 | //Command settings 35 | float target_velocity = 5; 36 | Commander command = Commander(Serial); 37 | void doTarget(char* cmd) { command.scalar(&target_velocity, cmd); } 38 | 39 | void setup() { 40 | sensor.init(); 41 | sensor1.init(); 42 | sensor.enableInterrupts(doA, doB, doC); 43 | sensor1.enableInterrupts(doA1, doB1, doC1); 44 | 45 | 46 | //Connect the motor object and the sensor object 47 | motor.linkSensor(&sensor); 48 | motor1.linkSensor(&sensor1); 49 | 50 | //Supply voltage setting [V] 51 | driver.voltage_power_supply = 24; 52 | driver.init(); 53 | 54 | driver1.voltage_power_supply = 24; 55 | driver1.init(); 56 | //Connect the motor and driver objects 57 | motor.linkDriver(&driver); 58 | motor1.linkDriver(&driver1); 59 | 60 | // aligning voltage [V] 61 | motor.voltage_sensor_align = 3; 62 | // index search velocity [rad/s] 63 | motor.velocity_index_search = 3; 64 | 65 | //Motion control mode settings 66 | motor.controller = MotionControlType::velocity; 67 | motor1.controller = MotionControlType::velocity; 68 | 69 | //Speed ​​PI loop settings 70 | motor.PID_velocity.P = 0.01; 71 | motor1.PID_velocity.P = 0.01; 72 | motor.PID_velocity.I = 0.1; 73 | motor1.PID_velocity.I = 0.1; 74 | motor.PID_velocity.D = 0; 75 | motor1.PID_velocity.D = 0; 76 | //Angle P ring setting 77 | motor.P_angle.P = 20; 78 | motor1.P_angle.P = 20; 79 | //Maximum motor limiting voltage 80 | motor.voltage_limit = 6; 81 | motor1.voltage_limit = 6; 82 | 83 | motor.PID_velocity.output_ramp = 1000; 84 | motor1.PID_velocity.output_ramp = 1000; 85 | 86 | //Speed ​​low pass filter time constant 87 | motor.LPF_velocity.Tf = 0.01f; 88 | motor1.LPF_velocity.Tf = 0.01f; 89 | 90 | //Set a maximum speed limit 91 | motor.velocity_limit = 45; 92 | motor1.velocity_limit = 45; 93 | 94 | Serial.begin(115200); 95 | motor.useMonitoring(Serial); 96 | motor1.useMonitoring(Serial); 97 | 98 | 99 | //Initialize the motor 100 | motor.init(); 101 | motor1.init(); 102 | //Initialize FOC 103 | motor.initFOC(); 104 | motor1.initFOC(); 105 | command.add('T', doTarget, "target velocity"); 106 | 107 | Serial.println(F("Motor ready.")); 108 | Serial.println(F("Set the target velocity using serial terminal:")); 109 | } 110 | 111 | 112 | 113 | void loop() { 114 | motor.loopFOC(); 115 | motor1.loopFOC(); 116 | 117 | motor.move(target_velocity); 118 | motor1.move(target_velocity); 119 | 120 | command.run(); 121 | // sensor.update(); 122 | // sensor1.update(); 123 | 124 | // Serial.print(sensor1.getAngle()); 125 | // Serial.print("\t"); 126 | // Serial.println(sensor1.getVelocity()); 127 | } 128 | -------------------------------------------------------------------------------- /Test Code/Read Before You Begin.txt: -------------------------------------------------------------------------------- 1 | ❗Read❗Before❗You❗Begin❗ 2 | 3 | ① The parameters adapted by this set of routines are 2808 aircraft model motors. Please pay attention to modify the values ​​of the following parameters when using other motors: 4 | 5 | BLDCMotor() pole pair number; 6 | voltage_limit motor voltage limit The recommended setting value for aircraft model motors is 1~0.5, and the recommended setting for PTZ motors is below 4; 7 | current_limit motor current limit This value should be greater than the current loop parameter and less than the maximum safe current of the motor; 8 | If there is no input voltage detection in a routine, the value of voltage_power_supply also needs to be modified; 9 | The above parameters need to be especially careful, and a large wrong value may cause the board to burn! 10 | 11 | ② The open-loop control mode is a test routine, and the heating of the motor is inevitable. Be careful not to get burned! 12 | Please do not run the open-loop routine for more than one minute, otherwise it will cause overheating and burn the motor or circuit board! 13 | 14 | ③ The pid parameters in the closed-loop routine have been tested and can be used to drive 2808 aircraft model motors and 2804 PTZ motors. 15 | If you want better control effects, or when using other motors, please adjust the pid parameters yourself. 16 | 17 | ④MKS ESP32 FOC V2.0 can be powered by USB and burned with programs. It is recommended to burn the program first and then power it on. 18 | 19 | ⑤MKS ESP32 FOC V1.0&2.0 comes with a test program for the AS5600 encoder. If you notice it, please don't misunderstand it! 20 | Therefore, some components and interfaces will have signal flow. Although it will not cause the board to burn, it is recommended that you burn the program first and then connect the input power when using it for the first time. 21 | 22 | Thank you for purchasing Makerbase products! -------------------------------------------------------------------------------- /User Manual/User Manual: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /image/FireShot Capture 874 - MKS ESP32 FOC EN v2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makerbase-motor/MKS-ESP32FOC/23525e415933be639629f6fef85e250789b69289/image/FireShot Capture 874 - MKS ESP32 FOC EN v2.png -------------------------------------------------------------------------------- /image/MKS ESP32 FOC V2.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makerbase-motor/MKS-ESP32FOC/23525e415933be639629f6fef85e250789b69289/image/MKS ESP32 FOC V2.0.png -------------------------------------------------------------------------------- /image/image: -------------------------------------------------------------------------------- 1 | 2 | --------------------------------------------------------------------------------