Witam. Zbudowałem regulator mppt według tego projektu tylko że na atmedze328 https://www.youtube.com/watch?v=qVfIR20kqQ0. W kodzie było kilka błędów, poprawiłem je ale coś jest jeszcze nie tak, bo po wgraniu na wyświetlaczu nic się nie wyświetla i cały czas świeci się czerwona dioda.
#include <LiquidCrystal.h>
#include <EEPROM.h>
LiquidCrystal lcd(7,8,0,1,2,3);
#define SOL_VOLTS_CHAN A0
#define SOL_AMPS_CHAN A3
#define BAT_VOLTS_CHAN A2
#define FAN_PIN A1
#define AVG_NUM 10
#define SOL_AMPS_SCALE 37
#define SOL_VOLTS_SCALE 28
#define BAT_VOLTS_SCALE 28
#define PWM_PIN 9
#define PWM_FULL 1023
#define PWM_MAX 100
#define PWM_MIN 60
#define PWM_START 90
#define PWM_INC 1
#define TRUE 1
#define FALSE 0
#define ON TRUE
#define OFF FALSE
#define ONE_SECOND 50000
#define LOW_SOL_WATTS 5.00
#define MIN_SOL_WATTS 1.00
#define MIN_BAT_VOLTS 11.00
#define MAX_BAT_VOLTS 14.10
#define HIGH_BAT_VOLTS 13.60
#define OFF_NUM 9
#define yellowLed 10
#define greenLed 11
#define redLed 12
byte solar[8] =
{
0b11111,
0b10101,
0b11111,
0b10101,
0b11111,
0b10101,
0b11111,
0b00000
};
byte battery[8]=
{
0b01110,
0b11011,
0b10001,
0b10001,
0b11111,
0b11111,
0b11111,
0b11111,
};
float pwm = 0;
float sol_amps;
float sol_volts;
float bat_volts;
float sol_watts;
int delta = PWM_INC;
float old_sol_watts = 0;
float watts, wattHours;
int disp_page=1;
unsigned long prev_millis, pwm_disp_millis;
double msec, last_msec, elasped_msec, elasped_time, ampSecs, wattSecs;
enum charger_mode {
off, on, bulk, bat_float }
charger_state;
void setup()
{
TCCR1B = TCCR1B & B11111000 | B00000001;
wattHours = 1000;
analogWrite(PWM_PIN,0);
pwm = PWM_START;
charger_state = on;
pinMode(yellowLed, OUTPUT);
pinMode(greenLed, OUTPUT);
pinMode(redLed, OUTPUT);
pinMode(FAN_PIN,OUTPUT);
digitalWrite(yellowLed,LOW);
digitalWrite(greenLed,LOW);
digitalWrite(redLed,LOW);
digitalWrite(FAN_PIN,HIGH);
lcd.begin(16, 2);
lcd.createChar(1,solar);
lcd.createChar(2,battery);
}
int read_adc(int channel){
int sum = 0;
int temp;
int i;
for (i=0; i<AVG_NUM; i++) {
temp = analogRead(channel);
sum += temp;
delayMicroseconds(50);
}
return(sum / AVG_NUM);
}
void set_pwm_duty(void) {
if (pwm > PWM_MAX) {
pwm = PWM_MAX;
}
else if (pwm < PWM_MIN) {
pwm = PWM_MIN;
}
if (pwm < PWM_MAX) {
analogWrite(PWM_PIN,(PWM_FULL * (long)pwm / 100));
//period
}
else if (pwm == PWM_MAX) {
analogWrite(PWM_PIN,(PWM_FULL - 1));
//1000uS period
}
}
void lcd_display1(void) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.write(1);
//lcd.print(" ");
lcd.print(sol_volts,1);
lcd.print("V ");
if ((sol_amps*sol_volts) < 10.0 && (sol_amps*sol_volts) > 0.0) {
lcd.print("0");
lcd.print(sol_amps*sol_volts,0);
}
else if ((sol_amps*sol_volts) >= 10.0) {
lcd.print(sol_amps*sol_volts,0);
}
else {
lcd.print("00");
}
lcd.print("W ");
if ((sol_amps) < 10.0 && sol_amps >0) {
lcd.print("0");
lcd.print(sol_amps,1);
}
else if (sol_amps >= 10){
lcd.print(sol_amps,1);
}
else {
lcd.print("00.0");
}
lcd.print("A");
//lcd.print(sol_amps,1);
//lcd.print("A");
lcd.setCursor(0, 1);
lcd.write(2);
//lcd.print(" ");
lcd.print(bat_volts,1);
lcd.print("V ");
if ((sol_amps*bat_volts) < 10.0 && (sol_amps*bat_volts) > 0.0) {
lcd.print("0");
lcd.print(sol_amps*bat_volts,0);
}
else if ((sol_amps*bat_volts) >= 10.0) {
lcd.print(sol_amps*bat_volts,0);
}
else {
lcd.print("00");
}
lcd.print("W ");
if (disp_page==1){
lcd.print(wattHours,0);
lcd.setCursor(15,1);
lcd.print("h");
}
if(disp_page==2) {
lcd.print(pwm,0);
lcd.setCursor(15,1);
lcd.print("%");
}
}
void read_data(void) {
//sol_volts = read_adc(SOL_VOLTS_CHAN)*0.0282;
//bat_volts = read_adc(BAT_VOLTS_CHAN)*0.0276;
sol_volts = read_adc(SOL_VOLTS_CHAN)*0.02705;
bat_volts = read_adc(BAT_VOLTS_CHAN)*0.02613;
sol_amps = (read_adc(SOL_AMPS_CHAN));
sol_amps = (sol_amps/1023.0)*5000;
sol_amps = 0.9*((sol_amps-2500)/66);
sol_amps = sol_amps-1.2;
sol_watts = sol_volts*sol_amps;
}
void power(void)
{
msec = millis();
elasped_msec = msec - last_msec;
elasped_time = elasped_msec / 1000.0;
watts = bat_volts*sol_amps;
ampSecs = (sol_amps*elasped_time);
wattSecs = ampSecs * sol_volts;
wattHours = wattHours + wattSecs/3600;
last_msec = msec;
}
void ledIndication(void) {
if (charger_state == off){
digitalWrite(greenLed,LOW);
digitalWrite(yellowLed,LOW);
digitalWrite(redLed,HIGH);
}
else if ((charger_state == bulk) || (charger_state == on)) {
digitalWrite(greenLed,LOW);
digitalWrite(yellowLed,HIGH);
digitalWrite(redLed,LOW);
}
else if (charger_state == bat_float) {
digitalWrite(greenLed,HIGH);
digitalWrite(yellowLed,LOW);
digitalWrite(redLed,LOW);
}
}
void run_charger(void) {
static int off_count = OFF_NUM;
switch (charger_state) {
case on:
if (sol_watts < MIN_SOL_WATTS) {
charger_state = off;
off_count = OFF_NUM;
analogWrite(PWM_PIN,0);
}
else if (bat_volts > MAX_BAT_VOLTS) {
charger_state = bat_float;
}
else if (sol_watts < LOW_SOL_WATTS) {
pwm = PWM_MAX;
set_pwm_duty();
//as possible
} //and stay in the charger on state
else {
pwm = ((bat_volts * 10) / (sol_volts / 10)) + 5;
//out what the pwm
charger_state = bulk;
}
break;
case bulk:
if (sol_watts < MIN_SOL_WATTS) {
charger_state = off;
off_count = OFF_NUM;
}
else if (bat_volts > MAX_BAT_VOLTS) {
charger_state = bat_float;
}
else if (sol_watts < LOW_SOL_WATTS) {
charger_state = on;
}
else {
if (old_sol_watts >= sol_watts) {
delta = -delta;
}
pwm += delta;
old_sol_watts = sol_watts;
set_pwm_duty();
}
break;
case bat_float:
if (sol_watts < MIN_SOL_WATTS) {
charger_state = off;
off_count = OFF_NUM;
set_pwm_duty();
analogWrite(PWM_PIN,0);
}
else if (bat_volts > MAX_BAT_VOLTS) {
pwm -= 1;
set_pwm_duty();
}
else if (bat_volts < MAX_BAT_VOLTS) {
pwm += 1;
set_pwm_duty();
if (pwm >= 100) {
charger_state = bulk;
}
}
break;
case off:
if (off_count > 0) {
off_count--;
}
else if ((bat_volts > HIGH_BAT_VOLTS) && (bat_volts < MAX_BAT_VOLTS) && (sol_volts > bat_volts)) {
charger_state = bat_float; //if battery voltage is still high and solar volts are high
set_pwm_duty();
}
else if ((bat_volts > MIN_BAT_VOLTS) && (bat_volts < MAX_BAT_VOLTS) && (sol_volts > bat_volts)) {
pwm = PWM_START;
set_pwm_duty();
charger_state = on;
}
break;
default:
analogWrite(PWM_PIN,0);
break;
}
}
void loop()
{
read_data();
power();
run_charger();
// delay(50);
// read_data();
if ((millis() > (prev_millis+ 1500))) {
prev_millis = millis();
ledIndication();
lcd_display1();
if (sol_amps > 2) {
digitalWrite(FAN_PIN,HIGH);
}
else{
digitalWrite(FAN_PIN,LOW);
}
if (disp_page==1) disp_page=2;
else disp_page=1;
}
}