Go Down

Topic: 3-Phase motor control (Read 8 times) previous topic - next topic

Martin Grove

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

Code: [Select]

/*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"

}        
         
         


Martin Grove

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

Mike Mc

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

Martin Grove

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


Mike Mc

Hi Martin. Small world indeed :)

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

rausma


Martin Grove


UncleBone

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...
Why do it right the first time, when building and rebuilding is  so much fun?

Martin Grove

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.

UncleBone

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...
Why do it right the first time, when building and rebuilding is  so much fun?

UncleBone

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.

Code: [Select]
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()
{
}

Why do it right the first time, when building and rebuilding is  so much fun?

David Canoe

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 :)

UnaClocker

This is really cool, I'd never considered using an alternator as a motor. That's a brilliant idea.
Brian from Tacoma, WA
Arduino evangelist - since Dec, 2010.

karlboll

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. :D
First we ignore them, then we make fun of them, then we fight them and then they win so let's cut the crap and just expose them for the corrupt liars they are.

Go Up