July 30, 2025

Arduino 3-phase Inverter 12V to 380V

This is a simple 3-phase Inverter using Arduino to convert 12V DC into 380V AC.

It has 3 push button: 

1-Forward 

2-Reverse

3-Stop (turn OFF) 

Forward and Reverse buttons used when the load is motor by swapping two phases. 

Output waveform is square wave and maximum power depends on the size of the transformers and MOSFETs.

 

Arduino 3-phase Inverter 12V to 380V

Parts list:

Arduino (UNO or MEGA) 

IC 7805  

LCD Display 16x2 with I2C 

Transformer center taped 9V-0-9V / 220V (3pcs)

MOSFET IRFZ44n (6pcs)

Optocoupler PC817 (6pcs)

Resistor 91K 

Resistor 10K (7pcs)

Resistor 300 ohm (6pcs)

Resistor 1K (6pcs) 

Capacitor 1000uF 16v (2pcs) 

Capacitor 100nF (2pcs) 

Heatsink for MOSFETs (6pcs)

12V Battery 

Battery connecting cable 

 

Circuit:

If you want to use Arduino UNO instead of Arduino MEGA, you have to connect the pin A4 of the Arduino UNO to SDA of the LCD and pin A5 of the Arduino UNO to SCL of the LCD, Rest of the wiring and even the code remains the same!

Arduino 3-phase Inverter 12V to 380V

Video:

 


Code:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <TimerOne.h>

// LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);  // Adjust I2C address if needed

// Phase pins
const int phaseA = 2;
const int phaseB = 3;
const int phaseC = 4;
const int phaseA_inv = 5;
const int phaseB_inv = 6;
const int phaseC_inv = 7;

// Buttons (Active HIGH)
const int btnForward = 8;
const int btnReverse = 9;
const int btnStop = 10;

// Battery sensing
const int battPin = A0;
const float battDividerRatio = 10;
const float lowCutOff = 10.5;
const float restoreVoltage = 11.0;

// State variables
volatile bool inverterOn = false;
volatile bool reverseMode = false;

// Debounce tracking
bool lastForwardState = LOW;
bool lastReverseState = LOW;
bool lastStopState = LOW;
unsigned long lastDebounceForward = 0;
unsigned long lastDebounceReverse = 0;
unsigned long lastDebounceStop = 0;
const unsigned long debounceDelay = 200;

// Phase control
volatile int phaseStep = 0;

// Correct symmetrical 6-step sequence
bool seqForward[6][3] = {
  {1,0,0},  // Step 1
  {1,1,0},  // Step 2
  {0,1,0},  // Step 3
  {0,1,1},  // Step 4
  {0,0,1},  // Step 5
  {1,0,1}   // Step 6
};

void setup() {
  lcd.init();
  lcd.backlight();

  pinMode(phaseA, OUTPUT);
  pinMode(phaseB, OUTPUT);
  pinMode(phaseC, OUTPUT);
  pinMode(phaseA_inv, OUTPUT);
  pinMode(phaseB_inv, OUTPUT);
  pinMode(phaseC_inv, OUTPUT);

  pinMode(btnForward, INPUT);  // Active HIGH (use pull-down resistors)
  pinMode(btnReverse, INPUT);
  pinMode(btnStop, INPUT);

  lcd.setCursor(0, 0);
  lcd.print("System Init...");
  delay(1000);
  lcd.clear();

  // Timer1 for 50Hz
  Timer1.initialize(3333); // 300Hz steps = 50Hz fundamental
  Timer1.attachInterrupt(stepPhases);
}

void loop() {
  float battVoltage = readBatteryVoltage();

  // Display battery voltage
  lcd.setCursor(0, 0);
  lcd.print("Battery:");
  lcd.print(battVoltage, 2);
  lcd.print(" V   ");

  // Low battery cutoff
  if (battVoltage < lowCutOff) {
    inverterOn = false;
  }

  // --- Forward Button ---
  bool currentForward = digitalRead(btnForward);
  if (currentForward == HIGH && lastForwardState == LOW && (millis() - lastDebounceForward > debounceDelay)) {
    inverterOn = true;
    reverseMode = false;
    lastDebounceForward = millis();
  }
  lastForwardState = currentForward;

  // --- Reverse Button ---
  bool currentReverse = digitalRead(btnReverse);
  if (currentReverse == HIGH && lastReverseState == LOW && (millis() - lastDebounceReverse > debounceDelay)) {
    inverterOn = true;
    reverseMode = true;
    lastDebounceReverse = millis();
  }
  lastReverseState = currentReverse;

  // --- Stop Button ---
  bool currentStop = digitalRead(btnStop);
  if (currentStop == HIGH && lastStopState == LOW && (millis() - lastDebounceStop > debounceDelay)) {
    inverterOn = false;
    lastDebounceStop = millis();
  }
  lastStopState = currentStop;

  // Status display
  lcd.setCursor(0, 1);
  if (battVoltage < lowCutOff) {
    lcd.print("Battery is LOW ");
  } else {
    if (!inverterOn) {
      lcd.print("Motor Stopped  ");
    } else {
      if (reverseMode) lcd.print("Reverse         ");
      else lcd.print("Forward         ");
    }
  }
}

// Averaged battery voltage reading
float readBatteryVoltage() {
  long sum = 0;
  for (int i = 0; i < 10; i++) {
    sum += analogRead(battPin);
    delay(2); // small delay between readings
  }
  float adcValue = sum / 10.0;
  return (adcValue * 5.0 / 1023.0) * battDividerRatio;
}

// Timer1 ISR for phases
void stepPhases() {
  if (!inverterOn) {
    // All outputs off
    digitalWrite(phaseA, LOW);
    digitalWrite(phaseB, LOW);
    digitalWrite(phaseC, LOW);
    digitalWrite(phaseA_inv, LOW);
    digitalWrite(phaseB_inv, LOW);
    digitalWrite(phaseC_inv, LOW);
    return;
  }

  bool A = seqForward[phaseStep][0];
  bool B = seqForward[phaseStep][1];
  bool C = seqForward[phaseStep][2];

  digitalWrite(phaseA, A);
  digitalWrite(phaseB, B);
  digitalWrite(phaseC, C);
  digitalWrite(phaseA_inv, !A);
  digitalWrite(phaseB_inv, !B);
  digitalWrite(phaseC_inv, !C);

  if (reverseMode) {
    phaseStep--;
    if (phaseStep < 0) phaseStep = 5;
  } else {
    phaseStep++;
    if (phaseStep > 5) phaseStep = 0;
  }
}