общее
/**
pinMode(32, OUTPUT); // Устанавливаем пин 32 как выход
digitalWrite(32, HIGH); // Установить пин в HIGH (плюс, 3.3 В)
digitalWrite(32, LOW); // Установить пин в LOW (минус, 0 В)
char big_data[60000] = "val="; //Объявляет большой буфер и задаёт начальное значение
sprintf(...) //Добавляет в конец форматированную строку
memset(big_data, 0, sizeof(big_data)); //Обнуляет (очищает) строку
strcat(big_data, "val="); //Снова начинает строку с "val=" после очистки
char letter = 'X';
int number = 42;
float temp = 23.4567;
char name[] = "ESP32";
char buffer[100];
sprintf(buffer, "Char: %c, Int: %d, Float: %.2f, String: %s", letter, number, temp, name);
float some_data = %.2f
millis() = %d
String name = "ESP32";
sprintf(buffer, "Name: %s", name.c_str());
String name = "ESP32";
name.reserve(5000); // резервируем память для предотвращения фрагментации!
*/
#include
#include
#include
#include
#include // для memset
String big_data = ""; // данные для отправки
int loop_counter = 0;
int responseLength = 0; // для подсчета длины ответа
// 7025 *************************
HardwareSerial mppt_uart(2); // 16 и 17 пины
byte response_array_mppt[512]; // массив байтов ответа
String vout;
String iout;
String power_out;
String vin;
String ah_total;
String wh_total;
String inner_temp;
// 7025(2) *************************
byte response_array_mppt2[512]; // массив байтов ответа
String vout2;
String iout2;
String power_out2;
String vin2;
String ah_total2;
String wh_total2;
String inner_temp2;
// BMS *******************
HardwareSerial bms_uart(1); // 18 19 пины
byte response_array_bms[512]; // массив байтов ответа
int b1_int;
int b2_int;
int b3_int;
int b4_int;
String b1;
String b2;
String b3;
String b4;
String total_voltage;
String current;
String soc;
String battery_temp;
String mosfet_temp;
String discharging_on_off;
String charging_on_off;
String bms_mosfet_status;
String bms_cycle;
///////// scatch_status
int relay_scatch_status = 1;
int mosfet_scatch_status = 1;
int turn_on_trigger = 3250; // по умолчанию включать при ячейке 3.25 вольта
int turn_off_trigger = 3100; // по умолчанию выключать при ячейке 3.1 вольта
byte ask_new_amp[8]; // глобальный массив фиксированной длины
void wifi_connection(){
WiFi.begin("netis_kitchen", "password");
//WiFi.begin("netis_7AB60F", "password");
//WiFi.begin("netis_2.4G_007C9D", "d11v09n03");
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
WiFi.setHostname("solar_esp");
Serial.print("OK! IP=");
Serial.println(WiFi.localIP());
}
void set_var_null(){
b1="";
b2="";
b3="";
b4="";
total_voltage="";
current="";
soc="";
battery_temp="";
mosfet_temp="";
discharging_on_off="";
charging_on_off="";
vout2="";
iout2="";
power_out2="";
vin2="";
ah_total2="";
wh_total2="";
inner_temp2="";
vout="";
iout="";
power_out="";
vin="";
ah_total="";
wh_total="";
inner_temp="";
bms_mosfet_status="";
bms_cycle = "";
//////
memset(response_array_mppt, 0, sizeof(response_array_mppt));
memset(response_array_mppt2, 0, sizeof(response_array_mppt2));
memset(response_array_bms, 0, sizeof(response_array_bms));
}
void send_http(){
Serial.println("send_http_func");
//Serial.println(big_data);
// Указываем URL и данные для POST запроса
HTTPClient http;
http.begin("https://fuguja.com/esp/solar/solar.php");
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
// Отправляем POST запрос
float httpResponseCode = http.POST(big_data);
String payload;
if (httpResponseCode == 200) {
payload = http.getString();
}
StaticJsonDocument<400> doc;
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.print("Ошибка разбора JSON: ");
Serial.println(error.c_str());
} else {
Serial.print("запись jsona: "+payload);
turn_off_trigger = doc["new_trigger_off"];
turn_on_trigger = doc["new_trigger_on"];
}
Serial.println("turn_off_trigger: "+String(turn_off_trigger));
Serial.println("turn_on_trigger: "+String(turn_on_trigger));
http.end();
big_data = "val=";
}
void on_off_relay_mosfet(int turn_r_m){
/*
pinMode(32, OUTPUT); // пин реле
pinMode(33, OUTPUT); // пин мосфета
on_off_relay_mosfet(1)
turn_r_m == 1 работа от солнца: на пин мосфета подаем минус для его открытия, на пин реле минус для отключения розетки
on_off_relay_mosfet(0)
turn_r_m == 0 работа от сети: на пин мосфета подаем плюс, и на реле плюс
*/
if(turn_r_m == 1){
digitalWrite(32, LOW); // выключить реле
digitalWrite(33, LOW); // включить мосфет
relay_scatch_status = 0;
mosfet_scatch_status = 1;
} else if(turn_r_m == 0){
digitalWrite(32, HIGH); // включить реле
delay(5000);
digitalWrite(33, HIGH); // выключить мосфет
relay_scatch_status = 1;
mosfet_scatch_status = 0;
}
}
void setup() {
bms_uart.begin(115200, SERIAL_8N1, 18, 19);
mppt_uart.begin(115200, SERIAL_8N1, 16, 17);
Serial.begin(115200);
big_data.reserve(100000); // резервируем 5000 бит
big_data = "val=";
// mppt:
vout.reserve(10);
iout.reserve(10);
power_out.reserve(10);
vin.reserve(10);
ah_total.reserve(10);
wh_total.reserve(10);
inner_temp.reserve(10);
// mppt2:
vout2.reserve(10);
iout2.reserve(10);
power_out2.reserve(10);
vin2.reserve(10);
ah_total2.reserve(10);
wh_total2.reserve(10);
inner_temp2.reserve(10);
// bms:
b1.reserve(10);
b2.reserve(10);
b3.reserve(10);
b4.reserve(10);
total_voltage.reserve(10);
current.reserve(10);
soc.reserve(10);
battery_temp.reserve(10);
mosfet_temp.reserve(10);
discharging_on_off.reserve(10);
charging_on_off.reserve(10);
bms_mosfet_status.reserve(10);
bms_cycle.reserve(10);
delay(1000);
wifi_connection();
pinMode(32, OUTPUT); // пин реле
pinMode(33, OUTPUT); // пин мосфета
on_off_relay_mosfet(1);
delay(1000);
}
void mppt_set_new_amp(int amp){
if(amp <= 0 && amp > 50){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x00, 0x00, 0xd8, 0x0a }; } // 0 A
elseif(amp <= 50 && amp > 100){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x00, 0x32, 0x59, 0xdf }; } // 50 A
elseif(amp <= 100 && amp > 150){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x00, 0x64, 0xd9, 0xe1 }; } // 100 A
elseif(amp <= 150 && amp > 200){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x00, 0x96, 0x58, 0x64 }; } // 150 A
elseif(amp <= 200 && amp > 250){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x00, 0xc8, 0xd9, 0x9c }; } // 200 A
elseif(amp <= 250 && amp > 300){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x00, 0xfa, 0x58, 0x49 }; } // 250 A
elseif(amp <= 300 && amp > 350){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x01, 0x2c, 0xd8, 0x47 }; } // 300 A
elseif(amp <= 350 && amp > 400){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x01, 0x5e, 0x58, 0x62 }; } // 350 A
elseif(amp <= 400 && amp > 450){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x01, 0x90, 0xd9, 0xf6 }; } // 400 A
elseif(amp <= 450 && amp > 500){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x01, 0xc2, 0x58, 0x0b }; } // 450 A
elseif(amp <= 500 && amp > 550){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x01, 0xf4, 0xd8, 0x1d }; } // 500 A
elseif(amp <= 550 && amp > 600){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x02, 0x26, 0x58, 0xb0 }; } // 550 A
elseif(amp <= 600 && amp > 650){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x02, 0x58, 0xd8, 0x90 }; } // 600 A
elseif(amp <= 650 && amp > 700){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x02, 0x8a, 0x58, 0xcd }; } // 650 A
elseif(amp <= 700 && amp > 750){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x02, 0xbc, 0xd8, 0xdb }; } // 700 A
elseif(amp <= 750 && amp > 800){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x02, 0xee, 0x59, 0x26 }; } // 750 A
elseif(amp <= 800 && amp > 850){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x03, 0x20, 0xd9, 0x22 }; } // 800 A
elseif(amp <= 850 && amp > 900){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x03, 0x52, 0x59, 0x07 }; } // 850 A
elseif(amp <= 900 && amp > 950){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x03, 0x84, 0xd8, 0x99 }; } // 900 A
elseif(amp <= 950 && amp > 1000){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x03, 0xb6, 0x59, 0x4c }; } // 950 A
elseif(amp <= 1000 && amp > 1050){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x03, 0xe8, 0xd8, 0xb4 }; } // 1000 A
elseif(amp <= 1050 && amp > 1100){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x04, 0x1a, 0x5b, 0x01 }; } // 1050 A
elseif(amp <= 1100 && amp > 1150){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x04, 0x4c, 0xdb, 0x3f }; } // 1100 A
elseif(amp <= 1150 && amp > 1200){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x04, 0x7e, 0x5a, 0xea }; } // 1150 A
elseif(amp <= 1200 && amp > 1250){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x04, 0xb0, 0xdb, 0x7e }; } // 1200 A
elseif(amp <= 1250 && amp > 1300){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x04, 0xe2, 0x5a, 0x83 }; } // 1250 A
elseif(amp <= 1300 && amp > 1350){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x05, 0x14, 0xdb, 0x55 }; } // 1300 A
elseif(amp <= 1350 && amp > 1400){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x05, 0x46, 0x5a, 0xa8 }; } // 1350 A
elseif(amp <= 1400 && amp > 1450){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x05, 0x78, 0xdb, 0x78 }; } // 1400 A
elseif(amp <= 1450 && amp > 1500){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x05, 0xaa, 0x5b, 0x25 }; } // 1450 A
elseif(amp <= 1500 && amp > 1550){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x05, 0xdc, 0xda, 0xc3 }; } // 1500 A
elseif(amp <= 1550 && amp > 1600){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x06, 0x0e, 0x5a, 0x6e }; } // 1550 A
elseif(amp <= 1600 && amp > 1650){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x06, 0x40, 0xda, 0x5a }; } // 1600 A
elseif(amp <= 1650 && amp > 1700){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x06, 0x72, 0x5b, 0x8f }; } // 1650 A
elseif(amp <= 1700 && amp > 1750){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x06, 0xa4, 0xda, 0x11 }; } // 1700 A
elseif(amp <= 1750 && amp > 1800){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x06, 0xd6, 0x5a, 0x34 }; } // 1750 A
elseif(amp <= 1800 && amp > 1850){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x07, 0x08, 0xdb, 0xfc }; } // 1800 A
elseif(amp <= 1850 && amp > 1900){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x07, 0x3a, 0x5a, 0x29 }; } // 1850 A
elseif(amp <= 1900 && amp > 1950){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x07, 0x6c, 0xda, 0x17 }; } // 1900 A
elseif(amp <= 1950 && amp > 2000){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x07, 0x9e, 0x5b, 0x92 }; } // 1950 A
elseif(amp <= 2000 && amp > 2050){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x07, 0xd0, 0xdb, 0xa6 }; } // 2000 A
elseif(amp <= 2050 && amp > 2100){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x08, 0x02, 0x5e, 0x0b }; } // 2050 A
elseif(amp <= 2100 && amp > 2150){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x08, 0x34, 0xde, 0x1d }; } // 2100 A
elseif(amp <= 2150 && amp > 2200){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x08, 0x66, 0x5f, 0xe0 }; } // 2150 A
elseif(amp <= 2200 && amp > 2250){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x08, 0x98, 0xde, 0x60 }; } // 2200 A
elseif(amp <= 2250 && amp > 2300){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x08, 0xca, 0x5f, 0x9d }; } // 2250 A
elseif(amp <= 2300 && amp > 2350){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x08, 0xfc, 0xdf, 0x8b }; } // 2300 A
elseif(amp <= 2350 && amp > 2400){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x09, 0x2e, 0x5e, 0x46 }; } // 2350 A
elseif(amp <= 2400 && amp > 2450){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x09, 0x60, 0xde, 0x72 }; } // 2400 A
elseif(amp <= 2450 && amp > 2500){ byte local_ask_amp[] = { 0x01, 0x06, 0x00, 0x01, 0x09, 0x92, 0x5f, 0xf7 }; } // 2450 A
memset(ask_new_amp, 0, 8); // чистим глобальній массив
memcpy(ask_new_amp, local_ask_amp, 8); // присваиваем к глобальному массиву
// ask_new_amp;
// memset(ask_amp, 0, sizeof(ask_amp)); // заполняем нулями
// byte temp[] = { 0x01, 0x06, 0x00, 0x01, 0x09, 0x92, 0x5F, 0xF7 };
// memcpy(buffer, temp, 8);
}
void loop() {
Serial.println(loop_counter);
loop_counter++;
set_var_null();
// после 10 запросов отправка
if(loop_counter == 10){
send_http(); // отправка
loop_counter = 0;
}
///////////////////////////////////////////////////
// mppt ask
byte ask_mppt[] = { 0x01, 0x03, 0x00, 0x02, 0x00, 0x0D, 0x25, 0xCF };
// цикл опроса
for(int i=0; i<=8; i++){
mppt_uart.write(ask_mppt, sizeof(ask_mppt));
delay(300);
responseLength = 0;
while (mppt_uart.available()) {
byte b_mppt = mppt_uart.read();
if (responseLength < sizeof(response_array_mppt)){
response_array_mppt[responseLength++] = b_mppt; // запись битов в массив
}
}
if(response_array_mppt[0]){ i=10; }
else { delay(300); }
}
// переключение пинов
delay(500);
mppt_uart.end();
mppt_uart.begin(115200, SERIAL_8N1, 22, 23);
delay(500);
//////
for(int i=0; i<=8; i++){
mppt_uart.write(ask_mppt, sizeof(ask_mppt));
delay(300); // даём mppt время ответить
responseLength = 0;
while (mppt_uart.available()) {
byte b_mppt2 = mppt_uart.read();
if (responseLength < sizeof(response_array_mppt2)){
response_array_mppt2[responseLength++] = b_mppt2; // запись битов в массив
}
}
if(response_array_mppt2[0]){ i=10; }
else { delay(300); }
}
// переключение пинов:
delay(500);
mppt_uart.end();
mppt_uart.begin(115200, SERIAL_8N1, 16, 17);
delay(500);
// bms ask
for(int i=0; i<=8; i++){
byte ask_bms[] = { 0x4E, 0x57, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x01, 0x29 };
bms_uart.write(ask_bms, sizeof(ask_bms));
delay(300); // даём BMS время ответить
responseLength = 0;
while (bms_uart.available()) {
byte b_bms = bms_uart.read();
if (responseLength < sizeof(response_array_bms)) {
response_array_bms[responseLength++] = b_bms;
}
}
if(response_array_bms[0]){ i=10; }
else { delay(300); }
}
/////////////////////////////////******************
// mppt result:
vout = String((response_array_mppt[3] << 8) | response_array_mppt[4]); // дели на 100
iout = String((response_array_mppt[5] << 8) | response_array_mppt[6]); // дели на 100
power_out = String((response_array_mppt[7] << 8) | response_array_mppt[8]); // трехзнач дели на 100
vin = String((response_array_mppt[9] << 8) | response_array_mppt[10]);
ah_total = String((response_array_mppt[13] << 24) | (response_array_mppt[14] << 16) | (response_array_mppt[11] << 8) | response_array_mppt[12]);
wh_total = String((response_array_mppt[17] << 24) | (response_array_mppt[18] << 16) | (response_array_mppt[15] << 8) | response_array_mppt[16]);
inner_temp = String((response_array_mppt[25] << 8) | response_array_mppt[26]);
// mppt2 result:
vout2 = String((response_array_mppt2[3] << 8) | response_array_mppt2[4]); // дели на 100
iout2 = String((response_array_mppt2[5] << 8) | response_array_mppt2[6]); // дели на 100
power_out2 = String((response_array_mppt2[7] << 8) | response_array_mppt2[8]); // трехзнач дели на 100
vin2 = String((response_array_mppt2[9] << 8) | response_array_mppt2[10]);
ah_total2 = String((response_array_mppt2[13] << 24) | (response_array_mppt2[14] << 16) | (response_array_mppt2[11] << 8) | response_array_mppt2[12]);
wh_total2 = String((response_array_mppt2[17] << 24) | (response_array_mppt2[18] << 16) | (response_array_mppt2[15] << 8) | response_array_mppt2[16]);
inner_temp2 = String((response_array_mppt2[25] << 8) | response_array_mppt2[26]);
// bms result:
b1_int = (response_array_bms[14] << 8) | response_array_bms[15]; // 14 значит 15 и 16
b2_int = (response_array_bms[17] << 8) | response_array_bms[18]; // 16 значит 17 и 18
b3_int = (response_array_bms[20] << 8) | response_array_bms[21]; // 19 значит 20 и 21
b4_int = (response_array_bms[23] << 8) | response_array_bms[24]; // 22 значит 23 и 24
b1 = String(b1_int); // 14 значит 15 и 16
b2 = String(b2_int); // 16 значит 17 и 18
b3 = String(b3_int); // 19 значит 20 и 21
b4 = String(b4_int); // 22 значит 23 и 24
total_voltage = String((response_array_bms[35] << 8) | response_array_bms[36]); // 83 | 34 значит 35 и 36
current = String((response_array_bms[38] << 8) | response_array_bms[39]); // 84 ячейка | 37 номер массива (38 39)
soc = String(response_array_bms[41]); // 85 | 40 номер массива (41);
battery_temp = String((response_array_bms[32] << 8) | response_array_bms[33]); // 82 | 31 номер массива (32 33)
mosfet_temp = String((response_array_bms[26] << 8) | response_array_bms[27]); // 80 | 25 (26 b 27)
discharging_on_off = String(response_array_bms[151]); // AC (discharge)
charging_on_off = String(response_array_bms[149]); // AB (charge)
bms_mosfet_status = String((response_array_bms[59] << 8) | response_array_bms[60]); // 8C - 58 ячейка, 59 60 данные
bms_cycle = String((response_array_bms[45] << 8) | response_array_bms[46]); // 87 - 44 ячейка, 45 46 данные
if(b1_int < turn_off_trigger || b2_int < turn_off_trigger || b3_int < turn_off_trigger || b4_int < turn_off_trigger){
// отключение солнца, включение сети:
Serial.println("off solar");
on_off_relay_mosfet(0);
} else if(b1_int < turn_on_trigger || b2_int < turn_on_trigger || b3_int < turn_on_trigger || b4_int < turn_on_trigger){
// включение солнца:
Serial.println("on solar");
on_off_relay_mosfet(1);
}
big_data += "{my_mos:"+String(mosfet_scatch_status)+"my_relay:"+String(relay_scatch_status)+"trigger_on:"+String(turn_on_trigger)+"trigger_off:"+String(turn_off_trigger)+
"vout:"+vout+"iout:"+iout+"pout:"+power_out+"vin:"+vin+"ah:"+ah_total+"wh:"+wh_total+"mppt_t:"+inner_temp+
"vout2:"+vout2+"iout2:"+iout2+"pout2:"+power_out2+"vin2:"+vin2+"ah2:"+ah_total2+"wh2:"+wh_total2+"mppt_t2:"+inner_temp2+
"b1:"+b1+"b2:"+b2+"b3:"+b3+"b4:"+b4+"v:"+total_voltage+"c:"+current+"soc:"+soc+"out_t:"+battery_temp+"bms_t:"+mosfet_temp+"cy:"+bms_cycle+"mos_st:"+bms_mosfet_status+"dch:"+discharging_on_off+"ch:"+charging_on_off+"wf:"+String(WiFi.RSSI())+"ms:"+String(millis())+"}";
delay(5000); // 10 секунд пауза перед следующим запросом
}
22.05.2025; 14:58
хиты: 20
рейтинг:0
|
|
|