Saturday, July 14, 2012

Three Phase 6 Pulse Inverter

One of the primary things i wanted to do with my Arduino was turn my generators into motors. My simple generators were not simple to turn into motors but this proved to be particularly tricky with my three phase generator. Doing this requires me to create a three phase inverter. The first time I looked at a circuit for this, I thought it would be dead simple. All I need is a few transistors and a few diodes then I can hook them up like this:

and it would work. This turned out to be untrue. That diagram really leaves out a whole lot of details which had me scratching my head for weeks. In particular the transistors connected to the high side just will not work without additional circuitry.

After about four or five failed attempts I got one to work. Here are three almost identical videos of the finished product:







Here is a wiring diagram showing how it is hooked up(click on it for a larger version:



















Components consisted of:

1- Arduino Uno r3

3- NTE 2980 Logic Level N Channel MOSFETs

3- SPP15P10PL H Logic Level P Channel MOSFETs

6- 200 ohm resistors (actually I ran out of these and used 100 ohm and 4000 ohm resistors from the output of the MOSFETs to the Arduino Uno, but 200 ohm are probably a better choice)

1- 100 ohm resistor

3- 100,000 ohm resistors

3- 1,000,000 ohm resistors

3- TC4432 MOSFET driver chip. Be really careful with these, not sure if it was static on my part or poor quality control from the supplier but half of these didn't work. If you want a inverter above 30V this component will need to be replaced with a different MOSFET driver. Another alternative might be a charge pump circuit.

1- 7805A R1424 Voltage regulator. This powers the Arduino from the battery pack. The onboard voltage regulator on the arduino could probably substitute for this.

1- capacitor. Unfortunately this didn't have a legible label on it so I am not quite sure what I used beyond that it was not an electrolytic capacitor so it was probably fairly low capacitance. This was just to lower any ripple which occurred on the DC side of the inverter.

1- battery pack with six rechargeable 1.25 volt batteries. I also ran this circuit using a 20V DC supply but if you do this pin 3 on the TC4432s must be disconnected from ground and the voltage regulator must be replaced with a separate DC source to power the Arduino or the voltage regulator will overheat. Above 30 Volts the circuit will need to be redesigned.

6- NTE in4007 Diodes, These are to prevent any voltage spikes during switching from damaging the MOSFETs.

1- Potentiometer. This isn't really necessary unless you want speed control of the motor. 

The code used to run this circuit is the following:



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 3 MOSFETS should be ON, 4 OFF
int ledStateC1 = LOW;             // Each Phase should have one MOSFET which is on
int ledStateC2 = LOW;

int sensorPin = A0;             // Pin which reads output from the Potentiometer
int sensorValue = 0;            // Initial sensor value

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long previousMillis = 0;        // will store last time a cycle finished was updated
long wavelength = 500;           // wavelength of the output, the read from the potentiometer changes this setting
;

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();      // Records the time at the start of the program
sensorValue = analogRead(sensorPin);         // Takes a read of the output from the potentiometer
if(sensorValue>900){
  PhaseA1 =  5;     // will switch the phases depending on the value read from the potentiometer
  PhaseA2 =  6;     // wswitching the phases will change the direction of rotation of the motor
  PhaseB1 =  7;
  PhaseB2 =  8;
}
else{
  PhaseA1 =  7;      // will switch the phases depending on the value read from the potentiometer
  PhaseA2 =  8;      // wswitching the phases will change the direction of rotation of the motor
  PhaseB1 =  5;
  PhaseB2 =  6;
}

if(sensorValue>900){
  wavelength = 10500-10*sensorValue;  // will change the wavelength depending on the output of the potentiometer
}                                     // changing the wavelength speeds or slows the motor
else{
  wavelength=500+100*sensorValue;    // will change the wavelength depending on the output of the potentiometer,
}                                    // changing the wavelength speeds or slows the motor

if(currentMillis - previousMillis < wavelength/2-wavelength/12 && currentMillis - previousMillis > wavelength/12) {
  ledStateA1=LOW;          // Sets the state for the A phase MOSFETs so the output from the inverter follows the correct waveform
  ledStateA2=LOW;          // Does this by turning on and off the correct MOSFET at the correct time
  digitalWrite(PhaseA1, ledStateA1);
  digitalWrite(PhaseA2, ledStateA2);
}
  else {
  if(currentMillis - previousMillis > wavelength/2+wavelength/12 && currentMillis - previousMillis < wavelength - wavelength/12){
  ledStateA1=HIGH;
  ledStateA2=HIGH;
  digitalWrite(PhaseA1, ledStateA1);
  digitalWrite(PhaseA2, ledStateA2);
  }
else{
  ledStateA1=HIGH;
  ledStateA2=LOW;
  digitalWrite(PhaseA1, ledStateA1);
  digitalWrite(PhaseA2, ledStateA2);
}
  }
if(currentMillis - previousMillis > wavelength/3+wavelength/12 && currentMillis - previousMillis < 5*wavelength/6-wavelength/12  ) {
  ledStateB1=LOW;  // Sets the state for the B phase MOSFETs so the output from the inverter follows the correct waveform
  ledStateB2=LOW;  // Does this by turning on and off the correct MOSFET at the correct time
  digitalWrite(PhaseB1, ledStateB1);
  digitalWrite(PhaseB2, ledStateB2);
}
else{
  if(currentMillis - previousMillis < wavelength/3-wavelength/12 ){
  ledStateB1=HIGH; 
  ledStateB2=HIGH;
  digitalWrite(PhaseB1, ledStateB1);
  digitalWrite(PhaseB2, ledStateB2);
  }
 else{
  if(currentMillis - previousMillis > 5*wavelength/6+wavelength/12){
  ledStateB1=HIGH; 
  ledStateB2=HIGH;
  digitalWrite(PhaseB1, ledStateB1);
  digitalWrite(PhaseB2, ledStateB2);
  }

else{
  ledStateB1=HIGH;
  ledStateB2=LOW;
  digitalWrite(PhaseB1, ledStateB1);
  digitalWrite(PhaseB2, ledStateB2);
}
}
}

if(currentMillis - previousMillis > wavelength/6 + wavelength/12 && currentMillis - previousMillis < 2*wavelength/3-wavelength/12  ) {
  ledStateC1=HIGH;  // Sets the state for the C phase MOSFETs so the output from the inverter follows the correct waveform
  ledStateC2=HIGH;  // Does this by turning on and off the correct MOSFET at the correct time
  digitalWrite(PhaseC1, ledStateC1);
  digitalWrite(PhaseC2, ledStateC2);
}
else{
  if( currentMillis - previousMillis > 2*wavelength/3+wavelength/12) {
  ledStateC1=LOW; 
  ledStateC2=LOW;
  digitalWrite(PhaseC1, ledStateC1);
  digitalWrite(PhaseC2, ledStateC2);
  }
  else{
  if( currentMillis - previousMillis < wavelength/6 - wavelength/12) {
  ledStateC1=LOW; 
  ledStateC2=LOW;
  digitalWrite(PhaseC1, ledStateC1);
  digitalWrite(PhaseC2, ledStateC2);
}
else{
  ledStateC1=HIGH;
  ledStateC2=LOW;
  digitalWrite(PhaseC1, ledStateC1);
  digitalWrite(PhaseC2, ledStateC2);
}
  }
}
if(currentMillis - previousMillis > wavelength){
  previousMillis=currentMillis;  // resets the stored in CurrentMillis before restarting the program
}

}




3 comments:

Anonymous said...

great work

MURARI SHARAN said...

Bro Is this a complete code for 3 phase inverter 180 degree mode? Kindly reply

Jose Cano said...

Hello from Colombia, I did a Axial flow generator with permanent neodymium magnets, 500 watts, (48 vol x 10 amp) aprox. I want to convert it to a motor, yuo can help me?