DIY 3kW Arduino MPPT Solar Charge Controller ESP32

Diskuze na téma solárních, větrných a ostatních regulátorů, datové komunikace mezi regulátory a PC, instalace software, zapojení regulátorů, chování a zkušenosti s různými typy regulátorů.
Uživatelský avatar
rottenkiwi
Příspěvky: 5369
Registrován: pát úno 13, 2015 2:24 pm
Chci prodávat energii a využít dotace: ANO
Souhlasím s podmínkami fóra: NE
Bydliště: SO, SK

Re: DIY 3kW Arduino MPPT Solar Charge Controller ESP32

Příspěvek od rottenkiwi »

Ked si chcete niekto vyskusat urobit dvojfazovy MPPT s ESP32
tak odporucam precitat:

https://www.instructables.com/DIY-1kW-M ... ontroller/
schemu najdete tu:

https://www.youtube.com/watch?v=R-_ATHYgcBQ

parametre BUCK tu:

https://www.youtube.com/watch?v=bJVInQO7r_A

Tu je moj kod na par riadkov:

Kód: Vybrat vše

#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
//#include <AsyncMqttClient.h>
#include "SPIFFS.h"
#include <Arduino_JSON.h>
#include <EEPROM.h>
#include <driver/ledc.h>
#include <driver/gpio.h>
#include <driver/mcpwm.h>
#include <esp_intr_alloc.h>
#include <soc/soc.h>
#include <soc/soc_caps.h>
#include <soc/mcpwm_reg.h>
#include <soc/mcpwm_struct.h>
#include <esp_err.h>
#include <hal/mcpwm_types.h>
#include <Adafruit_ADS1X15.h>
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <DS1307ESP.h>

const int oneWireBus = 27;  
OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);
int numberOfDevices;
DeviceAddress tempDeviceAddress; 

Adafruit_ADS1115 ads0, ads1;
uint8_t address = 0x27;uint8_t cols = 20;uint8_t rows = 4;
LiquidCrystal_I2C lcd( address, cols, rows );
DS1307ESP rtc;

#define EEPROM_MAX 1024
#define FAN_PIN_0 33
#define FAN_PIN_1 35

// setting PWM properties
const int freq = 5000;const int ledChannel_0 = 0;const int ledChannel_1 = 1;const int resolution = 8;

#define SD_PIN  2  // ESP32 for SD at IR2104 IR2184 .. etc. first phase
#define SD_PIN2  4  // ESP32 for second phase 

#define MIN_AMPS 0.49
#define REBULK_VOLTS 12.95
#define MIN_PANEL_VOLTS 13.00
#define CRITICAL_VOLTS 15.15

#define MAX_VOLTS_PB 14.95
#define MAX_VOLTS_SLOW_PB 13.60
#define MAX_VOLTS_FLOAT_PB 13.50
#define REBULK_VOLTS_PB 13.45

#define MAX_V_OUT 14.90
#define MAX_V_IN 119.00

#define MAX_VOLTS_LFP 14.20
#define MAX_VOLTS_SLOW_LFP 13.60
#define MAX_VOLTS_FLOAT_LFP 13.50
#define REBULK_VOLTS_LFP 13.40

#define MAX_V_OUT_12V 14.95
#define MIN_V_OUT_12V 11.10
#define MIN_PANEL_VOLTS_12V 19.00

#define MAX_V_OUT_24V 29.80
#define MIN_V_OUT_24V 22.20
#define MIN_PANEL_VOLTS_24V 32.00

#define MAX_V_OUT_48V 59.40
#define MIN_V_OUT_48V 44.40
#define MIN_PANEL_VOLTS_48V 51.20

#define A_OFFSET 1825.0

#define PWM_1 2300
#define PWM_10 23000
#define PWM_2 2000
#define PWM_20 20000
#define PWM_3 2400
#define PWM_30 24000
#define PWM_4 2500
#define PWM_40 25000

#define GPIO_PWM0A_OUT 19
#define GPIO_PWM0B_OUT 23
#define GPIO_PWM1A_OUT 17
#define GPIO_PWM1B_OUT 18
#define GPIO_PWM2A_OUT 16
#define GPIO_PWM2B_OUT 5

const char* ssid = "guest";
const char* password = "password";
AsyncWebServer server(80);
AsyncWebSocket ws("/ws");
AsyncEventSource events("/events");

JSONVar readings;

const int ledPin1 = 2;
const int ledPin2 = 4;
const int ledPin3 = 12;
const int ledPin4 = 13;

String message = "";
String buffer_1 = "                  ";
String sliderValue1 = "0";
String sliderValue2 = "0";
String sliderValue3 = "0";
String sliderValue4 = "0";

int dutyCycle1;
int dutyCycle2;
int dutyCycle3;
int dutyCycle4;
int deltaPWM = 0;

const int ledChannel1 = 0;
const int ledChannel2 = 1;
const int ledChannel3 = 2;
const int ledChannel4 = 3;

unsigned long previous = 0;   // Stores last time temperature was published
const long interval = 992;        // Interval at which to publish sensor readings
const long setup_interval = 333;        // Interval at which to publish sensor readings
long int num_of_intervals, duty_high, duty_low, max_volts_high; 
unsigned long previousTime = 0; 
unsigned long now, currentTime, loop_time, loop_interval, now_m;

long wh_all;
int wh_day;
int Addr_0 = 0, Addr_1 = 4;
const unsigned long timeoutTime = 19990;

char sF_BULK[7] = {'F','_','B','U','L','K','\0'} ;
char sS_BULK[7] = {'S','_','B','U','L','K','\0'} ;
char sS_ABS[7] = {'S','_','A','B','S',' ','\0'} ;
char sS_FLOAT[7] = {'_','F','L','O','A','T','\0'} ;
char sS_ST_BY[7] = {'_','S','T','_','B','Y','\0'} ;
char sS_CRIT [7] = {'C','R','I','T','_','V','\0'} ;

char sS_A_IN [3] = {'I','\0'} ; char sS_A_OUT [3] = {'O','\0'} ;char sS_V_IN  [3] = {'O','\0'} ;char sS_V_OUT [3] = {'O','\0'} ;

float duty_0 [325] = { 11.0,11.2,11.4,11.6,11.8, 12.0,12.2,12.4,12.6,12.8, 13.0,13.2,13.4,13.6,13.8, 14.0,14.2,14.4,14.6,14.8, 
                       15.0,15.2,15.4,15.6,15.8, 16.0,16.2,16.4,16.6,16.8, 17.0,17.2,17.4,17.6,17.8, 18.0,18.2,18.4,18.6,18.8, 
                       19.0,19.2,19.4,19.6,19.8, 20.0,20.2,20.4,20.6,20.8,
                       21.0,21.2,21.4,21.6,21.8, 22.0,22.2,22.4,22.6,22.8, 23.0,23.2,23.4,23.6,23.8, 24.0,24.2,24.4,24.6,24.8, 
                       25.0,25.2,25.4,25.6,25.8, 26.0,26.2,26.4,26.6,26.8, 27.0,27.2,27.4,27.6,27.8, 28.0,28.2,28.4,28.6,28.8, 
                       29.0,29.2,29.4,29.6,29.8, 30.0,30.2,30.4,30.6,30.8,
                       31.0,31.2,31.4,31.6,31.8, 32.0,32.2,32.4,32.6,32.8, 33.0,33.2,33.4,33.6,33.8, 34.0,34.2,34.4,34.6,34.8, 
                       35.0,35.2,35.4,35.6,35.8, 36.0,36.2,36.4,36.6,36.8, 37.0,37.2,37.4,37.6,37.8, 38.0,38.2,38.4,38.6,38.8, 
                       39.0,39.2,39.4,39.6,39.8, 40.0,40.2,40.4,40.6,40.8, 41.0,41.2,41.4,41.6,41.8, 42.0,42.2,42.4,42.6,42.8,
                       43.0,43.2,43.4,43.6,43.8, 44.0,44.2,44.4,44.6,44.8, 45.0,45.2,45.4,45.6,45.8, 46.0,46.2,46.4,46.6,46.8,
                       47.0,47.2,47.4,47.6,47.8, 48.0,48.2,48.4,48.6,48.8, 49.0,49.2,49.4,49.6,49.8, 50.0,50.1,50.2,50.3,50.4,
                       50.5,50.6,50.7,50.8,50.9, 51.0,51.1,51.2,51.3,51.4, 51.5,51.6,51.7,51.8,51.9, 52.0,52.1,52.2,52.3,52.4,
                       52.5,52.6,52.7,52.8,52.9, 53.0,53.1,53.2,53.3,53.4, 53.5,53.6,53.7,53.8,53.9, 54.0,54.2,54.4,54.6,54.8,
                       55.0,55.2,55.4,55.6,55.8, 56.0,56.2,56.4,56.6,56.8, 57.0,57.2,57.4,57.6,57.8, 58.0,58.2,58.4,58.6,58.8,
                       59.0,59.2,59.4,59.6,59.8 ,60.0,60.2,60.4,60.6,60.8, 61.0,61.2,61.4,61.6,61.8 ,62.0,62.2,62.4,62.6,62.8,
                       63.0,63.2,63.4,63.6,63.8, 64.0,64.2,64.4,64.6,64.8, 65.0,65.2,65.4,65.6,65.8, 66.0,66.2,66.4,66.6,66.8,
                       67.0,67.2,67.4,67.6,67.8, 68.0,68.2,68.4,68.6,68.8, 69.0,69.2,69.4,69.6,69.8, 70.0,70.2,70.4,70.6,70.8,
                       71.0,71.2,71.4,71.6,71.8  };

float duty_1 [325] = { 11.0,11.2,11.4,11.6,11.8, 12.0,12.2,12.4,12.6,12.8, 13.0,13.2,13.4,13.6,13.8, 14.0,14.2,14.4,14.6,14.8, 
                       15.0,15.2,15.4,15.6,15.8, 16.0,16.2,16.4,16.6,16.8, 17.0,17.2,17.4,17.6,17.8, 18.0,18.2,18.4,18.6,18.8, 
                       19.0,19.2,19.4,19.6,19.8, 20.0,20.2,20.4,20.6,20.8,
                       21.0,21.2,21.4,21.6,21.8, 22.0,22.2,22.4,22.6,22.8, 23.0,23.2,23.4,23.6,23.8, 24.0,24.2,24.4,24.6,24.8, 
                       25.0,25.2,25.4,25.6,25.8, 26.0,26.2,26.4,26.6,26.8, 27.0,27.2,27.4,27.6,27.8, 28.0,28.2,28.4,28.6,28.8, 
                       29.0,29.2,29.4,29.6,29.8, 30.0,30.2,30.4,30.6,30.8,
                       31.0,31.2,31.4,31.6,31.8, 32.0,32.2,32.4,32.6,32.8, 33.0,33.2,33.4,33.6,33.8, 34.0,34.2,34.4,34.6,34.8, 
                       35.0,35.2,35.4,35.6,35.8, 36.0,36.2,36.4,36.6,36.8, 37.0,37.2,37.4,37.6,37.8, 38.0,38.2,38.4,38.6,38.8, 
                       39.0,39.2,39.4,39.6,39.8, 40.0,40.2,40.4,40.6,40.8, 41.0,41.2,41.4,41.6,41.8, 42.0,42.2,42.4,42.6,42.8,
                       43.0,43.2,43.4,43.6,43.8, 44.0,44.2,44.4,44.6,44.8, 45.0,45.2,45.4,45.6,45.8, 46.0,46.2,46.4,46.6,46.8,
                       47.0,47.2,47.4,47.6,47.8, 48.0,48.2,48.4,48.6,48.8, 49.0,49.2,49.4,49.6,49.8, 50.0,50.1,50.2,50.3,50.4,
                       50.5,50.6,50.7,50.8,50.9, 51.0,51.1,51.2,51.3,51.4, 51.5,51.6,51.7,51.8,51.9, 52.0,52.1,52.2,52.3,52.4,
                       52.5,52.6,52.7,52.8,52.9, 53.0,53.1,53.2,53.3,53.4, 53.5,53.6,53.7,53.8,53.9, 54.0,54.2,54.4,54.6,54.8,
                       55.0,55.2,55.4,55.6,55.8, 56.0,56.2,56.4,56.6,56.8, 57.0,57.2,57.4,57.6,57.8, 58.0,58.2,58.4,58.6,58.8,
                       59.0,59.2,59.4,59.6,59.8 ,60.0,60.2,60.4,60.6,60.8, 61.0,61.2,61.4,61.6,61.8 ,62.0,62.2,62.4,62.6,62.8,
                       63.0,63.2,63.4,63.6,63.8, 64.0,64.2,64.4,64.6,64.8, 65.0,65.2,65.4,65.6,65.8, 66.0,66.2,66.4,66.6,66.8,
                       67.0,67.2,67.4,67.6,67.8, 68.0,68.2,68.4,68.6,68.8, 69.0,69.2,69.4,69.6,69.8, 70.0,70.2,70.4,70.6,70.8,
                       71.0,71.2,71.4,71.6,71.8  };

float duty_2 [325] = { 11.0,11.2,11.4,11.6,11.8, 12.0,12.2,12.4,12.6,12.8, 13.0,13.2,13.4,13.6,13.8, 14.0,14.2,14.4,14.6,14.8, 
                       15.0,15.2,15.4,15.6,15.8, 16.0,16.2,16.4,16.6,16.8, 17.0,17.2,17.4,17.6,17.8, 18.0,18.2,18.4,18.6,18.8, 
                       19.0,19.2,19.4,19.6,19.8, 20.0,20.2,20.4,20.6,20.8,
                       21.0,21.2,21.4,21.6,21.8, 22.0,22.2,22.4,22.6,22.8, 23.0,23.2,23.4,23.6,23.8, 24.0,24.2,24.4,24.6,24.8, 
                       25.0,25.2,25.4,25.6,25.8, 26.0,26.2,26.4,26.6,26.8, 27.0,27.2,27.4,27.6,27.8, 28.0,28.2,28.4,28.6,28.8, 
                       29.0,29.2,29.4,29.6,29.8, 30.0,30.2,30.4,30.6,30.8,
                       31.0,31.2,31.4,31.6,31.8, 32.0,32.2,32.4,32.6,32.8, 33.0,33.2,33.4,33.6,33.8, 34.0,34.2,34.4,34.6,34.8, 
                       35.0,35.2,35.4,35.6,35.8, 36.0,36.2,36.4,36.6,36.8, 37.0,37.2,37.4,37.6,37.8, 38.0,38.2,38.4,38.6,38.8, 
                       39.0,39.2,39.4,39.6,39.8, 40.0,40.2,40.4,40.6,40.8, 41.0,41.2,41.4,41.6,41.8, 42.0,42.2,42.4,42.6,42.8,
                       43.0,43.2,43.4,43.6,43.8, 44.0,44.2,44.4,44.6,44.8, 45.0,45.2,45.4,45.6,45.8, 46.0,46.2,46.4,46.6,46.8,
                       47.0,47.2,47.4,47.6,47.8, 48.0,48.2,48.4,48.6,48.8, 49.0,49.2,49.4,49.6,49.8, 50.0,50.1,50.2,50.3,50.4,
                       50.5,50.6,50.7,50.8,50.9, 51.0,51.1,51.2,51.3,51.4, 51.5,51.6,51.7,51.8,51.9, 52.0,52.1,52.2,52.3,52.4,
                       52.5,52.6,52.7,52.8,52.9, 53.0,53.1,53.2,53.3,53.4, 53.5,53.6,53.7,53.8,53.9, 54.0,54.2,54.4,54.6,54.8,
                       55.0,55.2,55.4,55.6,55.8, 56.0,56.2,56.4,56.6,56.8, 57.0,57.2,57.4,57.6,57.8, 58.0,58.2,58.4,58.6,58.8,
                       59.0,59.2,59.4,59.6,59.8 ,60.0,60.2,60.4,60.6,60.8, 61.0,61.2,61.4,61.6,61.8 ,62.0,62.2,62.4,62.6,62.8,
                       63.0,63.2,63.4,63.6,63.8, 64.0,64.2,64.4,64.6,64.8, 65.0,65.2,65.4,65.6,65.8, 66.0,66.2,66.4,66.6,66.8,
                       67.0,67.2,67.4,67.6,67.8, 68.0,68.2,68.4,68.6,68.8, 69.0,69.2,69.4,69.6,69.8, 70.0,70.2,70.4,70.6,70.8,
                       71.0,71.2,71.4,71.6,71.8  };                                            


float AMPS_MAX [3][6] = { { 19, 19, 19, 19, 19, 19   }, { 12, 12, 12, 12, 12, 12   } ,{ 6, 6, 6, 6, 6, 6  }  };
int duty_modulo = 325;int duty_index = 1;int duty_index_b = 1;int amps_index = 0;int phase = 0;
float A1_awg, A1_sum, A2_awg, A2_sum  = 0;
float max_volts, max_volts_slow, max_volts_float ,rebulk_volts, min_panel_volts  ;
int amps_modulo = 6;
float AMPS [3][6] = { { 17, 17, 17, 17, 17, 17   }, { 10, 10, 10, 10, 10, 10   } ,{ 4, 4, 4, 4, 4, 4   }  };
boolean setup_amps, mppt, lfp, temp_algo;
float   amps_f,   amps_s, amps_step, max_v_in, max_v_out, critical_volts, T_factor;
int duty_begin;
  
float x,y,z,n = 0.0;
char sx[10] = {' '} ;char sy[10] = {' '} ;char sz[10] = {' '} ;
char sa[10] = {' '} ;char sn[10] = {' '} ;char ss[10] = {' '} ;
char x0 [10] = {' '};  char x1 [10] = {' '};  char x2 [10] = {' '}; 
char x3 [10] = {' '};  char x4 [10] = {' '};  char x5 [10] = {' '};
char x6 [10] = {' '};   char x7 [10] = {' '};    char x8 [10] = {' '};  char x9 [10] = {' '};

int16_t adc0, adc1, adc2, adc3, adc1_0;
int32_t adc_avg;

float volts0, volts1, volts2, volts3, volts1_0, V_IN, V_OUT, V_OC;
float amps0, amps1, amps1_0, amps_1, p_in, p_out, eta, p_out_0, p_out_1, wh;
float V_panels, V_panels_last, power, power_last;

const int S_max = 3;
int32_t A_0_a [S_max] = {13300};
int A_0_i = 0;
int32_t A_1_a [S_max] = {13200};
int A_1_i = 0;
int32_t A_2_a [S_max] = {13200};
int A_2_i = 0;
 
const float volts0_off = 2494.0;
const float volts1_off = 2489.0;
const float volts1_0_off = 2482.0;

const float volts2_off = - 0.120;
const float volts3_off = - 0.120;
const float FACTOR_IN = 13.23; // -----------------mV per AMPER
const float FACTOR_OUT_0 = -13.23; // ACS758 sens. mV per AMPER
const float FACTOR_OUT_1 = -13.23; // ------------ mV per AMPER

//String tempA [10] = { "29.12","28.95","14.77","15.05","28.83","56.12","1674.06", "20.36","86.12","1752.94"  };
String tempA [12] = { "29.12","28.95","14.77","15.05","28.83","56.12","1674.06", "93.98", "20.36","86.12","1752.94", "1.02"  };

JSONVar sliderValues;

String getSliderValues(){
  sliderValues["sliderValue1"] = String(sliderValue1);  sliderValues["sliderValue2"] = String(sliderValue2);
  sliderValues["sliderValue3"] = String(sliderValue3);  sliderValues["sliderValue4"] = String(sliderValue4);
  String jsonString = JSON.stringify(sliderValues);
  return jsonString;
}

void initFS() {
  if (!SPIFFS.begin()) {    Serial.println("An error has occurred while mounting SPIFFS");  }
  else { Serial.println("SPIFFS mounted successfully");  }
}

void initWiFi() {
  WiFi.mode(WIFI_STA);  WiFi.begin(ssid, password);  Serial.print("Connecting to WiFi ..");
  while (WiFi.status() != WL_CONNECTED) {    Serial.print('.');    delay(500);  }
  Serial.println(WiFi.localIP());
}

void notifyClients(String sliderValues) {
  ws.textAll(sliderValues);
}

void handleWebSocketMessage(void *arg, uint8_t *data, size_t len) {
  AwsFrameInfo *info = (AwsFrameInfo*)arg;
  if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
    data[len] = 0;
    message = (char*)data;
    if (message.indexOf("1s") >= 0) {
      sliderValue1 = message.substring(2);
      dutyCycle1 = map(sliderValue1.toInt(), 0, 100, 0, 255);
      Serial.println(dutyCycle1);
      Serial.print(getSliderValues());
      notifyClients(getSliderValues());
    }
    if (message.indexOf("2s") >= 0) {
      sliderValue2 = message.substring(2);
      dutyCycle2 = map(sliderValue2.toInt(), 0, 100, 0, 255);
      Serial.println(dutyCycle2);
      Serial.print(getSliderValues());
      notifyClients(getSliderValues());
    }    
    if (message.indexOf("3s") >= 0) {
      sliderValue3 = message.substring(2);
      dutyCycle3 = map(sliderValue3.toInt(), 0, 100, 0, 255);
      Serial.println(dutyCycle3);
      Serial.print(getSliderValues());
      notifyClients(getSliderValues());
    }
     if (message.indexOf("4s") >= 0) {
      sliderValue4 = message.substring(2);
      dutyCycle4 = map(sliderValue4.toInt(), 0, 100, 0, 255);
      Serial.println(dutyCycle4);
      Serial.print(getSliderValues());
      notifyClients(getSliderValues());
    }
    if (strcmp((char*)data, "getValues") == 0) {
      notifyClients(getSliderValues());
    }
  }
}

void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
  switch (type) {
    case WS_EVT_CONNECT:
      Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
      break;
    case WS_EVT_DISCONNECT:
      Serial.printf("WebSocket client #%u disconnected\n", client->id());
      break;
    case WS_EVT_DATA:
      handleWebSocketMessage(arg, data, len);
      break;
    case WS_EVT_PONG:
    case WS_EVT_ERROR:
      break;
  }
}

void initWebSocket() {
  ws.onEvent(onEvent);
  server.addHandler(&ws);
}

String processor(const String& var){

  if(var == "TEMPERATUREA"){
    return tempA[0];
  }
  else if(var == "TEMPERATUREB"){
    return tempA[1];
  }
  else if(var == "TEMPERATUREC"){
    return tempA[2];
  }
  else if(var == "TEMPERATURED"){
    return tempA[3];
  }
   else if(var == "TEMPERATUREE"){
    return tempA[4];
  }
   else if(var == "TEMPERATUREF"){
    return tempA[5];
  }
   else if(var == "TEMPERATUREG"){
    return tempA[6];
  }
   else if(var == "TEMPERATUREH"){
    return tempA[7];
  }
   else if(var == "TEMPERATUREI"){
    return tempA[8];
  }
   else if(var == "TEMPERATUREJ"){
    return tempA[9];
  }
  else if(var == "TEMPERATUREK"){
    return tempA[10];
  }
  else if(var == "TEMPERATUREL"){
    return tempA[11];
  }
  return String();
}

void readTemp_1 () {
  sensors.requestTemperatures();   float temp_1 = sensors.getTempCByIndex(0);
  Serial.print(temp_1);  Serial.print("ºC_1");  tempA [0] = String(temp_1);
  temp_1 = sensors.getTempCByIndex(1);  Serial.print(temp_1);  Serial.println("ºC_2");
  tempA [1] = String(temp_1);
}

void set_lcd (){
  lcd.init();    
  lcd.backlight(); lcd.setCursor(1,0);  lcd.print("MPPT ver.  -07.07-!");
  lcd.setCursor(1,1);  lcd.print("Amps  OUT: ");   lcd.setCursor(1,2);  lcd.print("Volts IN : ");
  lcd.setCursor(1,3);  lcd.print("VOLTS OUT: ");  char x1 [10] = {' '};  char x2 [10] = {' '};  char x3 [10] = {' '};  char x4 [10] = {' '};
  
  sprintf (x2, "%3.2f", amps_f );   x2[7] = {'\0'} ;  sprintf (x3, "%3.2f", volts2 );   x3[7] = {'\0'} ;
  sprintf (x4, "%3.2f", volts3 );   x4[7] = {'\0'} ;  lcd.setCursor(12,1);       lcd.print( x2 );
  lcd.setCursor(12,2);       lcd.print( x3 );  lcd.setCursor(12,3);       lcd.print( x4 );
  delay (550);    lcd.init();     lcd.backlight();
  lcd.setCursor(1,0);  lcd.print("      A           W");
  lcd.setCursor(1,1);  lcd.print("      A           C");
  lcd.setCursor(1,2);  lcd.print("      A           C");
  lcd.setCursor(1,3);  lcd.print("      V           V");
  delay (100);
  sx[9] = {'\0'} ;     sy[9] = {'\0'} ;      sz[9] = {'\0'} ;     sa[9] = {'\0'} ;     
}

void printAddress(DeviceAddress deviceAddress) {
  for (uint8_t i = 0; i < 8; i++){     if (deviceAddress[i] < 16) Serial.print("0");      Serial.print(deviceAddress[i], HEX);  }
}  

void set_sd_HIGH (){ digitalWrite ( SD_PIN, HIGH ); digitalWrite ( SD_PIN2, HIGH ); }

void set_sd_LOW (){ digitalWrite ( SD_PIN, LOW ); digitalWrite ( SD_PIN2, LOW ); }

static void readOutTemp( void * pvParameters )
{
  for(;;)
  {
    if (1)
    {
      String extTemp = "";      sensors.requestTemperatures();
      extTemp = (String)sensors.getTempCByIndex(0);      tempA [0] = String(extTemp );
      extTemp = (String)sensors.getTempCByIndex(1);      tempA [1] = String(extTemp );
      #if DEBUG 
        Serial.print("Temperature: ");        Serial.println(extTemp);
      #endif
      delay(1);  
    }
    delay(1);  
  }
}

void setup(void)
{
  Serial.begin(115200);   rtc.begin();
  pinMode ( SD_PIN, OUTPUT );   pinMode ( SD_PIN2, OUTPUT );
  digitalWrite ( SD_PIN, LOW );   digitalWrite ( SD_PIN2, LOW );
  EEPROM.begin( EEPROM_MAX );    wh_day = 0;    wh_all = 0;
  xTaskCreatePinnedToCore(
      readOutTemp,                       /* Function to implement the task */
      "readOutTemp ",                    /* Name of the task */
      8192,                           /* Stack size in words */
      NULL,                           /* Task input parameter */
      5,                              /* Priority of the task idle ... WTD */
      NULL,                           /* Task handle. */
   0);  
      
   sensors.begin();
   numberOfDevices = sensors.getDeviceCount();  Serial.print("Found ");  Serial.print(numberOfDevices, DEC);  Serial.println(" devices.");
   for(int i=0;i<numberOfDevices; i++){
   if(sensors.getAddress(tempDeviceAddress, i)){
      Serial.print("Found device ");Serial.print(i, DEC);Serial.print(" with address: ");printAddress(tempDeviceAddress);Serial.println();
    } else {
      Serial.print("Found ghost device at ");Serial.print(i, DEC);Serial.print(" but could not detect address. Check power and cabling");
    }
  }
    // configure LED PWM for FAN_0 & FAN_1
  ledcSetup(ledChannel_0, freq, resolution);  ledcSetup(ledChannel_1, freq, resolution);
    
  // attach the channel to the GPIO to be controlled
  ledcAttachPin(FAN_PIN_0, ledChannel_0);  ledcAttachPin(FAN_PIN_1, ledChannel_1);
  dutyCycle1 = 128;  dutyCycle2 = 128;  ledcWrite(ledChannel_0, dutyCycle1);  ledcWrite(ledChannel_1, dutyCycle2);
  
   mcpwm_config_t pwm_config_0;    mcpwm_config_t pwm_config_0_1;    mcpwm_config_t pwm_config_0_2;
   mcpwm_config_t pwm_config_1;    mcpwm_config_t pwm_config_1_1;    mcpwm_config_t pwm_config_1_2;
 
   mcpwm_gpio_init(MCPWM_UNIT_1, MCPWM0A, GPIO_PWM0A_OUT);
   mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0B, GPIO_PWM0B_OUT);
   mcpwm_gpio_init(MCPWM_UNIT_1, MCPWM1A, GPIO_PWM1A_OUT);
   mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM1B, GPIO_PWM1B_OUT);
   mcpwm_gpio_init(MCPWM_UNIT_1, MCPWM2A, GPIO_PWM2A_OUT);
   mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM2B, GPIO_PWM2B_OUT);

   mcpwm_sync_config_t  sync_ttt_0 ;
   sync_ttt_0.sync_sig = MCPWM_SELECT_TIMER0_SYNC;
   sync_ttt_0.timer_val = 600;
   sync_ttt_0.count_direction   = MCPWM_TIMER_DIRECTION_UP;

   mcpwm_sync_config_t  sync_ttt_1 ;
   sync_ttt_1.sync_sig = MCPWM_SELECT_TIMER0_SYNC;
   sync_ttt_1.timer_val = 0;
   sync_ttt_1.count_direction   = MCPWM_TIMER_DIRECTION_UP;

  
  ads0.setGain(GAIN_ONE);        // 1x gain   +/- 4.096V  1 bit = 2mV      0.125mV
  ads1.setGain(GAIN_ONE);  
  // ads.setGain(GAIN_TWO);     0.0625mV
  // ads.setGain(GAIN_FOUR);    0.03125mV
  // ads.setGain(GAIN_EIGHT);   0.015625mV
  // ads.setGain(GAIN_SIXTEEN); 0.0078125mV
  lcd.init();       lcd.backlight();    lcd.setCursor(1,0);     rtc.DSread(); 
   lcd.print( rtc.getTime() );   lcd.setCursor(1,1);   lcd.print( rtc.getDate() ); 
   delay (1111);      
  
  if (!ads0.begin(0x49)) {
    Serial.println("Failed to initialize ADS.");   lcd.init();       lcd.backlight();    lcd.setCursor(1,0);   lcd.print("1115_x49_NOTOK");
    while (1);
  }
  if (!ads1.begin(0x48)) {
    Serial.println("Failed to initialize ADS.");   lcd.init();       lcd.backlight();    lcd.setCursor(2,0);   lcd.print("1115_x48_NOTOK");
    while (1);
  }
  
  previous = millis();  now = millis();  currentTime = millis();  previousTime = millis();
  sx[8] = {'\0'} ;    sy[8] = {'\0'} ;      sz[8] = {'\0'} ;
  setup_amps = true;   mppt = false;   amps_step = 0.5;
  duty_index = 20;   amps_f = 10;   amps_s = 8;   phase = 0;
  V_panels_last = 0;   power_last = 0;   duty_high = 0;   duty_low = 0;
  max_volts_high = 0;   wh = 0;
  lcd.init();       lcd.backlight();    lcd.setCursor(1,0);   lcd.print("MPPT_______________");
  if ( setup_amps  ) 
  {
     amps_f = get_amps ();
     for (int i=0; i< amps_modulo; i++) { 
       AMPS_MAX [phase][i] = amps_f;
       AMPS [phase][i] = amps_f - 1.5;
     }
     get_mppt ();     get_batt ();     get_temp_algo ();     print_temps ();
     delay (199);     setup_amps = false;
  }

  uint32_t PWM = PWM_1;    uint32_t PWM_0 = PWM_10;
    if ( amps_f < 30.0  )    {       PWM = PWM_2; PWM_0 = PWM_20;    }
    if ( amps_f > 60.0  )    {       PWM = PWM_3; PWM_0 = PWM_30;    } 
    if ( amps_f > 80.0  )    {       PWM = PWM_4; PWM_0 = PWM_40;    } 
    pwm_config_0.frequency = PWM;    //frequency 
    pwm_config_0.cmpr_a = 50.0;       // Duty em porcentagem
    pwm_config_0.cmpr_b = 50.0;       
    pwm_config_0.counter_mode = MCPWM_UP_COUNTER;
    pwm_config_0.duty_mode = MCPWM_DUTY_MODE_0;
    
    pwm_config_0_1.frequency = PWM;    //frequency 
    pwm_config_0_1.cmpr_a = 50.0;       // Duty em porcentagem
    pwm_config_0_1.cmpr_b = 50.0;       
    pwm_config_0_1.counter_mode = MCPWM_UP_COUNTER;
    pwm_config_0_1.duty_mode = MCPWM_DUTY_MODE_0;

    pwm_config_0_2.frequency = PWM;    //frequency 
    pwm_config_0_2.cmpr_a = 50.0;       // Duty em porcentagem
    pwm_config_0_2.cmpr_b = 50.0;       
    pwm_config_0_2.counter_mode = MCPWM_UP_COUNTER;
    pwm_config_0_2.duty_mode = MCPWM_DUTY_MODE_0;

    pwm_config_1.frequency = PWM_0;    //frequency 
    pwm_config_1.cmpr_a = 0.0;       // Duty em porcentagem
    pwm_config_1.cmpr_b = 50.0;       
    pwm_config_1.counter_mode = MCPWM_UP_COUNTER;
    pwm_config_1.duty_mode = MCPWM_DUTY_MODE_1;

    pwm_config_1_2.frequency = PWM_0;    //fr equency 
    pwm_config_1_2.cmpr_a = 0.0;       // Duty em porcentagem
    pwm_config_1_2.cmpr_b = 50.0;       
    pwm_config_1_2.counter_mode = MCPWM_UP_COUNTER;
    pwm_config_1_2.duty_mode = MCPWM_DUTY_MODE_1;

    mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &pwm_config_0);   //Configure PWM0A & PWM0B with above settings
    mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_1, &pwm_config_0_1);   //Configure PWM1A & PWM1B with above settings
    mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_2, &pwm_config_0_2);   //Configure PWM2A & PWM2B with above settings   

    mcpwm_init(MCPWM_UNIT_1, MCPWM_TIMER_0, &pwm_config_0_2);   //Configure PWM0A & PWM0B with above settings
    mcpwm_init(MCPWM_UNIT_1, MCPWM_TIMER_1, &pwm_config_0_2);   //Configure PWM1A & PWM1B with above settings
    mcpwm_init(MCPWM_UNIT_1, MCPWM_TIMER_2, &pwm_config_0_2);   //Configure PWM2A & PWM2B with above settings   

    mcpwm_group_set_resolution( MCPWM_UNIT_0, 80000000) ;
    mcpwm_timer_set_resolution( MCPWM_UNIT_0, MCPWM_TIMER_0, 8000000);
    mcpwm_timer_set_resolution( MCPWM_UNIT_0, MCPWM_TIMER_1, 8000000);
    mcpwm_timer_set_resolution( MCPWM_UNIT_0, MCPWM_TIMER_2, 8000000);
    mcpwm_group_set_resolution( MCPWM_UNIT_1, 80000000) ;
    mcpwm_timer_set_resolution( MCPWM_UNIT_1, MCPWM_TIMER_0, 8000000);
    mcpwm_timer_set_resolution( MCPWM_UNIT_1, MCPWM_TIMER_1, 8000000);
    mcpwm_timer_set_resolution( MCPWM_UNIT_1, MCPWM_TIMER_2, 8000000);

    mcpwm_sync_configure(MCPWM_UNIT_0, MCPWM_TIMER_1, &sync_ttt_0);
    mcpwm_sync_configure(MCPWM_UNIT_0, MCPWM_TIMER_2,  &sync_ttt_1);
    mcpwm_sync_configure(MCPWM_UNIT_1, MCPWM_TIMER_1, &sync_ttt_0);
    mcpwm_sync_configure(MCPWM_UNIT_1, MCPWM_TIMER_2,  &sync_ttt_1);
   
    adc2 = ads0.readADC_SingleEnded(2); // consider median
    adc3 = ads0.readADC_SingleEnded(3); // consider median
    volts2 = ads0.computeVolts(adc2);
    volts3 = ads0.computeVolts(adc3);
    volts2 = volts2 * 18.0 / 1.037;
    volts3 = volts3 * 36.0 / 1.067;

    char x3 [10] = {' '};  char x4 [10] = {' '};    sprintf (x3, "%3.2f", volts2 );   x3[7] = {'\0'} ;    sprintf (x4, "%3.2f", volts3 );   x4[7] = {'\0'} ;
    lcd.setCursor(2,3);       lcd.print( x3 );       lcd.setCursor(12,3);      lcd.print( x4 );
    V_IN = volts3; V_OC = V_IN;
    V_OUT = volts2;

    if ((  V_OUT > MIN_V_OUT_12V) &&  ( V_OUT < MAX_V_OUT_12V )) {
       max_v_out = MAX_V_OUT_12V;
       critical_volts = CRITICAL_VOLTS;
       min_panel_volts = MIN_PANEL_VOLTS_12V;
       get_wh ();
       if (  lfp ) {
         max_volts = MAX_VOLTS_LFP; max_volts_slow = MAX_VOLTS_SLOW_LFP;max_volts_float = MAX_VOLTS_FLOAT_LFP;rebulk_volts = REBULK_VOLTS_LFP; }
       else  { max_volts = MAX_VOLTS_PB; max_volts_slow = MAX_VOLTS_SLOW_PB; max_volts_float = MAX_VOLTS_FLOAT_PB; rebulk_volts = REBULK_VOLTS_PB;         }
    }
    if ((  V_OUT > MIN_V_OUT_24V) &&  ( V_OUT < MAX_V_OUT_24V )) {
       max_v_out = MAX_V_OUT_24V;
       critical_volts = 2 * CRITICAL_VOLTS;
       min_panel_volts = MIN_PANEL_VOLTS_24V;
       get_wh ();
       if (  lfp ) { max_volts = 2 * MAX_VOLTS_LFP; max_volts_slow = 2 * MAX_VOLTS_SLOW_LFP; max_volts_float = 2 * MAX_VOLTS_FLOAT_LFP; rebulk_volts = 2 * REBULK_VOLTS_LFP;         }
       else  { max_volts = 2 * MAX_VOLTS_PB; max_volts_slow = 2 * MAX_VOLTS_SLOW_PB; max_volts_float = 2 * MAX_VOLTS_FLOAT_PB; rebulk_volts = 2 * REBULK_VOLTS_PB;    }
    }
    if ((  V_OUT > MIN_V_OUT_48V) &&  ( V_OUT < MAX_V_OUT_48V )) {
       max_v_out = MAX_V_OUT_48V;
       critical_volts = 4 * CRITICAL_VOLTS;
       min_panel_volts = MIN_PANEL_VOLTS_48V;
       get_wh ();
       if (  lfp ) { max_volts = 4 * MAX_VOLTS_LFP; max_volts_slow = 4 * MAX_VOLTS_SLOW_LFP; max_volts_float = 4 * MAX_VOLTS_FLOAT_LFP; rebulk_volts = 4 * REBULK_VOLTS_LFP;  }
       else { max_volts = 4 * MAX_VOLTS_PB; max_volts_slow = 4 * MAX_VOLTS_SLOW_PB; max_volts_float = 4 * MAX_VOLTS_FLOAT_PB; rebulk_volts = 4 * REBULK_VOLTS_PB;  }
    }
      
    if ( V_OUT < MIN_V_OUT_12V ) {  Serial.println("Failed to init MPPT.");  lcd.init();    
      lcd.backlight();  lcd.setCursor(1,0); lcd.print("V_OUT_LOW !");
      while (1);
    }
     
    if ( V_IN > MAX_V_IN ) {  Serial.println("Failed to init MPPT.");      lcd.init();    
      lcd.backlight();    lcd.setCursor(1,0);   lcd.print("V_IN_HIGH !");
      while (1);
    }
    
    if ( V_OUT > max_v_out ) {   Serial.println("Failed to init MPPT.");    lcd.init();    
      lcd.backlight();      lcd.setCursor(1,0);     lcd.print("V_OUT_HIGH !");
      while (1);
    }
    
    if ( V_IN < V_OUT ) {   Serial.println("Failed to init MPPT.");   lcd.init();    
      lcd.backlight();     lcd.setCursor(1,0);     lcd.print("V_IN_LOW !");
      while (1);
    }
    
    for (int i=0; i < duty_modulo ; i++) {   
       if ( duty_0 [i] <  (float )(V_OUT / V_IN * 96.0 )) duty_index = i;
    }     duty_index--;duty_index--;    duty_begin = duty_index;
        
    if (  duty_0 [duty_index] / 100 * V_IN > max_v_out ) {    Serial.println("Failed to init MPPT.");
      lcd.init();    lcd.backlight();   lcd.setCursor(1,0);  lcd.print("DUTY_HIGH !");
      while (1);
    } 
    
    set_lcd ();    delay (300);    read_amps (); 
    initFS();    initWiFi();    initWebSocket();
    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SPIFFS, "/index.html", "text/html");
  });
 
  server.serveStatic("/", SPIFFS, "/");
 // Request for the latest sensor readings
  server.on("/readings", HTTP_GET, [](AsyncWebServerRequest *request){
    String json = getSensorReadings();
    request->send(200, "application/json", json);
    json = String();
  });
  events.onConnect([](AsyncEventSourceClient *client){
    if(client->lastId()){
      Serial.printf("Client reconnected! Last message ID that it got is: %u\n", client->lastId());
    }
    client->send("hello!", NULL, millis(), 10000);
  });
  
  server.addHandler(&events);  server.begin();
  set_sd_HIGH ();    loop_interval = millis();    T_factor = 1.0000;
  
}

String getSensorReadings(){
  readings["temperature_1"] = String(tempA[0]);
  readings["temperature_2"] = String(tempA[1]);
  readings["phase_1"] =  String(tempA [2]);
  readings["phase_2"] =  String(tempA [3]);
  readings["vin_1"] =  String(tempA [9]);
  readings["vout_1"] =  String(tempA [5]);
  readings["aout_1"] =  String(tempA [4]);
  readings["wout_1"] =  String(tempA [6]);
  String jsonString = JSON.stringify(readings);
  return jsonString;
}

float read_amps (){
  for (int i=0; i < S_max ; i++) {   
    adc_avg = (int32_t )ads0.readADC_SingleEnded(0);
    A_0_a [A_0_i] = adc_avg;    A_0_i = ( A_0_i + 1 ) % S_max;      isort ( A_0_a, S_max );
    adc_avg = ( A_0_a [S_max / 2] + A_0_a [S_max / 2 + 1] ) / 2;

    adc_avg = (int32_t )ads0.readADC_SingleEnded(1);
    A_1_a [A_1_i] = adc_avg;    A_1_i = ( A_1_i + 1 ) % S_max;    isort ( A_1_a, S_max );
    adc_avg = ( A_1_a [S_max / 2] + A_1_a [S_max / 2 + 1] ) / 2;

    adc_avg = (int32_t )ads1.readADC_SingleEnded(0);
    A_2_a [A_2_i] = adc_avg;    A_2_i = ( A_2_i + 1 ) % S_max;      isort ( A_2_a, S_max );
    adc_avg = ( A_2_a [S_max / 2] + A_2_a [S_max / 2 + 1] ) / 2;     
  }
  return( 0.0 );
}

void isort (int32_t * a, int n)
{
 for (int i = 1; i < n; ++i) {
   int32_t j = a[i];   int k;
   for (k = i - 1; (k >= 0) && (j < a[k]); k--)
   {     a[k + 1] = a[k];   }
   a[k + 1] = j;
 }
}

void print_temps (){
         lcd.setCursor(1,1); lcd.print("FET_1 :");  lcd.setCursor(9,1); lcd.print( tempA [0]);
         lcd.setCursor(1,2); lcd.print("FET_2 :"); lcd.setCursor(9,2); lcd.print( tempA [1]);
}

void write_wh (){
        wh_day = floor( wh );        wh_all = wh_day;        EEPROM.writeInt(Addr_0, wh_day );
        EEPROM.commit();          EEPROM.writeLong(Addr_1, wh_all );        EEPROM.commit();          //lcd.noBacklight();
}

void get_wh (){
        wh_day = EEPROM.readInt(Addr_0 );  wh_all = EEPROM.readLong(Addr_1 );  wh = floor( wh_day );      
}

void get_batt (){
     lcd.setCursor(1,0);         lcd.print("BATT : LiFePO4___"); max_volts = MAX_VOLTS_LFP;     lfp = true;         delay (333);
     while ( setup_amps  ) 
     { int touch_up = touchRead(T6);    int touch_down = touchRead(T5);    int touch_enter = touchRead(T4);
       now = millis();       currentTime = millis();
       if (now - previous > setup_interval ) {
         previous = now;
         Serial.print(" T6 up = "); Serial.println(touch_up);  Serial.print(" T5 down = ");  Serial.println(touch_down);
         Serial.print(" T4 enter = "); Serial.println(touch_enter);   Serial.print(" amsp_f = "); Serial.println( amps_f );
       }
       if ( touch_up < 20  ) 
       {
         lcd.setCursor(1,0);  lcd.print("BATT: LiFePO_13.9 V"); max_volts = MAX_VOLTS_LFP;   lfp = true;   delay (399);
       }
       touch_up = touchRead(T6);       touch_down = touchRead(T5);
       if ( touch_up < 20  )  {  lcd.setCursor(1,0);   lcd.print("BATT: AGM_Pb_14.4 V"); max_volts = MAX_VOLTS_PB;  lfp = false;   delay (399);
       }
       delay (222);
       if ( touch_down < 20  )  break ; 
     }
}

void get_mppt (){
     lcd.setCursor(1,0);  lcd.print("ALGO : CHARGER_____"); mppt = false;    delay (333);
     while ( setup_amps  ) 
     { int touch_up = touchRead(T6);      int touch_down = touchRead(T5);      int touch_enter = touchRead(T4);
       now = millis();       currentTime = millis();
       if (now - previous > setup_interval ) {
         previous = now;
         Serial.print(" T6 up = ");  Serial.println(touch_up);  Serial.print(" T5 down = "); Serial.println(touch_down);
         Serial.print(" T4 enter = ");  Serial.println(touch_enter);  Serial.print(" amsp_f = ");  Serial.println( amps_f );
       }
       if ( touch_up < 20  ) 
       {
         lcd.setCursor(1,0);      lcd.print("ALGO : MPPT________"); mppt = true;      delay (399);
       }
       touch_up = touchRead(T6);       touch_down = touchRead(T5);
       if ( touch_up < 20  )  {  lcd.setCursor(1,0);  lcd.print("ALGO : CHARGER_____"); mppt = false;  delay (399);
       }
       delay (322);
       if ( touch_down < 20  )  break ; 
     }
}

void get_temp_algo (){
     lcd.setCursor(1,0);
     lcd.print("ALGO : OPTIMAL____"); temp_algo = false;         delay (333);
     while ( setup_amps  ) 
     { int touch_up = touchRead(T6); int touch_down = touchRead(T5);  int touch_enter = touchRead(T4);
       now = millis();   currentTime = millis();
       if (now - previous > setup_interval ) {
         previous = now;
         Serial.print(" T6 up = "); Serial.println(touch_up);   Serial.print(" T5 down = ");   Serial.println(touch_down);
         Serial.print(" T4 enter = ");  Serial.println(touch_enter);  Serial.print(" amsp_f = ");   Serial.println( amps_f );
       }
       if ( touch_up < 20  ) 
       {
         lcd.setCursor(1,0);   lcd.print("ALGO : MIN_TEMP____"); temp_algo = true;     delay (399);
       }
       touch_up = touchRead(T6);       touch_down = touchRead(T5);
       if ( touch_up < 20  ) 
       {
         lcd.setCursor(1,0);    lcd.print("ALGO : OPTIMAL____"); temp_algo = false;     delay (399);
       }
       delay (322);
       if ( touch_down < 20  )  break ; 
     }
}

float get_amps (){
     while ( setup_amps  ) 
     { int touch_up = touchRead(T6);   int touch_down = touchRead(T5);   int touch_enter = touchRead(T4);
       now = millis();       currentTime = millis();
       if (now - previous > setup_interval ) {
         previous = now;
         Serial.print(" T6 up = ");   Serial.println(touch_up);    Serial.print(" T5 down = ");    Serial.println(touch_down);
          Serial.print(" T4 enter = ");  Serial.println(touch_enter);   Serial.print(" amsp_f = ");    Serial.println( amps_f );
       }
       if ( touch_up < 20  ) 
       {
         amps_f = ( amps_f + amps_step ) ; 
       }   
       delay (99);       lcd.setCursor(1,0);       lcd.print("AMPS :_____________");       n = amps_f;
       sprintf (sn, "%f.1", n );        sn[7] = {'\0'} ;       lcd.setCursor(12,0);       lcd.print( sn );
       if ( touch_down < 20  )  break ; 
     }
    return( amps_f );               // divide sum by AVG_NUM to get average and return it
}

void loop(void)
{
  now = millis();  currentTime = millis();  now_m = micros();
  loop_interval = now_m - loop_time;  loop_time = now_m;
  adc2 = ads0.readADC_SingleEnded(2);  volts2 = ads0.computeVolts(adc2);
  volts2 = volts2 * 17.35775;
  if  (  volts2 > critical_volts   )  
  {
     set_sd_LOW (); lcd.setCursor(10,3);  lcd.print( sS_CRIT );  num_of_intervals = 0;
  }
  adc_avg = ads0.readADC_SingleEnded(0);
  A_0_a [A_0_i] = adc_avg;  A_0_i = ( A_0_i + 1 ) % S_max;  isort ( A_0_a, S_max ); adc_avg = ( A_0_a [S_max / 2] + A_0_a [S_max / 2 + 1] ) / 2;
  adc0 =  (int16_t )adc_avg;
  adc_avg = ads0.readADC_SingleEnded(1);
  A_1_a [A_1_i] = adc_avg; A_1_i = ( A_1_i + 1 ) % S_max; isort ( A_1_a, S_max ); adc_avg = ( A_1_a [S_max / 2] + A_1_a [S_max / 2 + 1] ) / 2;
  adc1 = (int16_t ) adc_avg;
  adc_avg = ads1.readADC_SingleEnded(0);
  A_2_a [A_2_i] = adc_avg; A_2_i = ( A_2_i + 1 ) % S_max;  isort ( A_2_a, S_max ); adc_avg = ( A_2_a [S_max / 2] + A_2_a [S_max / 2 + 1] ) / 2;     
  adc1_0 = (int16_t )adc_avg;
  adc3 = ads0.readADC_SingleEnded(3);
  volts0 = ads0.computeVolts(adc0)*1000.0 -volts0_off;
  volts1 = ads0.computeVolts(adc1)*1000.0 -volts1_off;
  volts1_0 = ads1.computeVolts(adc1_0)*1000.0 -volts1_0_off;
  volts2 = ads0.computeVolts(adc2);
  volts3 = ads0.computeVolts(adc3);
  volts2 = volts2 * 17.35775;  volts3 = volts3 * 33.73951;
  amps0 = T_factor * volts0 / FACTOR_IN;  amps1 = T_factor * volts1 / FACTOR_OUT_0;
  amps1_0 = T_factor * volts1_0 / FACTOR_OUT_1;  amps_1 =  amps1 +  amps1_0;
  p_in = amps0 *  volts3;  p_out_0 = amps1 *  volts2;  p_out_1 = amps1_0 *  volts2;  p_out  = p_out_0 + p_out_1;
  if ( mppt  ) 
  {
     V_panels  = volts3;     power = p_out;
     if ( power  < 1.0  ) duty_index++;
     if ( power  > power_last  ) 
     { if ( V_panels  > V_panels_last  )  {     duty_index--;  }
       else  {    duty_index++;     }    
     }
     else  
     { if ( V_panels  > V_panels_last  )  {     duty_index++;  }
       else
       {    duty_index--;       }    
     }
     V_panels_last = V_panels;     power_last =  power;
   }
   else
   {
      if ( amps_1 > AMPS [phase][amps_index]  ) { duty_index --;   }
      if ( amps_1 < AMPS [phase][amps_index]  ) { duty_index ++;   }
   }
   if ( amps_1 > AMPS_MAX [phase][amps_index]  )   {     duty_index--;  duty_index--;  }

   if ( duty_index <= 2  ) {   duty_index = 2;  }
   if ( duty_index >= duty_modulo  ) { duty_index = duty_modulo - 2; }
   
   mcpwm_set_duty(MCPWM_UNIT_1, MCPWM_TIMER_0, MCPWM_OPR_A, duty_0 [ duty_index % duty_modulo] );
   mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_B,  duty_0 [ duty_index % duty_modulo] );
   mcpwm_set_duty(MCPWM_UNIT_1, MCPWM_TIMER_1, MCPWM_OPR_A,  duty_1 [ duty_index % duty_modulo] );
   mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_1, MCPWM_OPR_B,  duty_1 [ duty_index % duty_modulo] );
   mcpwm_set_duty(MCPWM_UNIT_1, MCPWM_TIMER_2, MCPWM_OPR_A,  duty_2 [ duty_index % duty_modulo] );
   mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_2, MCPWM_OPR_B,  duty_2 [ duty_index % duty_modulo] );
   now = millis();
   if (now - previous > interval ) {
     previous = now;     num_of_intervals++;      wh = wh + p_in / 3600.0;    
     float max_temp = tempA [0].toFloat  ();     float max_temp_1 = tempA [1].toFloat  ();  
     if ( max_temp_1 > max_temp ) 
     {
       max_temp = max_temp_1;
     }     
     if  ( max_temp > 49.99 )    {     set_sd_LOW ();   }
     if  ( max_temp > 39.99 )    {     T_factor = 1.011;  }  
     if  ( ( max_temp < 39.99 ) &&  ( max_temp > 24.99 ) )    {    T_factor = 1.005;   }  
     if  ( max_temp < 24.99 )    {    T_factor = 0.985;  }
     if ( temp_algo  ) 
     {
       if ( max_temp > 26.0  ) { deltaPWM = deltaPWM + 3;  if ( deltaPWM > 220.0  )  deltaPWM = 220;      }
       dutyCycle1 = 32 + deltaPWM ;       dutyCycle2 = 32 + deltaPWM ;
       if (( max_temp < 24.0 ) &&  (max_temp > 22.0 )) 
       {
         deltaPWM = deltaPWM - 2;   if ( deltaPWM < 2  )  deltaPWM = 2;
       }
       ledcWrite(ledChannel_0, dutyCycle1);       ledcWrite(ledChannel_1, dutyCycle2);
     }
     if  ( mppt  ) 
     {
       if ( volts3 < V_OC * 0.77 )   {   duty_high ++;   }
       if ( duty_high > 10  )  { duty_index = duty_begin ;   duty_high = 0;   }
       if ( volts3 > V_OC * 0.966   )   {     duty_low ++;    }
       if ( duty_low > 10  )    {     duty_index = duty_begin;      duty_low = 0;     }
     } 
     if  (  (   num_of_intervals % 2  ) == 1 )
     {
        sprintf (x0, "%4.2f", amps0 );   x0[7] = {'\0'} ;   tempA [8] = String (amps0,2);
        sprintf (x1, "%4.2f", amps1 );   x1[7] = {'\0'} ;   tempA [2] = String (amps1,2);
        sprintf (x2, "%4.2f", amps1_0 );  x2[7] = {'\0'} ;  tempA [3] = String (amps1_0,2);
        sprintf (x3, "%3.2f", volts2 );   x3[7] = {'\0'} ;  tempA [5] = String (volts2,2);
        eta = p_out / (p_in+0.001 ) * 100.0;                tempA [7] = String (eta,2);
        lcd.setCursor(0,0);       lcd.print( x0 );       lcd.setCursor(0,1);       lcd.print( x1 );
        lcd.setCursor(0,2);       lcd.print( x2 );       lcd.setCursor(0,3);       lcd.print( x3 );
                                                            tempA [4] = String (amps_1,2);
        sprintf (x4, "%3.4f", volts3 );   x4[8] = {'\0'} ;  tempA [9] = String (volts3,2);
        sprintf (x5, "%3.1f", p_in );   x5[7] = {'\0'} ;    tempA [10] = String (p_in,2);
                                                            tempA [6] = String (p_out,2);  
                                                            tempA [11] = String ( wh,2);   
        lcd.setCursor(9,3);  lcd.print( x4 );    lcd.setCursor(18,3);   lcd.print( " V" ); lcd.setCursor(9,0);  lcd.print( x5 );
     }
     if  (  (   num_of_intervals % 4  ) == 1 )
     {   
        lcd.setCursor(9,1);      lcd.print( tempA [0]);        lcd.setCursor(9,2);      lcd.print( tempA [1]);
        lcd.setCursor(18,1);      lcd.print( " C" );
     }
     else if (  (   num_of_intervals % 4  ) == 3 )
     {
        sprintf (x8, "%3.1f", wh );   x8[8] = {'\0'} ;        sprintf (x9, "%3.3f", ( float )loop_interval/1000.0  );   x9[6] = {'\0'} ;
        lcd.setCursor(9,1);     lcd.print( x9 );        lcd.setCursor(9,3);      lcd.print( x8 ); 
        lcd.setCursor(18,3);      lcd.print( "Wh" );    lcd.setCursor(18,1);      lcd.print( "ms" );
     }
     events.send(getSensorReadings().c_str(),"new_readings" ,millis());
     if  (   num_of_intervals > 30  ) 
     { 
       if  (  (   num_of_intervals % 600  ) == 1 )   {     write_wh ();     }
       if  ( (   amps_1 < MIN_AMPS   ) &&  (   volts3 < min_panel_volts   ) )   
       {
          set_sd_LOW ();
       }
       if  ( (   !mppt   ) &&  (   volts3 < 50.11   ) )   
       {
         set_sd_LOW (); 
       }
       if  (  volts2 > max_volts   )  
       {
         max_volts_high++;
         if ( max_volts_high > 5  ) 
         {            
           max_volts_high = 0;    phase = 1;      num_of_intervals = 0;
         }
       }
       if ( (  volts2 > max_volts_slow )  && (  phase == 1 ) && (   num_of_intervals > 10  ) ) 
       {
          phase = 2;   num_of_intervals = 0;  
       }
       if ( (  volts2 > max_volts_float )  && (  phase == 2 )  && (   num_of_intervals > 10  ) )  
       {
          phase = 0;    lcd.setCursor(10,3);   lcd.print( sS_ST_BY );   set_sd_LOW ();    write_wh ();
       }
       if  ( (   amps_1 < MIN_AMPS   ) && ( volts2 < rebulk_volts ) &&  (  volts3 > min_panel_volts   ) ) 
         {
           phase = 0;           lcd.setCursor(10,3);           lcd.print( sF_BULK ); 
           V_IN = volts3; V_OC = V_IN;    V_OUT = volts2;
           for (int i=0; i < duty_modulo ; i++) {   
             if ( duty_0 [i] <  (float )(V_OUT / V_IN * 96.0 )) duty_index = i;
             }
             duty_index--;duty_index--;
             mcpwm_set_duty(MCPWM_UNIT_1, MCPWM_TIMER_0, MCPWM_OPR_A, duty_0 [ duty_index % duty_modulo] );
             mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_B,  duty_0 [ duty_index % duty_modulo] );
             mcpwm_set_duty(MCPWM_UNIT_1, MCPWM_TIMER_1, MCPWM_OPR_A,  duty_1 [ duty_index % duty_modulo] );
             mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_1, MCPWM_OPR_B,  duty_1 [ duty_index % duty_modulo] );
             mcpwm_set_duty(MCPWM_UNIT_1, MCPWM_TIMER_2, MCPWM_OPR_A,  duty_2 [ duty_index % duty_modulo] );
             mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_2, MCPWM_OPR_B,  duty_2 [ duty_index % duty_modulo] );
             digitalWrite ( SD_PIN, HIGH  );          digitalWrite ( SD_PIN2, HIGH  );
             num_of_intervals = 0;  
         }
     }
     if  (  currentTime - previousTime  > timeoutTime  ) 
     { 
        amps_index++; amps_index = amps_index % amps_modulo;        previousTime = currentTime;        currentTime = millis();
     }       
   }
   ws.cleanupClients();
}

/// made by Pavol Filek /*--*/
Este k tomu treba HTML kod na SPIFFS, ale ten sa tu vlozit neda.
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
Uživatelský avatar
rottenkiwi
Příspěvky: 5369
Registrován: pát úno 13, 2015 2:24 pm
Chci prodávat energii a využít dotace: ANO
Souhlasím s podmínkami fóra: NE
Bydliště: SO, SK

Re: DIY 3kW Arduino MPPT Solar Charge Controller ESP32

Příspěvek od rottenkiwi »

Viete niekto posudit, co je na tom dizajne DIY menicov dobre a co zle urobene ?

.
MPPT_DIY_01_06_23.jpg

.
DIY_INVERTER_01_06_2023.jpg
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
lzahradil
Site Admin
Příspěvky: 790
Registrován: ned srp 12, 2012 1:18 am
Lokalita: blízko Plzně
Chci prodávat energii a využít dotace: NE
Systémové napětí: 48V
Výkon panelů [Wp]: 5840
Kapacita baterie [kWh]: 28
Bydliště: CZ

Re: DIY 3kW Arduino MPPT Solar Charge Controller ESP32

Příspěvek od lzahradil »

Kondy u chladiče?
To jim moc na životnosti svědčit nebude
FVE 5,84kWp [Axpert 5048MK - LiFePO4 580Ah@48V (zatím) | 3x Axpert MSXE 2400W - NiCd 800Ah@24V]
Uživatelský avatar
rottenkiwi
Příspěvky: 5369
Registrován: pát úno 13, 2015 2:24 pm
Chci prodávat energii a využít dotace: ANO
Souhlasím s podmínkami fóra: NE
Bydliště: SO, SK

Re: DIY 3kW Arduino MPPT Solar Charge Controller ESP32

Příspěvek od rottenkiwi »

Cim budu kondy dalej od BJT, FET-ov, alebo IGBT, tym viac roboty budu
musiet robit + este bude treba dalsie mensie keramiky.
A tym bude vacsie EMI a neprejde to testom a nedostane sa to k zakaznikovi.

Potom aj VIctron to ma zle, kde to ma natrieskane v strede blizko chladicov
a s tym ventilatorikom 0.22 A / 12 V toho vela neuchladi.

https://www.youtube.com/watch?v=ISMpcy-wm44

V Quattrach to maju na druhej strane dosky.
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
FRSO
Příspěvky: 2129
Registrován: ned srp 14, 2011 10:13 pm

Re: DIY 3kW Arduino MPPT Solar Charge Controller ESP32

Příspěvek od FRSO »

rottenkiwi píše:Cim budu kondy dalej od BJT, FET-ov, alebo IGBT, tym viac roboty budu
musiet robit + este bude treba dalsie mensie keramiky.
A tym bude vacsie EMI a neprejde to testom a nedostane sa to k zakaznikovi.

Potom aj VIctron to ma zle, kde to ma natrieskane v strede blizko chladicov
a s tym ventilatorikom 0.22 A / 12 V toho vela neuchladi.

https://www.youtube.com/watch?v=ISMpcy-wm44

V Quattrach to maju na druhej strane dosky.
Tak dát taky ty kondíky z druhé strany :) V nových modelech victronů ofukuje ventilátor fetty, jinak by asi nevydržely trvalý výkon když nejsou na chladiči.
5,4 kWp JJZ, do 13.8.2022 bylo 3,6 kWp, MPII 5k, Victron MPPT 250/85-TR, aku 9,45 kWh Lion 15S, BMS 200A, Smart Shunt 500A.
Od 6 března 2022 vyrobeno k 9/6 1000 kWh, k 17/8 2000 kWH, k 1.10.2022 už 2500 kWH, k 27.12.2022 3000 kWh, k 14.3.2023 3500 kWh, k 16.4.2023 4000 kWh, k 19.6.2023 5000 kWh, k 21.8.2023 6000 kWh, k 20.9.2023 6387 kWh
Uživatelský avatar
rottenkiwi
Příspěvky: 5369
Registrován: pát úno 13, 2015 2:24 pm
Chci prodávat energii a využít dotace: ANO
Souhlasím s podmínkami fóra: NE
Bydliště: SO, SK

Re: DIY 3kW Arduino MPPT Solar Charge Controller ESP32

Příspěvek od rottenkiwi »

Prace na ESP32 DIY BOOST MPPT - 2-phase pokracuju dalej
skontrolovane IN, SD , COM pre obidva IR2184.

https://youtu.be/Oq4dqsNd0P0
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
Uživatelský avatar
rottenkiwi
Příspěvky: 5369
Registrován: pát úno 13, 2015 2:24 pm
Chci prodávat energii a využít dotace: ANO
Souhlasím s podmínkami fóra: NE
Bydliště: SO, SK

Re: DIY 3kW Arduino MPPT Solar Charge Controller ESP32

Příspěvek od rottenkiwi »

Prva faza ESP32 DIY BOOST MPPT otestovana, idem pridat druhu.

https://youtu.be/_MS4t6KTnJQ
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
Uživatelský avatar
rottenkiwi
Příspěvky: 5369
Registrován: pát úno 13, 2015 2:24 pm
Chci prodávat energii a využít dotace: ANO
Souhlasím s podmínkami fóra: NE
Bydliště: SO, SK

Re: DIY 3kW Arduino MPPT Solar Charge Controller ESP32

Příspěvek od rottenkiwi »

AKo z tychto hodnot Vin a Vout a delta I in pre BOOST DC-DC spocitat DUTY_CYCLE pre PWM pre jednu fazu ?

.
boost_tab_02062023.png
.
graph_boost_02062023.png
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
Uživatelský avatar
rottenkiwi
Příspěvky: 5369
Registrován: pát úno 13, 2015 2:24 pm
Chci prodávat energii a využít dotace: ANO
Souhlasím s podmínkami fóra: NE
Bydliště: SO, SK

Re: DIY 3kW Arduino MPPT Solar Charge Controller ESP32

Příspěvek od rottenkiwi »

Meranie ucinnosti jednofazoveho BOOST MPPT, priblizne / UNI-T / , lebo nie su ACS758.

https://youtu.be/RCbVICU1k_E
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
Uživatelský avatar
rottenkiwi
Příspěvky: 5369
Registrován: pát úno 13, 2015 2:24 pm
Chci prodávat energii a využít dotace: ANO
Souhlasím s podmínkami fóra: NE
Bydliště: SO, SK

Re: DIY 3kW Arduino MPPT Solar Charge Controller ESP32

Příspěvek od rottenkiwi »

Snazim sa dostat k ucinnosti, ale neviem kde je problem, podla grafu A OUT, V IN, V OUT
je merane +- 0.003 A / V, A IN +- 0.01 A.
ale ucinnost poskakuje velmi nepresne od 97.5 do 99.5 %.

.
BOOST_eff_measure_I.png
.
BOOST_ETA_I.png
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
Uživatelský avatar
rottenkiwi
Příspěvky: 5369
Registrován: pát úno 13, 2015 2:24 pm
Chci prodávat energii a využít dotace: ANO
Souhlasím s podmínkami fóra: NE
Bydliště: SO, SK

Re: DIY 3kW Arduino MPPT Solar Charge Controller ESP32

Příspěvek od rottenkiwi »

6 hodin zbytocneho pajkovania pre 2 pochybne suciastky, po vymene to slapalo
OK, len este treba vycizelovat ten druhy ACS senzor.

Efficiency at LCD:

https://youtu.be/YZF76qklNRI
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
Uživatelský avatar
rottenkiwi
Příspěvky: 5369
Registrován: pát úno 13, 2015 2:24 pm
Chci prodávat energii a využít dotace: ANO
Souhlasím s podmínkami fóra: NE
Bydliště: SO, SK

Re: DIY 3kW Arduino MPPT Solar Charge Controller ESP32

Příspěvek od rottenkiwi »

Merania efficiencie su konzistentne, teraz len zistit, ktora z hodnot
A IN, A OUT, V IN, V OUT je najmenej presna a ci eta nedriftuje
s teplotou ADS1115 ACS758 a ACS712.

Efficiency I:

https://youtu.be/R2v3eIuC4hc

Efficiency II:

https://youtu.be/aR1ifdrt1LM

.
BOOST_efficiency_04062023.jpg
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
Uživatelský avatar
rottenkiwi
Příspěvky: 5369
Registrován: pát úno 13, 2015 2:24 pm
Chci prodávat energii a využít dotace: ANO
Souhlasím s podmínkami fóra: NE
Bydliště: SO, SK

Re: DIY 3kW Arduino MPPT Solar Charge Controller ESP32

Příspěvek od rottenkiwi »

Uz su tie merania ucinnosti presnejsie:


.
BOOST_efficiency_04062023_II.png
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
Uživatelský avatar
rottenkiwi
Příspěvky: 5369
Registrován: pát úno 13, 2015 2:24 pm
Chci prodávat energii a využít dotace: ANO
Souhlasím s podmínkami fóra: NE
Bydliště: SO, SK

Re: DIY 3kW Arduino MPPT Solar Charge Controller ESP32

Příspěvek od rottenkiwi »

BOOST MPPT / CHARGER
CONSTANT CURRENT ALGO 3.000 AMPS:

https://youtu.be/SarqM8d6rZc
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
kodl69
podporuje fórum
Příspěvky: 7060
Registrován: sob črc 19, 2014 8:56 pm

Re: DIY 3kW Arduino MPPT Solar Charge Controller ESP32

Příspěvek od kodl69 »

nějak nevím, co tam zobrazuješ, nějak chybí popis osy x a té druhé y...
Tím, že účinnost je (U1*I1)/(U2/I2) tak se ti násobí nepřesnosti, tj pokud bys dokáazl měřit s přesností 1% proudy i napětí, tak na výkonu to bude 1.01*1.01=1.02 tj 2% a když tyhle hodnoty podělíš, tak může být nepřesnost zrovna ty 4% o který ti to skákalo. Tj nějak extra bych se s tím nezalamoval, když vlastně ani nevíš, jak ti přesnost měření ovlivNuje např vf rušení nebo nelineární průběhy napětí a proudu...
ostrov 4600Wp neustále ve stádiu zrodu: midnite classic 150 lite+whizbang jr., 16S a různě P cca 300Ah Winston, Ex Powerjack 8kW (momentálně samodomo cca 6kW). 48V DC rozvody a spotřebiče.
Uživatelský avatar
rottenkiwi
Příspěvky: 5369
Registrován: pát úno 13, 2015 2:24 pm
Chci prodávat energii a využít dotace: ANO
Souhlasím s podmínkami fóra: NE
Bydliště: SO, SK

Re: DIY 3kW Arduino MPPT Solar Charge Controller ESP32

Příspěvek od rottenkiwi »

Vlavo je osa pre ucinnost, eta I a eta II, ta druha je korigovana na zmeny teploty.
Osa X nema popis, lebo tam nie je ziadna hodnota.

Vpravo su AMPERE IN pre BOOST DC-DC merane ACS712, lebo som tam vcera
dal ACS758 a bol chybny, tak som stravil 6 hodin hladanim chyby, akurat, ze
ACS712 nevydrzia narazove prudy 1200 A, co pri 25 *C ACS758 vydrzi.

Nemam cim skontrolovat linearitu napati a prudov, to uz treba na 0.0005 A / V.

Nemam suciastky, tak dalsiu fazu dorobim az o mesiac.
Len si musim este dostudovat BOOST converter a potom
ked to pojde, tak skusim FLYBACK.

U BOOST je moznost COUPLED a INVERSE COUPLED inductor.
Ale to by som si musel navinut sam.

TEST CC 4.000 A.

https://youtu.be/HeHPKhHYapY
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
Uživatelský avatar
rottenkiwi
Příspěvky: 5369
Registrován: pát úno 13, 2015 2:24 pm
Chci prodávat energii a využít dotace: ANO
Souhlasím s podmínkami fóra: NE
Bydliště: SO, SK

Re: DIY 3kW Arduino MPPT Solar Charge Controller ESP32

Příspěvek od rottenkiwi »

Otestoval som BOOST na 4.4 - 4.5 A / 41 V OUT
a dalej sa neviem dostat, lebo mam len STPS3045CW, na 45 V max.

https://youtu.be/ph0lEemPAAM
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
Uživatelský avatar
gupa
Příspěvky: 1963
Registrován: sob pro 29, 2012 10:22 pm
Lokalita: pod Brnem
Chci prodávat energii a využít dotace: NE
Systémové napětí: 24V
Souhlasím s podmínkami fóra: ANO

Re: DIY 3kW Arduino MPPT Solar Charge Controller ESP32

Příspěvek od gupa »

rottenkiwi píše:
Dnes sa robia GaN menice 60 A na 3 MHz to spina a ma to plochu 25 x 18 mm.
Strasna hustota energie na palec.
Myslíš modulární přelévačku něco jako toto?

https://www.youtube.com/watch?v=dAgw88cUD6c
3x2000VA-VMP-par, NiCd 24V, 22x210-320Wp, 2x85A-VMPPT
Uživatelský avatar
gupa
Příspěvky: 1963
Registrován: sob pro 29, 2012 10:22 pm
Lokalita: pod Brnem
Chci prodávat energii a využít dotace: NE
Systémové napětí: 24V
Souhlasím s podmínkami fóra: ANO

Re: DIY 3kW Arduino MPPT Solar Charge Controller ESP32

Příspěvek od gupa »

rottenkiwi píše:Otestoval som BOOST na 4.4 - 4.5 A / 41 V OUT
a dalej sa neviem dostat, lebo mam len STPS3045CW, na 45 V max.
Na deskách v plazmové televizi jsou RF2001 na 200V 20A.
3x2000VA-VMP-par, NiCd 24V, 22x210-320Wp, 2x85A-VMPPT
Uživatelský avatar
rottenkiwi
Příspěvky: 5369
Registrován: pát úno 13, 2015 2:24 pm
Chci prodávat energii a využít dotace: ANO
Souhlasím s podmínkami fóra: NE
Bydliště: SO, SK

Re: DIY 3kW Arduino MPPT Solar Charge Controller ESP32

Příspěvek od rottenkiwi »

CO vsetko potrebujem na takyto Double Pulse Test , ak mam FET-y 0 - 600 V
a frekvenciu 10 kHz - 150 kHz ?

.
double_pulser_I.png
.
double_pulse_II.png
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.

Zpět na