Below are my codes for arduino mega 2560 that I use for solar panel mppt boost converter. I want to make the 17V input 34V but I cannot control my mppt algorithm. The voltage rises too much and the duty does not change continuously. I preferred the 11th pin for the pwm pin. I'm trying to use Timer1 mode14 fast mode. Can you show my shortcomings or mistakes? My voltage divider values for the input are 10k and 3.9k smd 1206 resistors, I used 26k and 2k resistors for the output voltage divider. I use ACS712 20a and 5a model.
// #include <LiquidCrystal_I2C.h> // I2C LCD library
// #include <Wire.h> // I2C library
// LiquidCrystal_I2C lcd(0x27, 16, 2);
float input_voltage = 0;
float output_voltage = 0;
float input_current = 0;
float output_current = 0;
float P = 0;
float dV = 0;
int delta = 1; // PWM değişim miktarı
int Dmax = 900; // 90% Duty
int Dmin = 0; // 0% Duty
int input_readings = 0;
int output_readings = 0;
int input_current_readings = 0;
int output_current_readings = 0;
int input_total_analogValue = 0;
int output_total_analogValue = 0;
int input_total_current_analogValue = 0;
int output_total_current_analogValue = 0;
int analog_step = 0;
void updateMPPT();
void updateLCD();
void setup() {
// Wire.begin();
// lcd.init();
// lcd.backlight();
Serial.begin(9600); // Main serial port
pinMode(11, OUTPUT);
// Timer1 i Mode 14 (Fast PWM)
TCCR1A = (1 << WGM11) | (0 << WGM10) | (1 << COM1A1) | (0 << COM1A0); // non-inverting mode
TCCR1B = (1 << WGM12) | (1 << WGM13) | (0 << CS12) | (0 << CS11) | (1 << CS10); // prescaler 1
ICR1 = 1000; // PWM period (1000 = %100 duty) - 16k Hz
OCR1A = 200; // 20% duty cycle begin
}
void loop() {
input_total_analogValue += analogRead(A12);
output_total_analogValue += analogRead(A6);
input_total_current_analogValue += analogRead(A8);
output_total_current_analogValue += analogRead(A15);
analog_step++;
if(analog_step == 16) {
input_readings = input_total_analogValue >> 4; // Divide by 16
output_readings = output_total_analogValue >> 4;
input_current_readings = input_total_current_analogValue >> 4;
output_current_readings = output_total_current_analogValue >> 4;
input_voltage = input_readings * (5/1023) * (13900/3900);
output_voltage = output_readings * (5/1023) * (26000/2000);
input_current = ((( (float) input_current_readings / 1024.0) * 5000 - 2500) / 100); // ACS712 20A
output_current = ((( (float) output_current_readings / 1024.0) * 5000 - 2500) / 185); // ACS712 5A
input_total_analogValue = 0;
output_total_analogValue = 0;
input_total_current_analogValue = 0;
output_total_current_analogValue = 0;
analog_step = 0;
updateMPPT();
updateLCD();
}
}
void updateMPPT() {
static float voltage_old = 0;
static float P_old = 0;
static int OCR1A_old = 500;
static int delta = 1; // PWM değişim miktarı
static int Dmax = 900; // %90 Duty
static int Dmin = 0; // %0 Duty
static float P = input_voltage * input_current;
static float dV = input_voltage - voltage_old;
static float dP = P - P_old;
if(dP != 0)
{
if((dP < 0) && (dV < -0.05)) // 50mV
{
OCR1A_old = OCR1A - delta;
}
else if ((dP < 0) && (dV > 0.05))
{
OCR1A_old = OCR1A + delta;
}
else if ((dP > 0) && (dV < -0.05))
{
OCR1A_old = OCR1A + delta;
}
else if ((dP > 0) && (dV > 0.05))
{
OCR1A_old = OCR1A - delta;
}
else
{
//-0.05 < dV < 0.05
}
}
else
{
// Since it is at max power, there is no need to change it.
}
void updateLCD() {
static float input_power = 0;
static float output_power = 0;
static int duty_cycle = 0;
static unsigned long lastUpdate = 0;
unsigned long currentMillis = millis();
if (currentMillis - lastUpdate > 1000) {
lastUpdate = currentMillis;
input_power = input_voltage * input_current;
output_power = output_voltage * output_current;
duty_cycle = (OCR1A / 10);
Serial.print("V_IN: ");
Serial.print(input_voltage);
Serial.println(" V");
Serial.print("I_IN: ");
Serial.print(input_current);
Serial.println(" A");
Serial.print("P_IN: ");
Serial.print(input_power);
Serial.println(" W");
Serial.println();
Serial.print("V_OUT: ");
Serial.print(output_voltage);
Serial.println(" V");
Serial.print("I_OUT: ");
Serial.print(output_current);
Serial.println(" A");
Serial.print("P_OUT: ");
Serial.print(output_power);
Serial.println(" W");
Serial.println();
Serial.print("Duty Cycle: ");
Serial.print(duty_cycle);
Serial.println(" %");
// LCD display
// lcd.clear();
// lcd.setCursor(0, 0);
// lcd.print("V_IN: ");
// lcd.print(input_voltage, 2);
// lcd.print("V");
// lcd.setCursor(0, 1);
// lcd.print("I_IN: ");
// lcd.print(input_current, 2);
// lcd.print("A");
// lcd.setCursor(9, 0);
// lcd.print("V_OUT: ");
// lcd.print(output_voltage, 2);
// lcd.print("V");
// lcd.setCursor(9, 1);
// lcd.print("I_OUT: ");
// lcd.print(output_current, 2);
// lcd.print("A");
}
}