397 lines
8.2 KiB
C
397 lines
8.2 KiB
C
const int maxSize = 60; // Taille du tableau
|
|
|
|
//--------------------------- SETUP -------------------------------------
|
|
|
|
#define MPPT_100_20 // Define used Victron Device
|
|
|
|
// Supported:
|
|
// "MPPT 75 | 10"
|
|
// "MPPT 75 | 15" tested with FW 1.56
|
|
// "MPPT 100 | 20" tested with FW 1.5 / 1.56
|
|
// "MPPT 100 | 30" tested with FW 1.59
|
|
|
|
//--------------------------- SETUP -------------------------------------
|
|
|
|
|
|
|
|
// MPPT 75 | 10
|
|
#ifdef MPPT_75_10
|
|
#define MAX_AMPERAGE 10
|
|
|
|
const byte buffsize = 32;
|
|
const byte value_bytes = 33;
|
|
const byte label_bytes = 9;
|
|
const byte num_keywords = 18;
|
|
|
|
char keywords[num_keywords][label_bytes] = {
|
|
"PID",
|
|
"FW",
|
|
"SER#",
|
|
"V",
|
|
"I",
|
|
"VPV",
|
|
"PPV",
|
|
"CS",
|
|
"ERR",
|
|
"LOAD",
|
|
"IL",
|
|
"H19",
|
|
"H20",
|
|
"H21",
|
|
"H22",
|
|
"H23",
|
|
"HSDS",
|
|
"Checksum"
|
|
};
|
|
#define PID 0
|
|
#define FW 1
|
|
#define SER 2 // Offically SER# but # does not play that well as macro
|
|
#define V 3 // ScV
|
|
#define I 4 // ScI
|
|
#define VPV 5 // PVV
|
|
#define PPV 6 // PVI = PVV / VPV
|
|
#define CS 7 // ScS
|
|
#define ERR 8 // ScERR
|
|
#define LOAD 9 // SLs
|
|
#define IL 10 // SLI
|
|
#define H19 11
|
|
#define H20 12
|
|
#define H21 13
|
|
#define H22 14
|
|
#define H23 15
|
|
#define HSDS 16
|
|
#define CHECKSUM 17
|
|
#endif
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
// MPPT 75 | 15
|
|
#ifdef MPPT_75_15
|
|
#define MAX_AMPERAGE 15
|
|
|
|
const byte buffsize = 32;
|
|
const byte value_bytes = 33;
|
|
const byte label_bytes = 9;
|
|
const byte num_keywords = 19;
|
|
|
|
char keywords[num_keywords][label_bytes] = {
|
|
"PID",
|
|
"FW",
|
|
"SER#",
|
|
"V",
|
|
"I",
|
|
"VPV",
|
|
"PPV",
|
|
"CS",
|
|
"MPPT",
|
|
"ERR",
|
|
"LOAD",
|
|
"IL",
|
|
"H19",
|
|
"H20",
|
|
"H21",
|
|
"H22",
|
|
"H23",
|
|
"HSDS",
|
|
"Checksum"
|
|
};
|
|
#define PID 0
|
|
#define FW 1
|
|
#define SER 2 // Offically SER# but # does not play that well as macro
|
|
#define V 3 // ScV
|
|
#define I 4 // ScI
|
|
#define VPV 5 // PVV
|
|
#define PPV 6 // PVI = PVV / VPV
|
|
#define CS 7 // ScS
|
|
#define MPPT 8
|
|
#define ERR 9 // ScERR
|
|
#define LOAD 10 // SLs
|
|
#define IL 11 // SLI
|
|
#define H19 12
|
|
#define H20 13
|
|
#define H21 14
|
|
#define H22 15
|
|
#define H23 16
|
|
#define HSDS 17
|
|
#define CHECKSUM 18
|
|
#endif
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
// MPPT 100 | 20
|
|
#ifdef MPPT_100_20
|
|
#define MAX_AMPERAGE 20
|
|
|
|
const byte buffsize = 32;
|
|
const byte value_bytes = 33;
|
|
const byte label_bytes = 9;
|
|
const byte num_keywords = 20;
|
|
|
|
char keywords[num_keywords][label_bytes] = {
|
|
"PID",
|
|
"FW",
|
|
"SER#",
|
|
"V",
|
|
"I",
|
|
"VPV",
|
|
"PPV",
|
|
"CS",
|
|
"MPPT",
|
|
"OR",
|
|
"ERR",
|
|
"LOAD",
|
|
"IL",
|
|
"H19",
|
|
"H20",
|
|
"H21",
|
|
"H22",
|
|
"H23",
|
|
"HSDS",
|
|
"Checksum"
|
|
};
|
|
#define PID 0
|
|
#define FW 1
|
|
#define SER 2
|
|
#define V 3
|
|
#define I 4
|
|
#define VPV 5
|
|
#define PPV 6
|
|
#define MPPT 7
|
|
#define OR 8
|
|
#define CS 9
|
|
#define ERR 10
|
|
#define LOAD 11
|
|
#define IL 12
|
|
#define H19 13
|
|
#define H20 14
|
|
#define H21 15
|
|
#define H22 16
|
|
#define H23 17
|
|
#define HSDS 18
|
|
#define CHECKSUM 19
|
|
#endif
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
// MPPT 100 | 30
|
|
#ifdef MPPT_100_30
|
|
#define MAX_AMPERAGE 30
|
|
|
|
const byte buffsize = 32;
|
|
const byte value_bytes = 33;
|
|
const byte label_bytes = 9;
|
|
const byte num_keywords = 20;
|
|
|
|
char keywords[num_keywords][label_bytes] = {
|
|
"PID",
|
|
"FW",
|
|
"SER#",
|
|
"V",
|
|
"I",
|
|
"VPV",
|
|
"PPV",
|
|
"CS",
|
|
"MPPT",
|
|
"OR",
|
|
"ERR",
|
|
"LOAD",
|
|
"IL",
|
|
"H19",
|
|
"H20",
|
|
"H21",
|
|
"H22",
|
|
"H23",
|
|
"HSDS",
|
|
"Checksum"
|
|
};
|
|
#define PID 0
|
|
#define FW 1
|
|
#define SER 2
|
|
#define V 3
|
|
#define I 4
|
|
#define VPV 5
|
|
#define PPV 6
|
|
#define MPPT 7
|
|
#define OR 8
|
|
#define CS 9
|
|
#define ERR 10
|
|
#define LOAD 11
|
|
#define IL 12
|
|
#define H19 13
|
|
#define H20 14
|
|
#define H21 15
|
|
#define H22 16
|
|
#define H23 17
|
|
#define HSDS 18
|
|
#define CHECKSUM 19
|
|
|
|
#endif
|
|
|
|
struct ErrorCode {
|
|
const char* code;
|
|
const char* label;
|
|
};
|
|
|
|
ErrorCode errorCodes[] = {
|
|
{"0", "No error"},
|
|
{"2", "Battery voltage too high"},
|
|
{"17", "Charger temperature too high"},
|
|
{"18", "Charger over current"},
|
|
{"19", "Charger current reversed"},
|
|
{"20", "Bulk time limit exceeded"},
|
|
{"21", "Current sensor issue (sensor bias/sensor broken)"},
|
|
{"26", "Terminals overheated"},
|
|
{"33", "Input voltage too high (solar panel)"},
|
|
{"34", "Input current too high (solar panel)"},
|
|
{"38", "Input shutdown (due to excessive battery voltage)"},
|
|
{"116", "Factory calibration data lost"},
|
|
{"117", "Invalid/incompatible firmware"},
|
|
{"119", "User settings invalid"}
|
|
};
|
|
const int errorCodesSize = sizeof(errorCodes) / sizeof(errorCodes[0]);
|
|
|
|
|
|
struct OperationState {
|
|
const char* code;
|
|
const char* label;
|
|
};
|
|
|
|
OperationState operationStates[] = {
|
|
{"0", "Off"},
|
|
{"1", "Low power"},
|
|
{"2", "Fault"},
|
|
{"3", "Bulk"},
|
|
{"4", "Absorption"},
|
|
{"5", "Float"},
|
|
{"9", "Inverting (on)"}
|
|
};
|
|
const int operationStatesSize = sizeof(operationStates) / sizeof(operationStates[0]);
|
|
|
|
struct LabelDescription {
|
|
const char* code;
|
|
const char* label;
|
|
};
|
|
|
|
struct OffReason {
|
|
const char* code;
|
|
const char* label;
|
|
};
|
|
|
|
OffReason offReasons[] = {
|
|
{"0x00000100", "No input power"},
|
|
{"0x00000080", "Switched off (power switch)"},
|
|
{"0x00000040", "Switched off (device mode register)"},
|
|
{"0x00000020", "Remote input"},
|
|
{"0x00000010", "Protection active"},
|
|
{"0x00000008", "Paygo"},
|
|
{"0x00000004", "BMS"},
|
|
{"0x00000002", "Engine shutdown detection"},
|
|
{"0x00000001", "Analysing input voltage"},
|
|
{"0x00000000", "Working"}
|
|
};
|
|
const int offReasonsSize = sizeof(offReasons) / sizeof(offReasons[0]);
|
|
|
|
|
|
LabelDescription mpptData[] = {
|
|
{"V", "Voltage batterie mV"},
|
|
{"VPV", "Voltage panneau mV"},
|
|
{"PPV", "Puissance panneau W"},
|
|
{"I", "Intensité batterie mA"},
|
|
{"IL", "Intensité décharge mA"},
|
|
{"OR", "Raison non fonctionnement"},
|
|
{"LOAD", "Etat sortie On/Off"},
|
|
{"H19", "Quantité d'énergie totale"},
|
|
{"H20", "Quantité d'énergie totale aujourd'hui"},
|
|
{"H21", "Puissance maximale aujourd'hui"},
|
|
{"H22", "Quantité d'énergie totale hier"},
|
|
{"H23", "Puissance maximale hier"},
|
|
{"ERR", "Code d'erreur"},
|
|
{"CS", "État de fonctionnement"},
|
|
{"FW", "Version du firmware (16 bits)"},
|
|
{"PID", "ID du produit"},
|
|
{"SER#", "Numéro de série"},
|
|
{"HSDS", "Numéro de la séquence du jour (0..364)"},
|
|
{"MPPT", "Mode de fonctionnement du tracker"}
|
|
};
|
|
const int mpptDataSize = sizeof(mpptData) / sizeof(mpptData[0]);
|
|
|
|
struct MPPTState {
|
|
const char* code;
|
|
const char* label;
|
|
};
|
|
|
|
MPPTState mpptStates[] = {
|
|
{"0", "Off"},
|
|
{"1", "Voltage or current limited"},
|
|
{"2", "Actif"}
|
|
};
|
|
const int mpptStatesSize = sizeof(mpptStates) / sizeof(mpptStates[0]);
|
|
|
|
|
|
//////////////////////////////////////////
|
|
// Storage
|
|
//////////////////////////////////////////
|
|
struct Configuration {
|
|
int max_current_charge;
|
|
int max_current_injection;
|
|
int voltage_charge;
|
|
int voltage_injection;
|
|
boolean configured;
|
|
};
|
|
|
|
Configuration config;
|
|
|
|
|
|
struct To_Store {
|
|
int total_elements;
|
|
int hour[maxSize];
|
|
int min[maxSize];
|
|
int tensions[maxSize];
|
|
};
|
|
To_Store to_store;
|
|
#define TO_STORE_ADDRESS sizeof(Configuration) // commence après la configuration
|
|
|
|
const int EEPROM_SIZE = 1024;
|
|
const int CONFIG_START = 0; // Start address in EEPROM
|
|
|
|
|
|
double getFloatParam(String param)
|
|
{
|
|
return String(server.arg(param).c_str()).toFloat();
|
|
}
|
|
|
|
void readConfiguration() {
|
|
|
|
EEPROM.get(CONFIG_START, config);
|
|
|
|
Serial.println("Configuration Loaded:");
|
|
Serial.println("Charge: " + String(config.max_current_charge));
|
|
Serial.println("Injection: " + String(config.max_current_injection));
|
|
|
|
}
|
|
void handleSave() {
|
|
if (getFloatParam("max_current_charge") && getFloatParam("max_current_injection")
|
|
&& getFloatParam("voltage_charge") && getFloatParam("voltage_injection")
|
|
) {
|
|
|
|
config.max_current_charge = getFloatParam("max_current_charge");
|
|
config.max_current_injection = getFloatParam("max_current_injection");
|
|
config.voltage_charge = getFloatParam("voltage_charge");
|
|
config.voltage_injection = getFloatParam("voltage_injection");
|
|
|
|
config.configured = true;
|
|
// // Sauvegarde des paramètres dans l'EEPROM
|
|
EEPROM.put(CONFIG_START, config);
|
|
EEPROM.commit();
|
|
server.send(200, "text/plain", "Configuration saved");
|
|
} else {
|
|
config.configured = false;
|
|
EEPROM.put(CONFIG_START, config);
|
|
EEPROM.commit();
|
|
server.send(400, "text/plain", "Invalid request");
|
|
}
|
|
}
|