Files
Arduino/ESP8266_BATTERIE_INJECTION_DEBUG/ESP8266_BATTERIE_INJECTION_DEBUG.ino
Jérôme Delacotte 7b30d6e298 first commit
2025-03-06 11:15:32 +01:00

1243 lines
35 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <ESP8266WebServer.h>
#include <SoftwareSerial.h>
#include <ArduinoJson.h>
// ______________________________
// | L T L T L T L T L T L T |
// | |
// RST| 1|TX HSer
// A0| 3|RX HSer
// D0|16 5|D1
// D5|14 4|D2
// D6|12 10kPUP_0|D3
//RX SSer/HSer swap D7|13 LED_10kPUP_2|D4
//TX SSer/HSer swap D8|15 |GND
// 3V3|__ |5V
// | |
// |___________________________|
// Time to sleep (in seconds):
const int sleepTimeS = 10;
void handleRoot(void);
// =======================
// WIFI
// =======================
//#include <ESP8266WebServer.h>
//#include <ESP8266WiFi.h>
//#include <ESP8266HTTPClient.h>
// Your WiFi credentials.
// Set password to "" for open networks.
const char* ssid = "Livebox-37cc";
const char* pass = "8A6060920A8A86896F770F2C47";
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 0, 0);
IPAddress DNS(192, 168, 1, 1);
ESP8266WebServer server(80);
void ICACHE_RAM_ATTR handleInterrupt();
bool led;
int pwm;
int pwmCount;
//const char* host = "192.168.1.3";
//const int port = 81;
//const char* apiEndpoint = "/json.htm?type=command&param=getSunRiseSet";
unsigned long lastUpdateTime = 0;
const unsigned long updateInterval = 20 * 1000; // 20 s en millisecondes
//String currentTime = "";
//String sunriseTime = "";
//String sunsetTime = "";
String error = "";
String date = "";
String heure = "";
#define SOFT_SERIAL_LOCAL true
// 192.168.1.50
//#define PIN_TENSION A0
//#define PIN_HALL A0
#define PIN_POWER 13 // D7
#define PIN_INJECTION 12 // D6
#define PIN_CHARGE 14 // D5
// #define PIN_BATTERIE 16 // D0
//#define PIN_DIMMER_OUTPUT 15 // D8
//#define PIN_DIMMER_ZEROCROSS 3 // 12 // D6 for boards with CHANGEBLE input pins
#define PIN_SOFTWARE_SERIAL_RX D4 //4
#define PIN_SOFTWARE_SERIAL_TX 0 // TX Not used
//#define PIN_TENSION A0
//#define PIN_HALL A0
//#define PIN_DALLAS 14 // D5
//#define PIN_POWER 0 // D3
//#define PIN_INJECTION 3 // RX
//#define PIN_CHARGE 4 // D2
//#define PIN_BATTERIE 5 // D1
//#define PIN_DIMMER_OUTPUT D7 // D7
//#define PIN_DIMMER_ZEROCROSS D6 // D6 for boards with CHANGEBLE input pins
//#define PIN_REGULATION D8
int speed_regulation = 0;// variable to hold speed value
//const int pins[] = {PIN_POWER, PIN_INJECTION, PIN_CHARGE
// #ifdef PIN_BATTERIE
// , PIN_BATTERIE
// #endif
// }; // Exemple: D1, D2, D3
//////////////////////////////////////////
// Victron Blue Solar
/////////////////////////////////////////
#ifdef SOFT_SERIAL_LOCAL
String devicename = "Victron Blue Solar";
#include "config.h"
#define PRINT_EVERY_SECONDS 5
#define rxPin PIN_SOFTWARE_SERIAL_RX // D7
#define txPin PIN_SOFTWARE_SERIAL_TX // D8 // TX Not used
SoftwareSerial victronSerial(rxPin, txPin);
// via the USB serial provided by the NodeMCU.
char receivedChars[buffsize]; // an array to store the received data
char tempChars[buffsize]; // an array to manipulate the received data
char recv_label[num_keywords][label_bytes] = {0}; // {0} tells the compiler to initalize it with 0.
char recv_value[num_keywords][value_bytes] = {0}; // That does not mean it is filled with 0's
char value[num_keywords][value_bytes] = {0}; // The array that holds the verified data
static byte blockindex = 0;
bool new_data = false;
bool blockend = false;
int outVal = 0;
String webpage = R"=(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Victron Control</title>
<SCRIPT>
var xmlHttp01=createXmlHttpObject();
function createXmlHttpObject(){
if(window.XMLHttpRequest){
xmlHttp=new XMLHttpRequest();
}else{
xmlHttp=new ActiveXObject('Microsoft.XMLHTTP');
}
return xmlHttp;
}
function process(){
if(xmlHttp01.readyState==0 || xmlHttp01.readyState==4){
xmlHttp01.open('GET','getData',true);
xmlHttp01.onreadystatechange=handleServerResponse;
xmlHttp01.send(null);
}
setTimeout('process()', 5000);
}
function handleServerResponse(){
console.log(xmlHttp01.readyState);
console.log(xmlHttp01.status);
if(xmlHttp01.readyState==4 && xmlHttp01.status==200){
const json_obj = JSON.parse(xmlHttp01.response);
console.log(xmlHttp01.response);
var result_text = "<table>";
for (var i = 0; i < json_obj.length; i++){
var obj = json_obj[i];
result_text = result_text + "<tr><td style=\"text-align: left;\">" + obj.id + "</td><td style=\"text-align: center;\">" + obj.value + "</td></tr>";
}
result_text = result_text + "</table>";
document.getElementById('response_items').innerHTML=result_text;
}
}
</SCRIPT>
<style>
body {
font-family: 'Arial', sans-serif;
background-color: #f2f2f2;
margin: 0;
padding: 0;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
align-items: center;
height: 100vh;
}
.control-container {
background: #C0C0C0;
width: 128px;
height: 64px;
margin: 10px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
transition: background-color 0.3s ease-in-out; /* Ajout de la transition */
}
h2,button {
margin: 0;
font-size: 1rem;
}
p {
font-size: 1.2rem;
margin-top: 20px;
}
/* Ajout des styles au survol ou au clic */
.control-container:hover,
.control-container:active {
background-color: #a0a0a0;
}
.arcade-button {
display: inline-block;
position: relative;
width: 150px;
height: 150px;
background-color: #3498db;
border: 10px solid #2c3e50;
border-radius: 50%;
overflow: hidden;
cursor: pointer;
transition: background-color 0.3s ease-in-out;
}
.arcade-button:hover {
background-color: #2980b9;
}
.button-content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #ecf0f1;
font-size: 1.5rem;
text-align: center;
}
h1 {
font-size: 120%;
color: blue;
margin: 0 0 10px 0;
}
table{
border-collapse: collapse;
}
table, th, td {
border: 0px solid blue;
}
</style>
</head>
<BODY onload="process()">
<div class="control-container" id="LEDn">
<button onclick="alert('on');">ON</button>
</div>
<div class="control-container" id="pwmplus">
<a href="/plus?value=10">Plus</a>
</div>
<div class="control-container" id="pwmminus">
<a href="/minus?value=10">Minus</a>
</div>
<div class="control-container" id="pwmstop">
<a href="/stop">Stop</a>
</div>
<div class="arcade-button">
<div class="button-content">@@pwmCount@@</div>
</div>
<div class="victron_data">
<span style="font-family: Arial, Helvetica, sans-serif;font-size: 20px;font-weight: bold;color: #a5a5a5;"><A id='response_items'></A></span>
</div>
</body>
</html>
)=";
#endif
//////////////////////////////////////////
// DALLAS
/////////////////////////////////////////
#ifdef PIN_DALLAS
float temperature = 0;
#include <OneWire.h>
#include <DallasTemperature.h>
#define onewirepin PIN_DALLAS // DATA pin of DS18B20 wired to pin DALLAS of Arduino
OneWire oneWire(onewirepin);
DallasTemperature sensors(&oneWire);
// find the DeviceAddress of your DS18B20 with the sketch DS18B20_address_reporter
// then replace the 8-byte ID below with the reported one
DeviceAddress Probe = { 0x28, 0xFF, 0x61, 0x1D, 0x76, 0x04, 0x00, 0x34 };
#endif
//////////////////////////////////////////
// DIMMER
/////////////////////////////////////////
#ifdef PIN_DIMMER_OUTPUT
#include <RBDdimmer.h>
// Dimmer
#define pas 5
dimmerLamp dimmer(PIN_DIMMER_OUTPUT, PIN_DIMMER_ZEROCROSS); //initialase port for dimmer for ESP8266, ESP32, Arduino due boards
//dimmerLamp dimmer(PIN_DIMMER_OUTPUT); //initialase port for dimmer for MEGA, Leonardo, UNO, Arduino M0, Arduino Zero
#endif
// HALL
int mVperAmp = 66; // 185 pour 5A, use 100 for 20A Module and 66 for 30A Module
int RawValue= 0;
int ACSoffset = 2500;
double mp_offset = 0.040;
double Voltage = 0;
double Amps = 0;
void setPwm(int pwm);
void handleRoot() {
String page = webpage;
page.replace("@@pwmCount@@", String(pwmCount));
//Serial.println(page);
server.send(200, "text/html", page);
// return;
//
// // getHall();
// #ifdef PIN_DALLAS
// temperature = printTemperature(Probe);
// #endif
//
// #ifdef PIN_TENSION
// getTension();
// #endif
//
//// recvWithEndMarker();
//// handleNewData();
//
// // Générer la page HTML avec CSS
// String html = "<!DOCTYPE html><html lang='en'><head><title>Victron Control</title>";
//
// html += "<meta charset='UTF-8'>";
// html += "<meta name='viewport' content='width=device-width, initial-scale=1.0'>";
//
// html += "<link type='text/css' rel='stylesheet' href='http://192.168.1.3:81/velux/velux.css'>";
//// html += "<script src='http://192.168.1.3:81/velux/jquery.min.js'></script>";
//// html += "<script src='http://192.168.1.3:81/velux/velux.js'></script>";
//
//
//#ifdef SOFT_SERIAL_LOCAL
// //html+= to_include;
//#endif
//
// // html += "<style>";
// // html += "body { font-family: Arial, sans-serif; text-align: center; }";
// // html += "h1 { color: #333; }";
// // html += "form { margin: 10% auto; max-width: 100%; }";
// // html += "input { padding: 1em; margin: 1em; }";
// // html += "#buttons {list-style: none;}";
// // html += "#button { display: inline-block; list-style-type: none;}";
// // html += "@media (max-width: 600px) {li {display: block; margin: 5px 0;list-style-type: none;}}";
// // html += "</style>";
//
// html += "</head><body onload='process()'>";
// html += "<h1>Controle des batteries</h1>";
// html += "<h2>" + String(WiFi.localIP().toString()) + "</h2>";
// html += "<ul class='buttons'>";
//
// String pinState = digitalRead(PIN_POWER) == HIGH ? "low" : "high";
// html += "<li class='button " + pinState + "' onclick='showNotification()'><form action='/stop' method='get'>";
// html += "<input type='submit' value='Arret'>";
// html += "</form></li>";
//
// pinState = digitalRead(PIN_POWER) == HIGH ? "high" : "low";
// html += "<li class='button " + pinState + "' onclick='showNotification()'><form action='/start' method='get'>";
// html += "<input type='submit' value='Demarrer'>";
// html += "</form></li>";
//
// pinState = digitalRead(PIN_INJECTION) == HIGH ? "high" : "low";
// html += "<li class='button " + pinState + "' onclick='showNotification()'><form action='/injection' method='get'>";
// // html += "<input type='hidden' id='time' name='time' value='" + String(to_store.max_time - to_store.theorique_position) + "'>";
//
// html += "<input type='submit' value='Injecter'>";
// html += "</form></li>";
//
// pinState = digitalRead(PIN_CHARGE) == HIGH ? "high" : "low";
// html += "<li class='button " + pinState + "' onclick='showNotification()'><form action='/charge' method='get'>";
// html += "<input type='submit' value='Charger'>";
// html += "</form></li>";
//
// #ifdef PIN_BATTERIE
// pinState = digitalRead(PIN_BATTERIE) == HIGH ? "high" : "low";
// html += "<li class='button " + pinState + "' onclick='showNotification()'><form action='/coupe' method='get'>";
// html += "<input type='submit' value='Coupe Batterie'>";
// html += "</form></li>";
// html += "</ul>";
// #endif
//
//#ifdef PIN_DIMMER_OUTPUT
//
// html += "<ul class='buttons'>";
//
// html += "<li class='button' onclick='showNotification()'><form action='/plus?value=10' method='get'>";
// html += "<input type='submit' value='Plus'>";
// html += "</form></li>";
//
// html += "<li class='button' onclick='showNotification()'><form action='/minus?value=10' method='get'>";
// html += "<input type='submit' value='Minus'>";
// html += "</form></li>";
//
// html += "<li class='button' onclick='showNotification()'><form action='/zero' method='get'>";
// html += "<input type='submit' value='Stop'>";
// html += "</form></li>";
//
// html += "</ul>";
//#endif
//
// // PIN_REGULATION
// #ifdef PIN_REGULATION
// html += "<ul class='buttons'>";
//
// html += "<li class='button' onclick='showNotification()'><form action='/plus_reg?value=10' method='get'>";
// html += "<input type='submit' value='Plus'>";
// html += "</form></li>";
//
// html += "<li class='button' onclick='showNotification()'><form action='/minus_reg?value=10' method='get'>";
// html += "<input type='submit' value='Minus'>";
// html += "</form></li>";
//
// html += "<li class='button' onclick='showNotification()'><form action='/zero_reg' method='get'>";
// html += "<input type='submit' value='Stop'>";
// html += "</form></li>";
//
// html += "</ul>";
// #endif
//
// html += "<ul class='buttons data'>";
//
// #ifdef PIN_DIMMER_OUTPUT
// html += "<li><div class='arcade-button'><div class='button-content'>@@pwmCount@@ %</div></div>";
// #endif
//
// //html += "<li><div class='arcade-button'><div class='button-content'>" + String(Amps) + " A</div></div>";
// html += "<li><div class='arcade-button'><div class='button-content'>" + String(Voltage / 55) + " V</div></div>";
// // html += "<li><div class='arcade-button'><div class='button-content'>" + String(Amps * Voltage) + " W</div></div>";
//
//
// #ifdef PIN_DALLAS
// html += "<li><div class='arcade-button'><div class='button-content'>" + String(temperature) + " °C</div></div>";
// #endif
//
// #ifdef PIN_REGULATION
// html += "<li><div class='arcade-button'><div class='button-content'>" + String(speed_regulation) + " %</div></div>";
// #endif
//
// html += "</ul>";
//
// html += "<div class='victron_data'><span style='font-family: Arial, Helvetica, sans-serif;font-size: 20px;font-weight: bold;color: #a5a5a5;'><A id='response_items'></A></span></div>";
//
// if (error != "") {
// html += "<p>" + error + "</p>";
// }
//
//
// // String page = "<h1>État des broches GPIO</h1>";
// //
// // // Pour chaque broche GPIO dans la liste
// // for (int i = 0; i < sizeof(pins) / sizeof(pins[0]); i++) {
// // // Lecture de l'état de la broche
// // int pinState = digitalRead(pins[i]);
// //
// // // Ajout d'un bouton rouge ou vert en fonction de l'état de la broche
// // if (pinState == HIGH) {
// // page += "<button style=\"background-color: green;\">Pin ";
// // page += pins[i];
// // page += " : HIGH</button>";
// // } else {
// // page += "<button style=\"background-color: red;\">Pin ";
// // page += pins[i];
// // page += " : LOW</button>";
// // }
// // page += "<br>";
// // }
// //
// // html += page;
//
// html.replace("@@pwmCount@@", String(pwmCount));
//
// html += "<div id='notification' class='notification'></div>";
// html += "</body></html>";
//
// // Envoyer la page HTML au client
// server.send(200, "text/html", html);
}
void handleStop() {
Serial.println("Arrêt");
digitalWrite(PIN_INJECTION, HIGH);
delay(200);
digitalWrite(PIN_CHARGE, HIGH);
delay(200);
digitalWrite(PIN_POWER, HIGH);
delay(200);
#ifdef PIN_BATTERIE
digitalWrite(PIN_BATTERIE, HIGH);
delay(200);
#endif
// Vous pouvez ajouter ici le code pour gérer l'arrêt comme vous le souhaitez
// Rediriger vers la page principale après le traitement
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
void handleStart() {
#ifdef PIN_DIMMER_OUTPUT
dimmer.setState(ON_OFF_typedef::ON);
#endif
Serial.println("Start");
digitalWrite(PIN_POWER, LOW);
delay(200);
#ifdef PIN_BATTERIE
digitalWrite(PIN_BATTERIE, LOW);
delay(200);
#endif
// Vous pouvez ajouter ici le code pour gérer l'arrêt comme vous le souhaitez
// Rediriger vers la page principale après le traitement
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
void handleInjection() {
#ifdef PIN_DIMMER_OUTPUT
dimmer.setState(ON_OFF_typedef::OFF);
#endif
digitalWrite(PIN_POWER, LOW);
delay(200);
#ifdef PIN_BATTERIE
digitalWrite(PIN_BATTERIE, LOW);
delay(200);
#endif
digitalWrite(PIN_CHARGE, HIGH);
delay(500);
Serial.println("injection");
digitalWrite(PIN_INJECTION, LOW);
delay(200);
#ifdef PIN_BATTERIE
digitalWrite(PIN_BATTERIE, LOW);
delay(200);
#endif
// Rediriger vers la page principale après le traitement
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
void handleStopInjection() {
#ifdef PIN_BATTERIE
digitalWrite(PIN_BATTERIE, HIGH);
delay(200);
#endif
Serial.println("Stop injection");
digitalWrite(PIN_INJECTION, HIGH);
delay(200);
// Rediriger vers la page principale après le traitement
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
void handleCharge() {
#ifdef PIN_DIMMER_OUTPUT
dimmer.setState(ON_OFF_typedef::ON);
#endif
Serial.println("charge");
digitalWrite(PIN_POWER, LOW);
delay(200);
#ifdef PIN_BATTERIE
digitalWrite(PIN_BATTERIE, HIGH);
delay(200);
#endif
digitalWrite(PIN_INJECTION, HIGH);
delay(200);
digitalWrite(PIN_CHARGE, LOW);
delay(200);
// Rediriger vers la page principale après le traitement
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
void handleStopCharge() {
Serial.println("stop charge");
#ifdef PIN_BATTERIE
digitalWrite(PIN_BATTERIE, HIGH);
delay(200);
#endif
digitalWrite(PIN_CHARGE, HIGH);
delay(200);
// Rediriger vers la page principale après le traitement
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
void handleCoupe() {
Serial.println("coupe batterie");
#ifdef PIN_BATTERIE
digitalWrite(PIN_BATTERIE, HIGH);
delay(200);
#endif
// Vous pouvez ajouter ici le code pour traiter la vitesse comme vous le souhaitez
// Rediriger vers la page principale après le traitement
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
// Méthode pour gérer la requête '/getData'
void handleData() {
String JSON = F("[");
for (int i = 0; i < num_keywords; i++){
JSON += "{\"id\":\"" + String(keywords[i]) + "\", \"value\":\"" + String(value[i]) + "\"},";
}
JSON += "{\"id\":\"end\", \"value\":\"end\"}";
JSON += "]";
server.send(200, "application/json", JSON);
// return;
// // Créer un objet JSON
// DynamicJsonDocument doc(200);
//
// // Remplir l'objet JSON avec les données PZEM
// doc["PIN_POWER"] = digitalRead(PIN_POWER);
// doc["PIN_INJECTION"] = digitalRead(PIN_INJECTION);
// doc["PIN_CHARGE"] = digitalRead(PIN_CHARGE);
// #ifdef PIN_BATTERIE
// doc["PIN_BATTERIE"] = digitalRead(PIN_BATTERIE);
// #endif
//
// doc["AMPS"] = Amps;
// doc["VOLTAGE"] = Voltage;
// #ifdef PIN_DALLAS
// doc["TEMPERATURE"] = temperature;
// #endif
// // Convertir l'objet JSON en chaîne
// String jsonData;
// serializeJson(doc, jsonData);
//
// // Envoyer la réponse JSON au client
// server.send(200, "application/json", jsonData);
}
#ifdef PIN_DIMMER_OUTPUT
//pwm functions - if pwm is set to 1/-1 it will in-/decrease pwmCounter in loop()
void exact(){
int value_to_set = getValueFromParam();
pwm=value_to_set;
pwmCount = pwm;
if (pwmCount>100) pwmCount = 100;
if (pwmCount < 0) {
pwmCount = 0;
}
Serial.println(pwmCount);
//dimmer.setPower(pwmCount);
setPwm(pwmCount);
handleRoot();
}
void plus(){
int value_to_set = getValueFromParam();
if (value_to_set <= 0) {
value_to_set = 5;
}
pwm+=value_to_set;
setPwm(pwm);
handleRoot();
}
void minus(){
int value_to_set = getValueFromParam();
if (value_to_set <= 0) {
value_to_set = 5;
}
pwm-=value_to_set;
setPwm(pwm);
handleRoot();
}
void stopPWM(){
dimmer.setState(ON_OFF_typedef::OFF);
pwm=0; //-pwmCount;
setPwm(pwm);
handleRoot();
}
void setPwm(int pwm)
{
pwmCount = pwm;
if (pwmCount>100) pwmCount = 100;
if (pwmCount <= 1) {
pwmCount = 0;
}
Serial.println(pwmCount);
if (pwmCount <= 0) {
dimmer.setState(ON_OFF_typedef::OFF);
}
else {
dimmer.setState(ON_OFF_typedef::ON);
}
dimmer.setPower(pwmCount);
}
int getValueFromParam()
{
String message = "Number of args received:";
message += server.args();
for (int i = 0; i < server.args(); i++) {
message = message + ("Arg nº" + String(i) + " > ");
message = message + (server.argName(i) + ": ");
message = message + (server.arg(i) + "\n");
if (server.argName(i) == "value") {
return String(server.arg(i)).toInt();
}
}
Serial.println(message);
return pas;
}
#endif
#ifdef PIN_TENSION
void getTension()
{
int pin_value = analogRead(PIN_TENSION);
Voltage = pin_value;
}
#endif
#ifdef PIN_HALL
void getHall(){
int i = 0;
RawValue = 0;
// Somme du courant alternatif pendant 20 ms ==> 50hz
// Détermination du max et max pour hauteur de crete
int vmin = 4096;
int vmax = 0;
for (i = 0; i < 200; i++) {
int value = analogRead(PIN_HALL);
if (value >= 0) {
RawValue += value;
vmax = max(value,vmax);
vmin = min(value,vmin);
} else {
i--;
}
delay(1);
}
// Serial.print("Raw Value = " );
// Serial.print(RawValue);
Serial.print("min = " );
Serial.print(vmin);
Serial.print(" max = " );
Serial.print(vmax);
// Serial.print(" i =" );Amps
// Serial.print(i);
// RawValue = RawValue / i;
// Tension continue
Voltage = (RawValue / 1023.0) * 5000; // Gets you mV
Amps = ((Voltage - ACSoffset) / mVperAmp);
// La valeur maxi * racine carrée de 2 pour obtenir la tension "réelle"
// La tension efficace pour l'effet Hall étant réduite d'un facteur 0,707
// Voltage = ((vmax - vmin) / 430.0) * 5000;
//
// Amps = max(5.5 * (vmax - vmin) / 473.0 -0.0580, 0.0); // <= pour le bruit
// Serial.print(" Raw Value = " ); // shows pre-scaled value
// Serial.print(RawValue);
Serial.print("\t mV = "); // shows the voltage measured
Serial.print(Voltage,3); // the '3' after voltage allows you to display 3 digits after decimal point
Serial.print("\t Amps = "); // shows the voltage measured
Serial.print(Amps,3); // the '3' after voltage allows you to display 3 digits after decimal point
Serial.print("\t Watt = "); // shows the voltage measured
Serial.print(Amps * 220,3);
Serial.print("\t WattH = "); // shows the voltage measured
Serial.println(Amps * 220 / 1200,3);
delay(2500);
}
#endif
#ifdef PIN_REGULATION
void setReg(int pwm)
{
speed_regulation=pwm;
if (speed_regulation>100) speed_regulation = 100;
if (speed_regulation <= 1) {
speed_regulation = 0;
}
Serial.println(speed_regulation);
analogWrite(PIN_REGULATION, speed_regulation);// send speed_regulation value to motor
}
void exact_reg(){
int value_to_set = getValueFromParam();
speed_regulation=value_to_set;
if (speed_regulation>100) speed_regulation = 100;
if (speed_regulation < 0) {
speed_regulation = 0;
}
setReg(speed_regulation);
handleRoot();
}
void plus_reg(){
int value_to_set = getValueFromParam();
if (value_to_set <= 0) {
value_to_set = 5;
}
speed_regulation += value_to_set;
setReg(speed_regulation);
handleRoot();
}
void minus_reg(){
int value_to_set = getValueFromParam();
if (value_to_set <= 0) {
value_to_set = 5;
}
speed_regulation -= value_to_set;
setReg(speed_regulation);
handleRoot();
}
void stop_reg(){
speed_regulation = 0;
setReg(speed_regulation);
handleRoot();
}
#endif
#ifdef PIN_DALLAS
float printTemperature(DeviceAddress deviceAddress)
{
sensors.requestTemperatures();
float tempC = sensors.getTempC(deviceAddress);
// if (tempC == -127.00)
// {
// Serial.print ("Error getting temperature ");
// }
// else
// {
// Serial.print ("C: ");
// Serial.println (tempC);
// // Serial.print (" F: ");
// // Serial.print(DallasTemperature::toFahrenheit(tempC));
// }
return tempC;
}
#endif
#ifdef SOFT_SERIAL_LOCAL
long temps = 0;
// Serial Handling
// ---
// This block handles the serial reception of the data in a
// non blocking way. It checks the Serial line for characters and
// parses them in fields. If a block of data is send, which always ends
// with "Checksum" field, the whole block is checked and if deemed correct
// copied to the 'value' array.
void recvWithEndMarker() {
static byte ndx = 0;
char endMarker = '\n';
char rc;
while (victronSerial.available() > 0 && new_data == false) {
rc = victronSerial.read();
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= buffsize) {
ndx = buffsize - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
ndx = 0;
new_data = true;
}
yield();
}
}
void parseData() {
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars,"\t"); // get the first part - the label
// The last field of a block is always the Checksum
if (strcmp(strtokIndx, "Checksum") == 0) {
blockend = true;
}
strcpy(recv_label[blockindex], strtokIndx); // copy it to label
// Now get the value
strtokIndx = strtok(NULL, "\r"); // This continues where the previous call left off until '/r'.
if (strtokIndx != NULL) { // We need to check here if we don't receive NULL.
strcpy(recv_value[blockindex], strtokIndx);
}
blockindex++;
if (blockend) {
// We got a whole block into the received data.
// Check if the data received is not corrupted.
// Sum off all received bytes should be 0;
byte checksum = 0;
for (int x = 0; x < blockindex; x++) {
// Loop over the labels and value gotten and add them.
// Using a byte so the the % 256 is integrated.
char *v = recv_value[x];
char *l = recv_label[x];
while (*v) {
checksum += *v;
v++;
}
while (*l) {
checksum+= *l;
l++;
}
// Because we strip the new line(10), the carriage return(13) and
// the horizontal tab(9) we add them here again.
checksum += 32;
}
// Checksum should be 0, so if !0 we have correct data.
if (!checksum) {
// Since we are getting blocks that are part of a
// keyword chain, but are not certain where it starts
// we look for the corresponding label. This loop has a trick
// that will start searching for the next label at the start of the last
// hit, which should optimize it.
int start = 0;
for (int i = 0; i < blockindex; i++) {
for (int j = start; (j - start) < num_keywords; j++) {
if (strcmp(recv_label[i], keywords[j % num_keywords]) == 0) {
// found the label, copy it to the value array
strcpy(value[j], recv_value[i]);
start = (j + 1) % num_keywords; // start searching the next one at this hit +1
break;
}
}
}
}
// Reset the block index, and make sure we clear blockend.
blockindex = 0;
blockend = false;
}
}
void printValues() {
for (int i = 0; i < num_keywords; i++){
Serial.print(keywords[i]);
Serial.print(",");
Serial.println(value[i]);
}
}
void printData() {
static unsigned long prev_millis;
if (millis() - prev_millis > PRINT_EVERY_SECONDS * 1000) {
printValues();
prev_millis = millis();
}
}
void handleNewData() {
// We have gotten a field of data
if (new_data == true) {
//Copy it to the temp array because parseData will alter it.
strcpy(tempChars, receivedChars);
parseData();
new_data = false;
}
}
// Méthode pour gérer la requête '/getData'
void handleVictron() {
String JSON = F("[");
for (int i = 0; i < num_keywords; i++){
JSON += "{\"id\":\"" + String(keywords[i]) + "\", \"value\":\"" + String(value[i]) + "\"},";
}
JSON += "{\"id\":\"end\", \"value\":\"end\"}";
JSON += "]";
server.send(200, "application/json", JSON);
// // Créer un objet JSON
// DynamicJsonDocument doc(200);
//
// for (int i = 0; i < num_keywords; i++){
// doc[String(keywords[i])] = String(value[i]);
// }
//
// // Convertir l'objet jsonData en chaîne
// String jsonData;
// serializeJson(doc, jsonData);
//
// // Envoyer la réponse JSON au client
// server.send(200, "application/json", jsonData);
}
#endif
void setup() {
// initialize digital pin LED_BUILTIN as an output.
Serial.begin(115200);
#ifdef PIN_TENSION
pinMode(PIN_TENSION, INPUT);
#endif
#ifdef PIN_HALL
pinMode(PIN_HALL, INPUT);
#endif
// pinMode(PIN_POWER, OUTPUT);
// pinMode(PIN_INJECTION, OUTPUT);
// pinMode(PIN_CHARGE, OUTPUT);
#ifdef PIN_BATTERIE
pinMode(PIN_BATTERIE, OUTPUT);
#endif
#ifdef PIN_REGULATION
pinMode(PIN_REGULATION,OUTPUT);// set mtorPin as output
#endif
#ifdef SOFT_SERIAL_LOCAL
victronSerial.begin(19200);
#endif
delay(10);
// handleStop();
// Connectez-vous au réseau WiFi
WiFi.begin(ssid, pass);
Serial.println("Connexion au WiFi en cours.");
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("Connecté au réseau WiFi");
Serial.println(WiFi.localIP());
// Démarrer le serveur
server.begin();
// Définissez les gestionnaires pour les différentes URL
server.on("/", handleRoot);
// server.on("/stop", handleStop);
// server.on("/start", handleStart);
//
// server.on("/injection", handleInjection);
// server.on("/stopInjection", handleStopInjection);
//
// server.on("/charge", handleCharge);
// server.on("/stopCharge", handleStopCharge);
// server.on("/coupe", handleCoupe);
server.on("/getData", HTTP_GET, handleData);
// #ifdef SOFT_SERIAL_LOCAL
// server.on("/getVictron", HTTP_GET, handleVictron);
// #endif
// Dimmer
#ifdef PIN_DIMMER_OUTPUT
server.on("/minus", minus);
server.on("/plus", plus);
server.on("/exact", exact);
server.on("/zero", stopPWM);
#endif
#ifdef PIN_REGULATION
server.on("/minus_reg", minus_reg);
server.on("/plus_reg", plus_reg);
server.on("/exact_reg", exact_reg);
server.on("/zero_reg", stop_reg);
#endif
//initialize variables__________________
pwm = 0;
pwmCount= 0;
led = 0;
Serial.print("Module IP: ");
Serial.println(WiFi.softAPIP());
// Dimmer
Serial.println("Dimmer Program is starting...");
delay(1000);
#ifdef PIN_DIMMER_OUTPUT
dimmer.begin(NORMAL_MODE, ON); //dimmer initialisation: name.begin(MODE, STATE)
Serial.println("Set value");
dimmer.setState(ON_OFF_typedef::OFF);
dimmer.setPower(pwmCount); // setPower(0-100%);
#endif
Serial.println("Serveur Web démarré");
#ifdef PIN_DALLAS
sensors.begin (); // Initialize the sensor and set resolution level
sensors.setResolution(Probe, 10);
delay(1000);
Serial.println();
Serial.print ("Number of Devices found on bus = ");
Serial.println (sensors.getDeviceCount());
Serial.print ("Getting temperatures... ");
Serial.println ();
#endif
///////////////////////////////////
// UPDATE OTA
///////////////////////////////////
// Port defaults to 8266
ArduinoOTA.setPort(8266);
// Hostname defaults to esp8266-[ChipID]
//ArduinoOTA.setHostname("ESP8266_VELUX_NORD_1");
// No authentication by default
// ArduinoOTA.setPassword("admin");
// Password can be set with it's md5 value as well
// MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
// ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
ArduinoOTA.onStart([]() {
Serial.println("Start");
});
ArduinoOTA.onEnd([]() {
Serial.println("\nEnd");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
});
ArduinoOTA.begin();
}
void loop() {
// Gérez les requêtes du serveur
server.handleClient();
// getJson();
ArduinoOTA.handle();
recvWithEndMarker();
handleNewData();
if (millis() - lastUpdateTime >= updateInterval) {
// Mettre à jour le temps de la dernière mise à jour
lastUpdateTime = millis();
#ifdef SOFT_SERIAL_LOCAL
// Receive information on Serial from MPPT
printData();
// Just print the values every second,
// Add your own code here to use the data.
// Make sure to not used delay(X)s of bigger than 50ms,
// so make use of the same principle used in printData()
// or use some sort of Alarm/Timer Library
// printData();
#endif
}
//delay(200);
}