Bidirectional arduino code:
// ---------------- PIN DEFINITIONS ----------------
#define S1S2 9 // Primary side
#define S3S4 10
#define SASB 5 // Secondary side
#define SCSD 6
#define CURRENT_SENSOR A0
// ---------------- VARIABLES ----------------
float current = 0;
float voltage = 0;
float sensorValue = 0;
#define THRESHOLD 2.5 // ACS712 zero point (approx)
// ---------------- SETUP ----------------
void setup() {
pinMode(S1S2, OUTPUT);
pinMode(S3S4, OUTPUT);
pinMode(SASB, OUTPUT);
pinMode(SCSD, OUTPUT);
[Link](9600);
// -------- Timer1 for 100 kHz PWM (Pin 9 & 10) --------
TCCR1A = 0;
TCCR1B = 0;
TCCR1A |= (1 << WGM11);
TCCR1B |= (1 << WGM12) | (1 << WGM13); // Fast PWM mode
TCCR1A |= (1 << COM1A1) | (1 << COM1B1); // Enable PWM on 9 & 10
TCCR1B |= (1 << CS10); // No prescaler
ICR1 = 160; // 16MHz / (1 * 100kHz) = 160
OCR1A = 80; // 50% duty (Pin 9)
OCR1B = 80; // 50% duty (Pin 10)
}
// ---------------- LOOP ----------------
void loop() {
// ---- Read ACS712 ----
sensorValue = analogRead(CURRENT_SENSOR);
current = (sensorValue * 5.0 / 1023.0);
[Link](current);
// -------- MODE SELECTION --------
if (current > THRESHOLD + 0.05) {
// -------- H2V MODE --------
// Enable Primary PWM (Timer1)
TCCR1A |= (1 << COM1A1) | (1 << COM1B1);
// Disable Secondary
digitalWrite(SASB, LOW);
digitalWrite(SCSD, LOW);
}
else if (current < THRESHOLD - 0.05) {
// -------- V2H MODE --------
// Disable Primary PWM
TCCR1A &= ~(1 << COM1A1);
TCCR1A &= ~(1 << COM1B1);
digitalWrite(S1S2, LOW);
digitalWrite(S3S4, LOW);
// Generate switching on secondary side
digitalWrite(SASB, HIGH);
digitalWrite(SCSD, LOW);
delayMicroseconds(5);
digitalWrite(SASB, LOW);
digitalWrite(SCSD, HIGH);
delayMicroseconds(5);
}
else {
// -------- IDLE --------
digitalWrite(S1S2, LOW);
digitalWrite(S3S4, LOW);
digitalWrite(SASB, LOW);
digitalWrite(SCSD, LOW);
}
}
100KHz PWM switching arduino code with 180deg phase shift code
// 100 kHz PWM with 180° phase shift
// Pin 9 -> OCR1A
// Pin 10 -> OCR1B
void setup() {
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
// Stop Timer1
TCCR1A = 0;
TCCR1B = 0;
// Fast PWM mode using ICR1 as TOP
TCCR1A |= (1 << WGM11);
TCCR1B |= (1 << WGM12) | (1 << WGM13);
// Non-inverting mode on both channels
TCCR1A |= (1 << COM1A1); // Pin 9
TCCR1A |= (1 << COM1B1); // Pin 10
// No prescaler (N = 1)
TCCR1B |= (1 << CS10);
// Set TOP for 100 kHz
// f = 16MHz / (1 * (1 + TOP))
// TOP = 159 → ~100 kHz
ICR1 = 159;
// 50% duty cycle
OCR1A = 80;
// 180° phase shift → half of TOP
OCR1B = 0;
// IMPORTANT: To create phase shift, we invert logic:
TCCR1A |= (1 << COM1B0); // Inverting mode for B channel
}
void loop() {
// Nothing needed, hardware handles PWM
}
Un phase shift code
void setup() {
pinMode(9, OUTPUT); // OC1A
pinMode(10, OUTPUT); // OC1B
// Stop Timer1
TCCR1A = 0;
TCCR1B = 0;
// Fast PWM mode using ICR1 as TOP
TCCR1A |= (1 << WGM11);
TCCR1B |= (1 << WGM13) | (1 << WGM12);
// Non-inverting mode for both outputs
TCCR1A |= (1 << COM1A1) | (1 << COM1B1);
// No prescaler (full 16 MHz)
TCCR1B |= (1 << CS10);
// Set TOP for 100 kHz
// f = 16MHz / (1 * (1 + TOP))
// TOP = 159 → ~100 kHz
ICR1 = 159;
// Duty cycle (adjust here)
OCR1A = 80; // 50% duty
OCR1B = 80; // same for second set
}
void loop() {
// nothing needed, hardware handles PWM
}