3-Phase motor control

This is my first ever attempt at programming, beyond "Hello world".
I was surprised that it compiled at all and astonished that it actually seems to be doing what I want it to! It's the first step in a much larger project.
The comments in the code should explain it all.
Any criticism/suggestions/improvements/comments are most welcome.
Martin

/*This sketch was produced to manage a
 3-phase motor using a potentiometer to
 control both direction and speed. 
The middle of the travel of the pot is "off" 
with the speed in either direction increasing 
with clockwise or anticlockwise turning.
*/



int potPin = 2;                  // select the input pin 
                                //for the potentiometer
int phase1 = 10;                 // select the output
int phase2 = 11;                 //  pins for each 
int phase3 = 12;                 // of the phases
int val = 0;                     /* variable to store the 
                                       value coming from 
                                        the pot*/

void setup() 
{
  pinMode(phase1, OUTPUT);        //declare the
  pinMode(phase2, OUTPUT);        // phase pins 
  pinMode(phase3, OUTPUT);        // as OUTPUTs
                          }

void loop() 
{
 {digitalWrite(13, LOW);}          //This LED will  
                                     //indicate the centre
                                     //off posistion later,
                                     //turn it off for now.
  val = analogRead(potPin);         // Read the value from
                                       // the potentiometer. 
  int speedForward = 2*(1023 - val);  /* This expression  
                                      reverses the values beyond
                                      512 so that the longest
                                      delay (slowest speed)
                                      lies at the RH 
                                      end of the range.
                                      Multiply by 2 to restore
                                      to maximum value of 1024*/
  int speedReverse = 2*(val);            //Only need to multiply.
  
  if (val > 542)                     //Values from 482 to 542
                                          // is "dead zone" to switch 
                                          //off motor. See "else if"
                                          
    {
digitalWrite(phase1, HIGH);         // For 3 phases there are 6 
  delay(speedForward/6);            // transitions per revolution.
digitalWrite(phase3, LOW);          // This switches them on and
  delay(speedForward/6);            // off in the correct order 
digitalWrite(phase2, HIGH);         // in the right-hand half  
  delay(speedForward/6);            // of the travel of the pot,  
digitalWrite(phase1, LOW);          // for clockwise rotation. 
  delay(speedForward/6);            // 
digitalWrite(phase3, HIGH);         // 
  delay(speedForward/6);            // 
digitalWrite(phase2, LOW);          // 
  delay(speedForward/6);            // 
}

 
  else if (val < 482)
  {
digitalWrite(phase3, HIGH);
  delay(speedReverse/6);             // 
digitalWrite(phase1, LOW);           // 
  delay(speedReverse/6);             // 
digitalWrite(phase2, HIGH);          // 
  delay(speedReverse/6);             // The same as above, 
digitalWrite(phase3, LOW);           // on the left-hand side,
  delay(speedReverse/6);             // for anticlockwise rotation.
digitalWrite(phase1, HIGH);          // 
  delay(speedReverse/6);             // 
digitalWrite(phase2, LOW);           // 
  delay(speedReverse/6);             // 
}
      
else
digitalWrite(phase1, LOW);           // Dead zone, everything off...
digitalWrite(phase2, LOW);
digitalWrite(phase3, LOW);
{digitalWrite(13, HIGH);}             //except the LED, which 
                                                  //indicates "off"

}
1 Like

Man, you gotta be really, really good to get even as much as a twitch of an eyebrow!
;D

Looks interesting, but how about some circuit diagrams and photos of the set-up? What is your purpose for doing this?

Hello Mike,
What a small world. You sold me my Freeduino on Ebay in April and changed my life!
No hardware yet but I'm learning programming to eventually run automotive alternators as 3-phase electric motors. These things are good for 1 KW or more and are being scrapped by the thousand every day. Motors in this power range are very useful in any DIY workshop with easy speed and direction control a nice bonus.
The power source may be a headache, though.
Martin

Hi Martin. Small world indeed :slight_smile:

What your doing certainly sounds interesting. I'd like to see what your 'end product' will be. Maybe a huge robot? :smiley:

Nice work :wink:

Thank you! :slight_smile:

I had a similar idea and THIS was the outcome. Currently there is no feedback or position sensors so even a light load can pull it out of phase and the torque drops right off. It does spool up some nice RPMs though. I also etched a circuit board to mount all of the components and eliminate the birds nest but have not taken beyond the bench testing. Though fun to build I shelved the idea for now for other aimless projects that lack a substantial real world use. So much fun to be had making things move and blink...

You've got the T-shirt then!
Yes, that is what I'm setting off to do, but like you I've also been sidetracked for the moment. I fully intend to return, though.
Would you mind sharing some more details about your setup?
Martin.

Martin,
Many of the projects (toys) that I work (play) with are copies, twists, variations or compilations of what others have already shared. It would be sad not to return the favor. I'll put together a component list, schematic and the sketch I used. I'm in for a busy weekend but, I'll try to do it soon...

Here is a schematic. There are three of these, one for each phase and another without the high side part of the circuit for the stator. Most of the components are recycles from other devices or items I had an abundance of. Hence the values but, it works...

A 12V, 14Ah gel cell battery is used to power the motor. The 9V battery is there because I never got around to building a charge pump to drive the high side fets. The gate voltage must be higher than the source to turn on N channel fets. It's on my "to do" list.

On the same list is rotor position sensing with hall switches.

I used optos because the duino was the most expensive component in the whole mess. I didn't want to fry the brain however, several fets did meet an untimely demise. "No honey, I don't smell anything burning! Is the dog near you?"

The sketch was only intended to run short durations. I used the on_time to control speed though I'm sure there are other solutions and cleaner more efficient code to be had.

int i = 0;
int stator = 11;
int ledPin1 = 10;
int ledPin2 = 9;
int ledPin3 = 8;
int ledPin4 = 7;
int ledPin5 = 6;
int ledPin6 = 5;
int between = 60;
int on_time = 1500;
void setup() 
{
  
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
pinMode(ledPin5, OUTPUT);
pinMode(ledPin6, OUTPUT);
pinMode(stator, OUTPUT);


analogWrite(stator, 0);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, LOW);
digitalWrite(ledPin4, LOW);
digitalWrite(ledPin5, LOW);
digitalWrite(ledPin6, LOW);


analogWrite(stator, 64);
delay(50);
  for(i = 0 ; i < 2000; i++)
    {
    digitalWrite(ledPin4, HIGH);
    delayMicroseconds(on_time);
    digitalWrite(ledPin6, LOW);
    delayMicroseconds(between);  //  2
    digitalWrite(ledPin5, HIGH);
    delayMicroseconds(on_time);
    digitalWrite(ledPin1, LOW);
    delayMicroseconds(between);  //  3
    digitalWrite(ledPin2, HIGH);
    delayMicroseconds(on_time);
    digitalWrite(ledPin4, LOW);
    delayMicroseconds(between);  //  4
    digitalWrite(ledPin3, HIGH);
    delayMicroseconds(on_time);
    digitalWrite(ledPin5, LOW);
    delayMicroseconds(between);  //  5
    digitalWrite(ledPin6, HIGH);
    delayMicroseconds(on_time);
    digitalWrite(ledPin2, LOW);
    delayMicroseconds(between);  //  6
    digitalWrite(ledPin1, HIGH);
    delayMicroseconds(on_time);
    digitalWrite(ledPin3, LOW);
    delayMicroseconds(between);
    
    if (i > 1500)
      {
      on_time = 875;
      }
    else if (i > 750)
      {
      on_time = 1000;
      }
    else 
      {
      on_time = 1500;
      }
    
    }
    

    analogWrite(stator, 0);
    digitalWrite(ledPin1, LOW);
    digitalWrite(ledPin2, LOW);
    digitalWrite(ledPin3, LOW);
    digitalWrite(ledPin4, LOW);
    digitalWrite(ledPin5, LOW);
    digitalWrite(ledPin6, LOW);
} 
 
void loop() 
{
}
1 Like

Hope people are still working on this as an alternator can be run as a starter so you would have a starterator. This I would use to start a 6.5 hp Asian horizontal shaft motor which would then generate power to charge batteries. The fuel would be wood gas (actually charcoal).

One might try looking at VFDs (Variable Frequency Drives) Arduino would do well in this aspect.

VFDs usually change the frequency and the pulse width.

I have not even got an Arduino yet but soon hope to be started on this path.

Too many things to do so things happen slowly around here.

Look forward to any and all comments :slight_smile:

This is really cool, I'd never considered using an alternator as a motor. That's a brilliant idea.

Sweet, this was one of the things I wanted to do with my ard-uno when I bought it. Finally I can have those harddrive-motors running. :smiley: