July 27, 2025

Arduino inverter 12V to 220V with LCD Display

This is a simple inverter to convert 12V DC to 220V AC with LCD Display to show the battery voltage. 

It has low battery cut off voltage at 10.5V to protect the battery from over discharge. 

The output is square waveform and the maximum output power depends on the power of your transformer and also the MOSFETs and heatsink's size. 

 

Arduino inverter 12V to 220V

Arduino inverter 12V to 220V with LCD Display

Parts list:

Arduino (UNO or MEGA) 

IC 7805  

LCD Display 16x2 with I2C 

Transformer center taped 9V-0-9V / 220V 

MOSFET IRFZ44n (2pcs)

Optocoupler PC817 (2pcs)

Resistor 91K 

Resistor 10K (3pcs)

Resistor 300 ohm (2pcs)

Resistor 1K (3pcs) 

Capacitor 1000uF 16v (2pcs) 

Capacitor 100nF (2pcs) 

Heatsink for MOSFETs (2pcs)

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 inverter 12V to 220V with LCD Display

Video: 

 


Code: 

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <avr/io.h>
#include <avr/interrupt.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);  // Try 0x3F if 0x27 doesn’t work

const int square1 = 8;
const int square2 = 9;
const int buttonPin = 2;

volatile bool waveState = false;       // Toggles HIGH/LOW
volatile bool outputEnabled = false;   // ON/OFF by user
bool voltageOK = true;                 // Low voltage check

const unsigned int deadTimeMicros = 200;
const float voltageThreshold = 10.5;   // Cutoff threshold

unsigned long lastLCDUpdate = 0;
const unsigned long lcdInterval = 200;

unsigned long lastButtonTime = 0;
const unsigned long debounceDelay = 200;

void setup() {
  pinMode(square1, OUTPUT);
  pinMode(square2, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);

  digitalWrite(square1, LOW);
  digitalWrite(square2, LOW);

  lcd.init();
  lcd.backlight();
  lcd.clear();

  attachInterrupt(digitalPinToInterrupt(buttonPin), toggleOutput, FALLING);

  // Timer1 for 50Hz waveform (10ms toggle = 20ms full cycle)
  noInterrupts();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A = 2499;  // 10ms at 16MHz / 64
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << CS11) | (1 << CS10);
  TIMSK1 |= (1 << OCIE1A);
  interrupts();
}

ISR(TIMER1_COMPA_vect) {
  if (outputEnabled && voltageOK) {
    waveState = !waveState;
    if (waveState) {
      digitalWrite(square2, LOW);
      delayMicroseconds(deadTimeMicros);
      digitalWrite(square1, HIGH);
    } else {
      digitalWrite(square1, LOW);
      delayMicroseconds(deadTimeMicros);
      digitalWrite(square2, HIGH);
    }
  } else {
    digitalWrite(square1, LOW);
    digitalWrite(square2, LOW);
  }
}

void loop() {
  // Update LCD every 200ms
  if (millis() - lastLCDUpdate >= lcdInterval) {
    lastLCDUpdate = millis();

    int adc0 = analogRead(A0); delay(2);
   
    float v0 = adc0 * (5.0 / 1023.0)*10;
   

    // Voltage check
    voltageOK = (v0 >= voltageThreshold);

    // Display voltages
    lcd.setCursor(0, 0);
    lcd.print("BATTERY: ");
    lcd.print(v0, 2);
    lcd.print(" V     ");


    // Show status
    lcd.setCursor(1, 1);
    if (!voltageOK) {
      lcd.print("BATTERY IS LOW");
    } else {
      lcd.print(outputEnabled ? "INVERTER IS ON " : "INVERTER IS OFF");
    }
  }
}

void toggleOutput() {
  unsigned long now = millis();
  if (now - lastButtonTime > debounceDelay) {
    outputEnabled = !outputEnabled;
    lastButtonTime = now;
  }
}