I found a Brushless DC motor off of a CD drive and ran it with this Arduino. It makes a much more interesting demonstration for most people since this type of motor is difficult to work with. Still, the added complexity of my inverter means that anyone seriously planning to control brushless motors should purchase an electronic speed controller https://store.diydrones.com/ArduCopter_ESC_20_Amp_p/ac-0004-08.htm. Still, using the Arduino directly does make a good way to learn how these operate.
Here is my youtube video of the cd motor running:
Here is the code being ran in the video:
int PhaseA1 = 5; // the number of the pin controlling the High side of Phase 1
int PhaseA2 = 6; // the number of the pin controlling the Low side of Phase 1
int PhaseB1 = 7; // the number of the pin controlling the High side of Phase 2
int PhaseB2 = 8; // the number of the pin controlling the Low side of Phase 2
int PhaseC1 = 9; // the number of the pin controlling the High side of Phase 3
int PhaseC2 = 10; // the number of the pin controlling the Low side of Phase 3
int ledStateA1 = LOW; // ledState used to set whether that MOSFET is on or off
int ledStateA2 = LOW; // LOW side MOSFETS are on with a HIGH
int ledStateB1 = HIGH; // HIGH side MOSFETS are on with a LOW
int ledStateB2 = HIGH; // At any given time 2 MOSFETS should be ON, 4 OFF
int ledStateC1 = LOW;
int ledStateC2 = LOW;
long previousMillis = 0; // will store last time a cycle finished was updated
int sensorPin = A0; // Pin which reads output from the switch controlling phase rotation
int sensorValue = 0; // Initial sensor value
long wavelength = 100; // wavelength of the output
void setup() {
// set the digital pin as output:
pinMode(PhaseA1, OUTPUT);
pinMode(PhaseA2, OUTPUT);
pinMode(PhaseB1, OUTPUT);
pinMode(PhaseB2, OUTPUT);
pinMode(PhaseC1, OUTPUT);
pinMode(PhaseC2, OUTPUT);
}
void loop()
{
unsigned long currentMillis = millis();
sensorValue = analogRead(sensorPin);
if(sensorValue>500){
PhaseA1 = 5; // the number of the LED pin
PhaseA2 = 6;
PhaseB1 = 7;
PhaseB2 = 8;
}
else{
PhaseA1 = 7; // the number of the LED pin
PhaseA2 = 8;
PhaseB1 = 5;
PhaseB2 = 6;
}
int sensorValueMap =map(sensorValue, 150, 850, 1, 11); // maps sensorValues into 11 different cases.
// If the potentiometer did not have resistors
// than the second two numbers would be 0 and 1024
switch(sensorValueMap){ // switches wavelength depending on value sent by potentiometer.
case 1:
wavelength = 15; // if the sensorValue is in case 1, than the wavelength is 15ms.
break;
case 2:
wavelength = 30; // if the sensorValue is in case 2, than the wavelength is 30ms...
break;
case 3:
wavelength = 100;
break;
case 4:
wavelength = 500;
break;
case 5:
wavelength = 1000;
break;
case 6:
wavelength = 5000;
break;
case 7:
wavelength = 1000;
break;
case 8:
wavelength = 500;
break;
case 9:
wavelength = 100;
break;
case 10:
wavelength = 30;
break;
case 11:
wavelength = 15;
break;
}
unsigned long elapsed = currentMillis - previousMillis; // elapsed is the time since the end of the last cycle
int pulses =map(elapsed, 0, 2*wavelength, 0, 12); // maps the elapsed time into 13 possible cases
switch (pulses){
case 0:
ledStateA1=HIGH; // Sets the state for the A MOSFETs so the output from the inverter follows the correct waveform
ledStateA2=LOW; // Case 0 is time = 0
ledStateB1=HIGH; // From time=0 to time=wavelength/12 phase A is 0, phase B is Negative, phase C is Positive
ledStateB2=HIGH;
ledStateC1=LOW;
ledStateC2=LOW;
digitalWrite(PhaseA1, ledStateA1);
digitalWrite(PhaseA2, ledStateA2);
digitalWrite(PhaseB1, ledStateB1);
digitalWrite(PhaseB2, ledStateB2);
digitalWrite(PhaseC1, ledStateC1);
digitalWrite(PhaseC2, ledStateC2);
break;
case 1: // Case 1 is time = wavelength/12
ledStateA1=LOW; // Phase A is switching to Pos
ledStateA2=LOW;
digitalWrite(PhaseA1, ledStateA1);
digitalWrite(PhaseA2, ledStateA2);
ledStateC1=HIGH; // Phase C is switching to 0
ledStateC2=LOW;
digitalWrite(PhaseC1, ledStateC1);
digitalWrite(PhaseC2, ledStateC2);
break;
case 3: // Case 3 is time = 3*wavelength/12
ledStateB1=HIGH; // phase B is switching to 0
ledStateB2=LOW;
digitalWrite(PhaseB1, ledStateB1);
digitalWrite(PhaseB2, ledStateB2);
ledStateC1=HIGH; //Phase C is switching to negative
ledStateC2=HIGH;
digitalWrite(PhaseC1, ledStateC1);
digitalWrite(PhaseC2, ledStateC2);
break;
case 5: // Case 5 is time = 5*wavelength/12
ledStateB1=LOW; // Phase B is switching to positive
ledStateB2=LOW;
digitalWrite(PhaseB1, ledStateB1);
digitalWrite(PhaseB2, ledStateB2);
ledStateA1=HIGH; // Phase A is switching to 0
ledStateA2=LOW;
digitalWrite(PhaseA1, ledStateA1);
digitalWrite(PhaseA2, ledStateA2);
break;
case 7: // Case 7 is time = 7*wavelength/12
ledStateA1=HIGH; // Phase A is switching to negative
ledStateA2=HIGH;
digitalWrite(PhaseA1, ledStateA1);
digitalWrite(PhaseA2, ledStateA2);
ledStateC1=HIGH; // Phase C is switching to 0
ledStateC2=LOW;
digitalWrite(PhaseC1, ledStateC1);
digitalWrite(PhaseC2, ledStateC2);
break;
case 9: // Case 9 is time = 9*wavelength/12
ledStateC1=LOW; // phase C is switching to positive
ledStateC2=LOW;
digitalWrite(PhaseC1, ledStateC1);
digitalWrite(PhaseC2, ledStateC2);
ledStateB1=HIGH; // phase B is switching to negative
ledStateB2=HIGH;
digitalWrite(PhaseB1, ledStateB1);
digitalWrite(PhaseB2, ledStateB2);
break;
case 11: // Case 11 is time = 11*wavelength/12
ledStateA1=HIGH; //Phase A is switching to 0
ledStateA2=LOW;
digitalWrite(PhaseA1, ledStateA1);
digitalWrite(PhaseA2, ledStateA2);
ledStateB1=HIGH; // Phase B is switching to negative
ledStateB2=HIGH;
digitalWrite(PhaseB1, ledStateB1);
digitalWrite(PhaseB2, ledStateB2);
break;
case 12: // Case 12 is time = 12*wavelength/12 or the end of the program
previousMillis = currentMillis;
break;
}
if(pulses>12){
previousMillis = currentMillis; // prevents program from crashing if it misses case 12
}
}
I switched to using switch case instead of a lot of if statements which rather mysteriously allowed the motor to spin the motor at a notably higher speed. Unfortunately the speed control programming makes it run a little choppy. The Arduino seems to need to stop and think at regular intervals.
This code, without the speed control, runs faster. I can get a wavelength as short as 15ms to work, which means that the motor is spinning something around 1800 rpm.