1243 lines
35 KiB
C++
1243 lines
35 KiB
C++
#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¶m=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);
|
||
}
|