Components and supplies
Rotary potentiometer (generic)
L298N Stepper Motor Controller Module
LiPO or NiMH battery, 2 cell (7.2V) or 3 cell (11.1V) tested
Arduino UNO
BLDC Brushless DC motor
Switch DPDT
Project description
Code
BLDC Brushless DC motor code V2 + stepper motor code
arduino
This code drives both a BLDC and a stepper motor at the same time. Three potentiometers are used to control the speed of both motors and the position of the stepper. A Protoneer Arduino CNC Shield V3 with Pololu A4988 Stepper Motor Driver Carrier fitted, to drive the stepper motor. An L298N Stepper Motor Controller Module is used to drive BLDC.
1/* 2 Derived from non-blocking mode Stepper Driver example by Laurentiu Badea 3 4 Parts required: 5 - Arduino Uno 6 - L298N Stepper Motor Controller Module, to drive BLDC. (Jaycar XC-4492)(Nb. LEDs L3 and L3 are reversed with respect to Motor B output pins) 7 - Protoneer Arduino CNC Shield V3 with Pololu A4988 Stepper Motor Driver Carrier fitted, to drive stepper motor. 8 - DC Brushless Motor (BLDC) (funtobuyonline GBM6324-180T appears to be internally wired as though 3-phase stepper motor). 9 (Refer http://www.aerodesign.de/peter/2001/LRK350/index_eng.html and http://www.aerodesign.de/peter/2001/LRK350/Paper_from%20_Wroclaw.html) 10 - 4 wire stepper motor (eg 12V NEMA 17). 11 - 2 or 3 cell LiPO or NiMH battery. 12 - Switch in series with battery. 13 - Pot delay on A5 because A0 is reserved by CNC Shield. Used for speed control of BLDC motor 14 - Pot delay on A4 connected to pot mounted on stepper motor to provide position feedback. 15 When the brush of the pot wipes past the extremes of the variable resistor the voltage will float, so values selected for this pot must be much higher than 0. 16 - Pot delay on A3 controls speed of rotation of the stepper motor 17 18 Michael Barr in January 2019 19 */ 20 21#include <Arduino.h> // Required to drive stepper motor 22 23// Motor steps per revolution. Most steppers are 200 steps or 1.8 degrees/step 24#define MOTOR_STEPS 200 25#define RPM 10 26#define MICROSTEPS 1 // Microstepping mode. If you hardwired it to save pins, set to the same value here. 27#define DIR 5 28#define STEP 2 29#define ENABLE 8 // optional (just delete ENABLE from everywhere if not used) 30 31// Generally, you should use "unsigned long" for variables that hold time 32// The value will quickly become too large for an int to store 33unsigned long previousMillisA3 = 0; // will store last time stepper motor was at extreme end of its arc 34unsigned long previousMillisBLDC0 = 0; // stores when BLDC moved to phase 0 35 36int potA5 = 50; 37unsigned long difference =0; 38const int highPotA5 = 100; 39// Defines pins numbers. Wire BLDC to pins on CNC shield which are not used because not using Y and Z motors 40const int BLDC1 = 3; // pin labelled Y STEP 41const int BLDC2 = 4; // pin labelled Y DIR 42const int BLDC3 = 6; // pin labelled Z STEP 43 44int potA3; // Defines variables 45int potA4,directionLinkage2; // Defines variables 46 47/* 48 * Choose one of the sections below that match your board 49#include "DRV8834.h" 50#define M0 10 51#define M1 11 52DRV8834 stepper(MOTOR_STEPS, DIR, STEP, ENABLE, M0, M1); 53*/ 54#include "A4988.h" 55#define MS1 10 56#define MS2 11 57#define MS3 12 58A4988 stepper(MOTOR_STEPS, DIR, STEP, ENABLE, MS1, MS2, MS3); 59 60// #include "DRV8825.h" 61// #define MODE0 10 62// #define MODE1 11 63// #define MODE2 12 64// DRV8825 stepper(MOTOR_STEPS, DIR, STEP, ENABLE, MODE0, MODE1, MODE2); 65 66// #include "DRV8880.h" 67// #define M0 10 68// #define M1 11 69// #define TRQ0 6 70// #define TRQ1 7 71// DRV8880 stepper(MOTORS_STEPS, DIR, STEP, ENABLE, M0, M1, TRQ0, TRQ1); 72 73void setup() { 74 Serial.begin(115200); 75 // declare the BLDC pins as outputs 76 pinMode(BLDC1, OUTPUT); 77 pinMode(BLDC2, OUTPUT); 78 pinMode(BLDC3, OUTPUT); 79 80 stepper.begin(RPM, MICROSTEPS); 81 stepper.enable(); 82 // set current level (for DRV8880 only). Valid percent values are 25, 50, 75 or 100. 83 // stepper.setCurrent(100); 84 // Serial.println("START"); 85} 86 87void loop() { 88 rotateStepper(); // Rotate 4 wire stepper motor 89 rotateBLDC(); // Rotate 3 wire BLDC motor 90 // Serial.println(); 91 } 92 93// Function for rotating stepper motor 94void rotateStepper(){ 95 // Linkage 2 stepper motor speed 96 int potA3 = analogRead(A3); // Reads the potentiometer 97 potA3 = map(potA3,0,1023,5,360); // Converts the read values of the potentiometer from 0 to 1023 into an angle (0 to 360 degrees ) 98 unsigned long currentMillisA3 = millis(); // Get current time 99 100 // Rotate stepper motor until pot is rotated 70 degrees and then rotate back to 0 degrees 101 int potA4 = analogRead(A4); // Reads the potentiometer 102 potA4 = map(potA4,0,1023,0,360); // Converts the read values of the potentiometer from 0 to 1023 into an angle (0 to 360 degrees ) 103 104 // The value selected here must be substantially above zero, as immediately less than zero is 360, which confuses the motor and me 105 if (potA4 <=80) { 106 // Serial.print(" potA4 <=80"); // Pot angled to side 107 directionLinkage2 = 0; 108 } 109 else if (potA4 >=185) { // Pot angled to other side 110 // Serial.print(" potA4 >=185"); 111 directionLinkage2 = 1; 112 } 113 114 if (directionLinkage2 == 0 && currentMillisA3 - previousMillisA3 >= potA3) { 115 // Serial.print(" rotating out"); 116 stepper.rotate(2); 117 previousMillisA3 = currentMillisA3; 118 } 119 else if (directionLinkage2 == 1 && currentMillisA3 - previousMillisA3 >= potA3) { 120 // Serial.print(" rotating back"); 121 stepper.rotate(-2); 122 previousMillisA3 = currentMillisA3; 123 } 124} 125 126// Function for rotating BLDC motor 127void rotateBLDC() { 128 potA5= analogRead(A5); //Read input from analog pin potA5 and store in potA5 129 potA5= map(potA5, 0, 1023,30,110); //map potA5 to minimum and maximum 130 // Serial.print("potA5:"); 131 // Serial.print(potA5); 132 unsigned long currentMillis = millis(); 133 difference = currentMillis - previousMillisBLDC0; 134 // Serial.print(" difference = "); 135 // Serial.print(difference); 136 137 if (potA5 >= highPotA5) { // Turn off BLDC when BLDC pot is near zero resistance 138 digitalWrite(BLDC1, LOW); 139 digitalWrite(BLDC2, LOW); 140 digitalWrite(BLDC3, LOW); 141 // Serial.println(" off"); 142 } 143 else if (difference >= potA5 * 6) { 144 previousMillisBLDC0 = currentMillis; 145 // Serial.println(" 6"); 146 } 147 else if (difference >= potA5 * 5) { 148 digitalWrite(BLDC1, HIGH); 149 digitalWrite(BLDC2, HIGH); 150 digitalWrite(BLDC3, LOW); 151 // Serial.println(" 5"); 152 } 153 else if (difference >= potA5 * 4) { 154 digitalWrite(BLDC1, HIGH); 155 digitalWrite(BLDC2, LOW); 156 digitalWrite(BLDC3, LOW); 157 // Serial.println(" 4"); 158 } 159 else if (difference >= potA5 * 3) { 160 digitalWrite(BLDC1, HIGH); 161 digitalWrite(BLDC2, LOW); 162 digitalWrite(BLDC3, HIGH); 163 // Serial.println(" 3"); 164 } 165 else if (difference >= potA5 * 2) { 166 digitalWrite(BLDC1, LOW); 167 digitalWrite(BLDC2, LOW); 168 digitalWrite(BLDC3, HIGH); 169 // Serial.println(" 2"); 170 } 171 else if (difference >= potA5) { 172 digitalWrite(BLDC1, LOW); 173 digitalWrite(BLDC2, HIGH); 174 digitalWrite(BLDC3, HIGH); 175 // Serial.println(" 1"); 176 } 177 else { 178 digitalWrite(BLDC1, LOW); 179 digitalWrite(BLDC2, HIGH); 180 digitalWrite(BLDC3, LOW); 181 // Serial.println(" 0"); 182 } 183} 184
BLDC Brushless DC motor code V2 + stepper motor code
arduino
This code drives both a BLDC and a stepper motor at the same time. Three potentiometers are used to control the speed of both motors and the position of the stepper. A Protoneer Arduino CNC Shield V3 with Pololu A4988 Stepper Motor Driver Carrier fitted, to drive the stepper motor. An L298N Stepper Motor Controller Module is used to drive BLDC.
1/* 2 Derived from non-blocking mode Stepper Driver example by Laurentiu Badea 3 4 Parts required: 5 - Arduino Uno 6 - L298N Stepper Motor Controller Module, to drive BLDC. (Jaycar XC-4492)(Nb. LEDs L3 and L3 are reversed with respect to Motor B output pins) 7 - Protoneer Arduino CNC Shield V3 with Pololu A4988 Stepper Motor Driver Carrier fitted, to drive stepper motor. 8 - DC Brushless Motor (BLDC) (funtobuyonline GBM6324-180T appears to be internally wired as though 3-phase stepper motor). 9 (Refer http://www.aerodesign.de/peter/2001/LRK350/index_eng.html and http://www.aerodesign.de/peter/2001/LRK350/Paper_from%20_Wroclaw.html) 10 - 4 wire stepper motor (eg 12V NEMA 17). 11 - 2 or 3 cell LiPO or NiMH battery. 12 - Switch in series with battery. 13 - Pot delay on A5 because A0 is reserved by CNC Shield. Used for speed control of BLDC motor 14 - Pot delay on A4 connected to pot mounted on stepper motor to provide position feedback. 15 When the brush of the pot wipes past the extremes of the variable resistor the voltage will float, so values selected for this pot must be much higher than 0. 16 - Pot delay on A3 controls speed of rotation of the stepper motor 17 18 Michael Barr in January 2019 19 */ 20 21#include <Arduino.h> // Required to drive stepper motor 22 23// Motor steps per revolution. Most steppers are 200 steps or 1.8 degrees/step 24#define MOTOR_STEPS 200 25#define RPM 10 26#define MICROSTEPS 1 // Microstepping mode. If you hardwired it to save pins, set to the same value here. 27#define DIR 5 28#define STEP 2 29#define ENABLE 8 // optional (just delete ENABLE from everywhere if not used) 30 31// Generally, you should use "unsigned long" for variables that hold time 32// The value will quickly become too large for an int to store 33unsigned long previousMillisA3 = 0; // will store last time stepper motor was at extreme end of its arc 34unsigned long previousMillisBLDC0 = 0; // stores when BLDC moved to phase 0 35 36int potA5 = 50; 37unsigned long difference =0; 38const int highPotA5 = 100; 39// Defines pins numbers. Wire BLDC to pins on CNC shield which are not used because not using Y and Z motors 40const int BLDC1 = 3; // pin labelled Y STEP 41const int BLDC2 = 4; // pin labelled Y DIR 42const int BLDC3 = 6; // pin labelled Z STEP 43 44int potA3; // Defines variables 45int potA4,directionLinkage2; // Defines variables 46 47/* 48 * Choose one of the sections below that match your board 49#include "DRV8834.h" 50#define M0 10 51#define M1 11 52DRV8834 stepper(MOTOR_STEPS, DIR, STEP, ENABLE, M0, M1); 53*/ 54#include "A4988.h" 55#define MS1 10 56#define MS2 11 57#define MS3 12 58A4988 stepper(MOTOR_STEPS, DIR, STEP, ENABLE, MS1, MS2, MS3); 59 60// #include "DRV8825.h" 61// #define MODE0 10 62// #define MODE1 11 63// #define MODE2 12 64// DRV8825 stepper(MOTOR_STEPS, DIR, STEP, ENABLE, MODE0, MODE1, MODE2); 65 66// #include "DRV8880.h" 67// #define M0 10 68// #define M1 11 69// #define TRQ0 6 70// #define TRQ1 7 71// DRV8880 stepper(MOTORS_STEPS, DIR, STEP, ENABLE, M0, M1, TRQ0, TRQ1); 72 73void setup() { 74 Serial.begin(115200); 75 // declare the BLDC pins as outputs 76 pinMode(BLDC1, OUTPUT); 77 pinMode(BLDC2, OUTPUT); 78 pinMode(BLDC3, OUTPUT); 79 80 stepper.begin(RPM, MICROSTEPS); 81 stepper.enable(); 82 // set current level (for DRV8880 only). Valid percent values are 25, 50, 75 or 100. 83 // stepper.setCurrent(100); 84 // Serial.println("START"); 85} 86 87void loop() { 88 rotateStepper(); // Rotate 4 wire stepper motor 89 rotateBLDC(); // Rotate 3 wire BLDC motor 90 // Serial.println(); 91 } 92 93// Function for rotating stepper motor 94void rotateStepper(){ 95 // Linkage 2 stepper motor speed 96 int potA3 = analogRead(A3); // Reads the potentiometer 97 potA3 = map(potA3,0,1023,5,360); // Converts the read values of the potentiometer from 0 to 1023 into an angle (0 to 360 degrees ) 98 unsigned long currentMillisA3 = millis(); // Get current time 99 100 // Rotate stepper motor until pot is rotated 70 degrees and then rotate back to 0 degrees 101 int potA4 = analogRead(A4); // Reads the potentiometer 102 potA4 = map(potA4,0,1023,0,360); // Converts the read values of the potentiometer from 0 to 1023 into an angle (0 to 360 degrees ) 103 104 // The value selected here must be substantially above zero, as immediately less than zero is 360, which confuses the motor and me 105 if (potA4 <=80) { 106 // Serial.print(" potA4 <=80"); // Pot angled to side 107 directionLinkage2 = 0; 108 } 109 else if (potA4 >=185) { // Pot angled to other side 110 // Serial.print(" potA4 >=185"); 111 directionLinkage2 = 1; 112 } 113 114 if (directionLinkage2 == 0 && currentMillisA3 - previousMillisA3 >= potA3) { 115 // Serial.print(" rotating out"); 116 stepper.rotate(2); 117 previousMillisA3 = currentMillisA3; 118 } 119 else if (directionLinkage2 == 1 && currentMillisA3 - previousMillisA3 >= potA3) { 120 // Serial.print(" rotating back"); 121 stepper.rotate(-2); 122 previousMillisA3 = currentMillisA3; 123 } 124} 125 126// Function for rotating BLDC motor 127void rotateBLDC() { 128 potA5= analogRead(A5); //Read input from analog pin potA5 and store in potA5 129 potA5= map(potA5, 0, 1023,30,110); //map potA5 to minimum and maximum 130 // Serial.print("potA5:"); 131 // Serial.print(potA5); 132 unsigned long currentMillis = millis(); 133 difference = currentMillis - previousMillisBLDC0; 134 // Serial.print(" difference = "); 135 // Serial.print(difference); 136 137 if (potA5 >= highPotA5) { // Turn off BLDC when BLDC pot is near zero resistance 138 digitalWrite(BLDC1, LOW); 139 digitalWrite(BLDC2, LOW); 140 digitalWrite(BLDC3, LOW); 141 // Serial.println(" off"); 142 } 143 else if (difference >= potA5 * 6) { 144 previousMillisBLDC0 = currentMillis; 145 // Serial.println(" 6"); 146 } 147 else if (difference >= potA5 * 5) { 148 digitalWrite(BLDC1, HIGH); 149 digitalWrite(BLDC2, HIGH); 150 digitalWrite(BLDC3, LOW); 151 // Serial.println(" 5"); 152 } 153 else if (difference >= potA5 * 4) { 154 digitalWrite(BLDC1, HIGH); 155 digitalWrite(BLDC2, LOW); 156 digitalWrite(BLDC3, LOW); 157 // Serial.println(" 4"); 158 } 159 else if (difference >= potA5 * 3) { 160 digitalWrite(BLDC1, HIGH); 161 digitalWrite(BLDC2, LOW); 162 digitalWrite(BLDC3, HIGH); 163 // Serial.println(" 3"); 164 } 165 else if (difference >= potA5 * 2) { 166 digitalWrite(BLDC1, LOW); 167 digitalWrite(BLDC2, LOW); 168 digitalWrite(BLDC3, HIGH); 169 // Serial.println(" 2"); 170 } 171 else if (difference >= potA5) { 172 digitalWrite(BLDC1, LOW); 173 digitalWrite(BLDC2, HIGH); 174 digitalWrite(BLDC3, HIGH); 175 // Serial.println(" 1"); 176 } 177 else { 178 digitalWrite(BLDC1, LOW); 179 digitalWrite(BLDC2, HIGH); 180 digitalWrite(BLDC3, LOW); 181 // Serial.println(" 0"); 182 } 183} 184
BLDC Brushless DC motor code V2
arduino
This code is simply to drive a BLDC using an L298 driver board and an Arduino. The sketch after this sketch is for driving a stepper motor at the same time as the BLDC. V1 code pulsed once and then waited for interval before sending next pulse, whereas this improved code keeps pulsing the same phase until the interval is past. Also, input from pot connected to A5, now varies BLDC motor speed. Removed 'step' variable by reversing order in which time interval is tested. Serial.print is commented out to improve smoothness of motion.
1/* 2 DC Brushless Motor (BLDC) 3 Appears to be internally wired as though 3-phase stepper motor 4 Tested with funtobuyonline GBM6324-180T 5 6 Parts required: 7 - Arduino (If using Chinese Nano then install CH340 driver and use ATmega328P (Old Bootloader) 8 - L298N Stepper Motor Controller Module (Jaycar XC-4492)(Nb. LEDs L3 and L3 are reversed with respect to Motor B output pins) 9 - 2 or 3 cell LiPO or NiMH battery 10 - Switch in series with battery 11 12 Michael Barr January 2019 13*/ 14 15// Generally, you should use "unsigned long" for variables that hold time 16// The value will quickly become too large for an int to store 17unsigned long previousMillis = 0; 18unsigned long difference =0; 19int potA5; 20// Define pins numbers 21const int tri1 = 3; 22const int tri2 = 4; 23const int tri3 = 6; 24 25void setup() { 26 // initialize the serial port: 27 Serial.begin(9600); 28 29 // declare MOTOR A and MOTOR B pins as outputs 30 pinMode(tri1, OUTPUT); 31 pinMode(tri2, OUTPUT); 32 pinMode(tri3, OUTPUT); 33 34} 35 36void loop() { 37 potA5= analogRead(A5); //Read input from analog pin potA5 and store in potA5 38 potA5= map(potA5, 0, 1023,30,100); //map potA5 to minimum and maximum 39 // Serial.print("potA5:"); 40 // Serial.print(potA5); 41 unsigned long currentMillis = millis(); 42 difference = currentMillis - previousMillis; 43 // Serial.print(" difference = "); 44 // Serial.print(difference); 45 46 if (difference >= potA5 * 6) { 47 previousMillis = currentMillis; 48 // Serial.println(" 6"); 49 } 50 else if (difference >= potA5 * 5) { 51 digitalWrite(tri1, HIGH); 52 digitalWrite(tri2, HIGH); 53 digitalWrite(tri3, LOW); 54 // Serial.println(" 5"); 55 } 56 else if (difference >= potA5 * 4) { 57 digitalWrite(tri1, HIGH); 58 digitalWrite(tri2, LOW); 59 digitalWrite(tri3, LOW); 60 // Serial.println(" 4"); 61 } 62 else if (difference >= potA5 * 3) { 63 digitalWrite(tri1, HIGH); 64 digitalWrite(tri2, LOW); 65 digitalWrite(tri3, HIGH); 66 // Serial.println(" 3"); 67 } 68 else if (difference >= potA5 * 2) { 69 digitalWrite(tri1, LOW); 70 digitalWrite(tri2, LOW); 71 digitalWrite(tri3, HIGH); 72 // Serial.println(" 2"); 73 } 74 else if (difference >= potA5) { 75 digitalWrite(tri1, LOW); 76 digitalWrite(tri2, HIGH); 77 digitalWrite(tri3, HIGH); 78 // Serial.println(" 1"); 79 } 80 else { 81 digitalWrite(tri1, LOW); 82 digitalWrite(tri2, HIGH); 83 digitalWrite(tri3, LOW); 84 // Serial.println(" 0"); 85 } 86}
Downloadable files
BLDC and L293
This layout is approximately right. I used a L298N Stepper Motor Controller Module (Jaycar XC-4492) instead of the genuine Arduino shield (which would have been easier, as it mounts directly on the Uno).
BLDC and L293
BLDC and L293
This layout is approximately right. I used a L298N Stepper Motor Controller Module (Jaycar XC-4492) instead of the genuine Arduino shield (which would have been easier, as it mounts directly on the Uno).
BLDC and L293
Comments
Only logged in users can leave comments
mbarraus
0 Followers
•0 Projects
Table of contents
Intro
8
0