|
| 1 | +--- |
| 2 | +layout: default |
| 3 | +title: Stepper Motor Control Nucleo-64 |
| 4 | +parent: Example projects |
| 5 | +description: "Arduino Simple Field Oriented Control (FOC) library ." |
| 6 | +nav_order: 8 |
| 7 | +permalink: /stepper_control_nucleo |
| 8 | +grand_parent: Arduino <span class="simple">Simple<span class="foc">FOC</span>library</span> |
| 9 | +--- |
| 10 | + |
| 11 | + |
| 12 | +# Stepper motor control example<br>using L298N and Stm32 Nucleo-64 |
| 13 | +For this stepper motor control example we are going to be using this hardware: |
| 14 | + |
| 15 | +[Stm32 Nucleo-64](https://www.mouser.fr/ProductDetail/STMicroelectronics/NUCLEO-F446RE?qs=%2Fha2pyFaduj0LE%252BzmDN2WNd7nDNNMR7%2Fr%2FThuKnpWrd0IvwHkOHrpg%3D%3D) | [L298N driver](https://www.ebay.com/itm/L298N-DC-Stepper-Motor-Driver-Module-Dual-H-Bridge-Control-Board-for-Arduino/362863436137?hash=item547c58a169:g:gkYAAOSwe6FaJ5Df) | [AMT 103 encoder](https://www.mouser.fr/ProductDetail/CUI-Devices/AMT103-V?qs=%2Fha2pyFaduiAsBlScvLoAWHUnKz39jAIpNPVt58AQ0PVb84dpbt53g%3D%3D) | [NEMA 17](https://www.ebay.com/itm/Nema-17-Stepper-Motor-Bipolar-2A-59Ncm-83-6oz-in-48mm-Body-4-lead-3D-Printer-CNC/282285186801?hash=item41b9821ef1:g:7dUAAOSwEzxYSl25) |
| 16 | +--- | --- | --- | --- |
| 17 | +<img src="extras/Images/nucleo.jpg" class="imgtable150"> | <img src="extras/Images/l298n.jpg" class="imgtable150"> | <img src="extras/Images/enc1.png" class="imgtable150"> | <img src="extras/Images/nema17_2.jpg" class="imgtable150"> |
| 18 | + |
| 19 | +# Connecting everything together |
| 20 | + |
| 21 | +Here is an example of the connection scheme using the L298N and Nucleo-64: |
| 22 | + |
| 23 | +<p><img src="extras/Images/stepper_connection.png" class="img400"></p> |
| 24 | + |
| 25 | +## L298N |
| 26 | +- Channels `ENA` and `ENB` are connected to pins `7` and `8` |
| 27 | +- Channels `IN1`, `IN2`, `IN3` and `IN4` are connected to the pins `5`, `6`, `9`, `10` |
| 28 | +- Common ground is connected in between nucleo and L298N |
| 29 | +- 12V power-supply is connected directly to the driver |
| 30 | + |
| 31 | +## Encoder |
| 32 | +- Channels `A` and `B` are connected to the pins `A0` qnd `A1` |
| 33 | +- Index channel is not used in this example but you cqn easily modify this example to support it |
| 34 | + |
| 35 | +## Motor |
| 36 | +- Motor phases `A1`, `A2`, `B1`and `B2` are connected directly the moto connectors of the L298N chip. |
| 37 | + |
| 38 | + |
| 39 | + |
| 40 | +# Full Arduino code |
| 41 | + |
| 42 | +```cpp |
| 43 | +#include <SimpleFOC.h> |
| 44 | + |
| 45 | +// Stepper motor instance |
| 46 | +StepperMotor motor = StepperMotor(5, 6, 9, 10, 50, 8, 7); |
| 47 | + |
| 48 | +// encoder instance |
| 49 | +Encoder encoder = Encoder(A1, A2, 2048); |
| 50 | + |
| 51 | +// Interrupt routine intialisation |
| 52 | +// channel A and B callbacks |
| 53 | +void doA(){encoder.handleA();} |
| 54 | +void doB(){encoder.handleB();} |
| 55 | + |
| 56 | +void setup() { |
| 57 | + |
| 58 | + // initialize encoder sensor hardware |
| 59 | + encoder.init(); |
| 60 | + encoder.enableInterrupts(doA, doB); |
| 61 | + // link the motor to the sensor |
| 62 | + motor.linkSensor(&encoder); |
| 63 | + |
| 64 | + // choose FOC modulation |
| 65 | + motor.foc_modulation = FOCModulationType::SpaceVectorPWM; |
| 66 | + |
| 67 | + // power supply voltage [V] |
| 68 | + motor.voltage_power_supply = 12; |
| 69 | + |
| 70 | + // set control loop type to be used |
| 71 | + motor.controller = ControlType::voltage; |
| 72 | + |
| 73 | + // contoller configuration based on the controll type |
| 74 | + motor.PID_velocity.P = 0.2; |
| 75 | + motor.PID_velocity.I = 20; |
| 76 | + motor.PID_velocity.D = 0; |
| 77 | + // default voltage_power_supply |
| 78 | + motor.voltage_limit = 12; |
| 79 | + |
| 80 | + // velocity low pass filtering time constant |
| 81 | + motor.LPF_velocity.Tf = 0.01; |
| 82 | + |
| 83 | + // angle loop controller |
| 84 | + motor.P_angle.P = 20; |
| 85 | + // angle loop velocity limit |
| 86 | + motor.velocity_limit = 50; |
| 87 | + |
| 88 | + // use monitoring with serial for motor init |
| 89 | + // monitoring port |
| 90 | + Serial.begin(115200); |
| 91 | + // comment out if not needed |
| 92 | + motor.useMonitoring(Serial); |
| 93 | + |
| 94 | + // initialise motor |
| 95 | + motor.init(); |
| 96 | + // align encoder and start FOC |
| 97 | + motor.initFOC(); |
| 98 | + |
| 99 | + // set the inital target value |
| 100 | + motor.target = 2; |
| 101 | + |
| 102 | + |
| 103 | + // Run user commands to configure and the motor (find the full command list in docs.simplefoc.com) |
| 104 | + Serial.println("Motor commands sketch | Initial motion control > torque/voltage : target 2V."); |
| 105 | + |
| 106 | + _delay(1000); |
| 107 | +} |
| 108 | + |
| 109 | + |
| 110 | +void loop() { |
| 111 | + // iterative setting FOC phase voltage |
| 112 | + motor.loopFOC(); |
| 113 | + |
| 114 | + // iterative function setting the outter loop target |
| 115 | + // velocity, position or voltage |
| 116 | + // if tatget not set in parameter uses motor.target variable |
| 117 | + motor.move(); |
| 118 | + |
| 119 | + // user communication |
| 120 | + motor.command(serialReceiveUserCommand()); |
| 121 | +} |
| 122 | + |
| 123 | +// utility function enabling serial communication the user |
| 124 | +String serialReceiveUserCommand() { |
| 125 | + |
| 126 | + // a string to hold incoming data |
| 127 | + static String received_chars; |
| 128 | + |
| 129 | + String command = ""; |
| 130 | + |
| 131 | + while (Serial.available()) { |
| 132 | + // get the new byte: |
| 133 | + char inChar = (char)Serial.read(); |
| 134 | + // add it to the string buffer: |
| 135 | + received_chars += inChar; |
| 136 | + |
| 137 | + // end of user input |
| 138 | + if (inChar == '\n') { |
| 139 | + |
| 140 | + // execute the user command |
| 141 | + command = received_chars; |
| 142 | + |
| 143 | + // reset the command buffer |
| 144 | + received_chars = ""; |
| 145 | + } |
| 146 | + } |
| 147 | + return command; |
| 148 | +} |
| 149 | + |
| 150 | +``` |
0 commit comments