add set spiff when edit using lcd

This commit is contained in:
Bluedragon 2022-04-28 05:54:33 +07:00
parent cc2cdedf7b
commit 05c8b38e21
8 changed files with 710 additions and 805 deletions

7
backup/bootstrap.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,196 +0,0 @@
<!DOCTYPE HTML><html><head>
<title>Rally TerraTrip v1 Constanta</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<!--
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
-->
<link href="bootstrap.css" rel="stylesheet">
<script>
function onlyNumberKey(evt,e) {
// Only ASCII character in that range allowed
var ASCIICode = (evt.which) ? evt.which : evt.keyCode
if (ASCIICode > 31 && (ASCIICode < 48 || ASCIICode > 57) && ASCIICode !=46)
return false;
return true;
}
function chback(e){ //change background to yellow
e.style.backgroundColor = "yellow";
}
</script>
</head><body onload="loaded();">
<!--
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
-->
<script src="bootstrap.bundle.min.js"></script>
<div class="bg-info text-white">
<!-- <div class="row">
<div class="col-2 mt-1"><h2><span id="counter">12345</span></h2></div>
<div class="col-3 mt-1"><h2>TRACK <span id="currenttrack">A</span></h2></div>
<div class="col mt-1"><h2 class="text-center">Time: <span id="currenttime">00:00:00</span></h2></div>
<div class="col-3 mt-1 text-end"><h2><span id="speed">123.4</span>Km/h</h2></div>
<hr>
</div>
-->
<!--//Constanta Menu-->
<div class="row g-2 align-items-center">
<div class="col-1"></div>
<div class="col-1 text-center "><label class="col-form-label fs-6 fw-bold">Dist(Km)</label></div>
<div class="col-1 text-end">= </div>
<div class="col-1 text-center "><label class="col-form-label fs-6 fw-bold">Speed</label></div>
<div class="col-1 text-center">X</div>
<div class="col-1 text-center "><label class="col-form-label fs-6 fw-bold">Time(min)</label></div>
<div class="col-1"></div>
<div class="col-2 text-center "><label class="col-form-label fs-6 fw-bold">Start Time</label></div>
</div>
)rawliteral";
const char HTML_CONSTROW[] PROGMEM = R"rawliteral(
<div class="row g-2 align-items-center" id="trip%A%">
<div class="col-1 "><label for="%dist%" class="col-form-label fs-4 ms-1 trip">%A%></label></div>
<div class="col-2">
<input type="number" step="any" maxlength="6" required oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
id="%dist%" name="%dist%" class="form-control dist" onkeypress="return onlyNumberKey(event,this)" onchange="chback(this)"></div>
<div class="col-2 ">
<input type="number" step="any" maxlength="6" required oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
id="%speed%" name="%speed%" class="form-control speed" onkeypress="return onlyNumberKey(event,this)" onchange="chback(this)"></div>
<div class="col-2">
<input type="number" maxlength="5" required oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
id="%time%" name="%time%" class="form-control time" onkeypress="return onlyNumberKey(event,this)" onchange="chback(this)"></div>
<div class="col-2">
<input type="time" id="%stime%" name="%stime%" class="form-control stime" onchange="chback(this)"></div>
<div class="col-2">
<button class="btn btn-primary fw-bold" id="myBtn" onclick="setConstanta(this)">SET %A%</button></div>
</div>
)rawliteral";
const char HTML_CONSTEND[] PROGMEM = R"rawliteral(
<button ondblclick="location.href='/menu';" class="btn btn-primary fw-bold btn-sm mt-2 mb-2 ms-3">Back to Menu</button>
</div>
<script>
// document.addEventListener("DOMContentLoaded", function() {
function loaded(){
var xhr = new XMLHttpRequest();
var url = "/rest/loadconst";
console.log("before open");
// for (var i=65; i<81; i++){
xhr.open("POST", url, true);
console.log("before setrequest");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
console.log(xhr.responseText);
if (xhr.readyState === 4 && xhr.status === 200) {
var jsonAllTrip = JSON.parse(xhr.responseText);
const jsonlen = Object.keys(jsonAllTrip.alltrip).length;
console.log(jsonAllTrip.alltrip[0]);
console.log("jsondlen="+jsonlen);
var jsontemp;
for (var i=0; i<jsonlen; i++){
jsontemp = jsonAllTrip.alltrip[i];
console.log(jsontemp);
var json = JSON.parse(JSON.stringify(jsontemp));
console.log(json);
// if (json.ok) {
parsingjson(json);
}
//console.log(json.trip + ", " + json.speed + ", " + json.dist + ", " + json.time + ", " + json.stime);
console.log(json);
}
};
let data = '{"req":"B"}'
console.log(data);
var datajson = JSON.stringify(data);
console.log(datajson);
// console.log(String.fromCharCode(i));
// data = '{"req":"'+String.fromCharCode(i)+'"}'
xhr.send(data);
// }
};
function setConstanta(e){
e = e || window.event;
var targ1 = e.target || e.srcElement || e;
if (targ1.nodeType == 3) targ1 = targ1.parentNode; // defeat Safari bug
const targ = targ1.closest(".row");
const trip = targ.getElementsByClassName("trip")[0].textContent[0];
const speed = targ.getElementsByClassName("speed")[0].value;
if (speed===""){
alert ("Trip "+trip+"-> [Speed] is required");
return;
}
const stime = targ.getElementsByClassName("stime")[0].value;
if (stime===""){
alert ("Trip "+trip+"-> [Start Time] is required");
return;
}
// targ.getElementsByClassName("speed")[0].value = "345" //trial change backColor
// targ.getElementsByClassName("speed")[0].style.backgroundColor = "white"
const dist = targ.getElementsByClassName("dist")[0].value;
const time = targ.getElementsByClassName("time")[0].value;
var full_data='{"trip":"'+trip+'", "speed":"'+speed+'", "dist":"'+dist+'", "time":"'+time+'", "stime":"'+stime+'"}';
console.log(full_data);
sendjson(full_data);
};
function parsingjson(json){
console.log(json);
var tripID = document.getElementById("trip"+json.trip);
console.log(tripID);
const speed = tripID.getElementsByClassName("speed")[0];
const dist = tripID.getElementsByClassName("dist")[0];
const time = tripID.getElementsByClassName("time")[0];
const stime = tripID.getElementsByClassName("stime")[0];
setValBackColor(speed, json.speed);
setValBackColor(dist, json.dist);
setValBackColor(time, json.time);
setValBackColor(stime, json.stime);
// speed.value = json.speed;
// dist.value = json.dist;
// time.value = json.time;
// stime.value = json.stime;
// speed.style.backgroundColor = "#94C4E2"// #6495ED
// dist.style.backgroundColor = "#94C4E2"
// time.style.backgroundColor = "#94C4E2"
// stime.style.backgroundColor = "#94C4E2"
console.log("result ok:"+json.trip + ", " + speed.value + ", " + dist.value + ", " + time.value + ", " + stime.value);
};
function setValBackColor(elem, jsonval){
if (jsonval) {
elem.value = jsonval;
elem.style.backgroundColor = "#ABEBC6";//"#E5E7E9";//"#C0C0C0";//"#94C4E2";
} else {
elem.style.backgroundColor = "white";
}
};
function sendjson(data){
var xhr = new XMLHttpRequest();
var url = "/rest/endpoint";
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
console.log(xhr.responseText);
if (xhr.readyState === 4 && xhr.status === 200) {
var json = JSON.parse(xhr.responseText);
console.log(json.trip + ", " + json.speed + ", " + json.dist + ", " + json.time + ", " + json.stime);
if (json.ok) {
parsingjson(json);
}
//console.log(json.trip + ", " + json.speed + ", " + json.dist + ", " + json.time + ", " + json.stime);
console.log(json);
}
};
console.log(data);
var datajson = JSON.stringify(data);
console.log(datajson);
xhr.send(data);
}
</script>
</body></html>

View File

@ -1,177 +1,227 @@
<!DOCTYPE HTML><html><head>
<title>Rally TerraTrip v1 Constanta</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script type = "text/javascript">
const ws = new WebSocket("ws://%serveripaddress%/wscal");
ws.onopen = function() {console.log("WebSocket Connected");};
ws.onclose = function() {alert("WS Connection Closed");};
ws.onmessage = function(event) {
console.log(event.data);
var data = JSON.parse(event.data);
const elemen = document.getElementsByClassName(data.trip)[0];
console.log(elemen);
element.getElementsByClassName("speed")[0].value = data.speed;
element.getElementsByClassName("dist")[0].value = data.dist;
element.getElementsByClassName("time")[0].value = data.time;
element.getElementsByClassName("stime")[0].value = data.stime;
document.getElementById("currenttime").innerHTML = data.curTime;
document.getElementById("currenttrack").innerHTML = data.curTrip;
document.getElementById("counter").innerHTML = data.counter;
document.getElementById("speed").innerHTML = data.curTripSpeed;
};
</script>
<script>
function onlyNumberKey(evt,e) {
// Only ASCII character in that range allowed
var ASCIICode = (evt.which) ? evt.which : evt.keyCode
if (ASCIICode > 31 && (ASCIICode < 48 || ASCIICode > 57) && ASCIICode !=46)
return false;
return true;
}
function chback(e){ //change background to yellow
e.style.backgroundColor = "yellow";
}
</script>
</head><body>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
<div class=" bg-success text-white">
<div class="row">
<div class="col-2 mt-1"><h2><span id="counter">12345</span></h2></div>
<div class="col-3 mt-1"><h2>TRACK <span id="currenttrack">A</span></h2></div>
<div class="col mt-1"><h2 class="text-center">Time: <span id="currenttime">00:00:00</span></h2></div>
<div class="col-3 mt-1 text-end"><h2><span id="speed">123.4</span>Km/h</h2></div>
<hr>
</div>
<!--//Constanta Menu-->
<title>Rally TerraTrip v1 Constanta</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<!--
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
-->
<link href="bootstrap.css" rel="stylesheet">
<script>
function onlyNumberKey(evt,e) {
// Only ASCII character in that range allowed
var ASCIICode = (evt.which) ? evt.which : evt.keyCode
if (ASCIICode > 31 && (ASCIICode < 48 || ASCIICode > 57) && ASCIICode !=46)
return false;
}
function chback(e){ //change background to yellow
var val = e.value;
var okColor = "yellow"
var Warning = "red"
console.log(val);
console.log(e);
console.log(e.classList);
if(e.classList.contains("speed")) {
if(val<100) e.style.backgroundColor = okColor;
else e.style.backgroundColor = Warning;
} else if(e.classList.contains("time")) {
if(val<1000) e.style.backgroundColor = okColor;
else e.style.backgroundColor = Warning;
} else if(e.classList.contains("dist")) {
if(val<1000) e.style.backgroundColor = okColor;
else e.style.backgroundColor = Warning;
} else e.style.backgroundColor = okColor;
// if(val<100) e.style.backgroundColor = "yellow";
// console.log(e);
// if(e.classList.contains("speed")) e.style.backgroundColor = "red";
// e.style.backgroundColor = "yellow";
}
</script>
</head><body onload="loaded();">
<!--
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
-->
<script src="bootstrap.bundle.min.js"></script>
<div class="bg-info text-white">
<!-- <div class="row">
<div class="col-2 mt-1"><h2><span id="counter">12345</span></h2></div>
<div class="col-3 mt-1"><h2>TRACK <span id="currenttrack">A</span></h2></div>
<div class="col mt-1"><h2 class="text-center">Time: <span id="currenttime">00:00:00</span></h2></div>
<div class="col-3 mt-1 text-end"><h2><span id="speed">123.4</span>Km/h</h2></div>
<hr>
</div>
-->
<!--//Constanta Menu-->
<div class="row g-2 align-items-center">
<div class="col-1"></div>
<div class="col-1 text-center "><label class="col-form-label fs-6 fw-bold">Dist(Km)</label></div>
<div class="col-1 text-end">= </div>
<div class="col-1 text-center "><label class="col-form-label fs-6 fw-bold">Speed</label></div>
<div class="col-1"></div>
<div class="col-1 text-center "><label class="col-form-label fs-6 fw-bold">Distance(Km)</label></div>
<div class="col-1"></div>
<div class="col-1 text-center">X</div>
<div class="col-1 text-center "><label class="col-form-label fs-6 fw-bold">Time(min)</label></div>
<div class="col-1"></div>
<div class="col-2 text-center "><label class="col-form-label fs-6 fw-bold">Start Time</label></div>
</div>
)rawliteral";
<div class="row g-2 align-items-center" id="tripA">
<div class="col-1 "><label for="speedA" class="col-form-label fs-4 ms-2 trip">A-></label></div>
<div class="col-2 ">
<input type="text" step="any" maxlength="6" required oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
id="speedA" name="speedA" class="form-control speed" onkeypress="return onlyNumberKey(event,this)" onchange="chback(this)"></div>
const char HTML_CONSTROW[] PROGMEM = R"rawliteral(
<div class="row g-2 align-items-center" id="trip%A%">
<div class="col-1 "><label for="%dist%" class="col-form-label fs-4 ms-1 trip">%A%></label></div>
<div class="col-2">
<input type="text" step="any" maxlength="6" required oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
id="distA" name="distA" class="form-control dist" onkeypress="return onlyNumberKey(event,this)" onchange="chback(this)"></div>
<input type="number" step="any" maxlength="6" required oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
id="%dist%" name="%dist%" class="form-control dist" onkeypress="return onlyNumberKey(event,this)" onchange="chback(this)"></div>
<div class="col-2 ">
<input type="number" step="any" maxlength="6" required oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
id="%speed%" name="%speed%" class="form-control speed" onkeypress="return onlyNumberKey(event,this)" onchange="chback(this)"></div>
<div class="col-2">
<input type="text" maxlength="5" required oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
id="timeA" name="timeA" class="form-control time" onkeypress="return onlyNumberKey(event,this)" onchange="chback(this)"></div>
<input type="number" maxlength="5" required oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
id="%time%" name="%time%" class="form-control time" onkeypress="return onlyNumberKey(event,this)" onchange="chback(this)"></div>
<div class="col-2">
<input type="time" id="stimeA" name="stimeA" class="form-control stime" onchange="chback(this)" required></div>
<div class="col-auto">
<button class="btn btn-primary fw-bold" id="myBtn" onclick="setConstanta(this)">SET A</button></div>
</div>
<div class="row g-2 align-items-center" id="tripB">
<div class="col-1 "><label for="speedB" class="col-form-label fs-4 trip">B-></label></div>
<div class="col-2 ">
<input type="text" step="any" maxlength="6" required oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
id="SpeedB" name="speedB" class="form-control speed" onkeypress="return onlyNumberKey(event,this)" onchange="chback(this)"></div>
<div class="col-2">
<input type="text" step="any" maxlength="6" required oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
id="distB" name="distB" class="form-control dist" onkeypress="return onlyNumberKey(event,this)" onchange="chback(this)"></div>
<div class="col-2">
<input type="text" maxlength="5" required oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
id="timeB" name="timeB" class="form-control time" onkeypress="return onlyNumberKey(event,this)" onchange="chback(this)"></div>
<div class="col-2">
<input type="time" id="stimeB" name="stimeB" class="form-control stime" onchange="chback(this)"></div>
<div class="col-auto">
<button class="btn btn-primary fw-bold" id="myBtn" onclick="setConstanta(this)">SET B</button></div>
<input type="time" id="%stime%" name="%stime%" class="form-control stime" onchange="chback(this)"></div>
<div class="col-2">
<button class="btn btn-primary fw-bold" id="myBtn" onclick="setConstanta(this)">SET %A%</button></div>
</div>
)rawliteral";
const char HTML_CONSTEND[] PROGMEM = R"rawliteral(
<button ondblclick="location.href='/menu';" class="btn btn-primary fw-bold btn-sm mt-2 mb-2 ms-3">Back to Menu</button>
</div>
<button ondblclick="location.href='/menu';" class="btn btn-primary fw-bold btn-sm mt-2 mb-2 ms-3">Back to Menu</button>
</div>
<script>
function setConstanta(e){
e = e || window.event;
var targ1 = e.target || e.srcElement || e;
if (targ1.nodeType == 3) targ1 = targ1.parentNode; // defeat Safari bug
const targ = targ1.closest(".row");
const trip = targ.getElementsByClassName("trip")[0].textContent.split("-")[0];
const speed = targ.getElementsByClassName("speed")[0].value;
if (speed===""){
alert ("Trip "+trip+"-> [Speed] is required");
return;
}
const stime = targ.getElementsByClassName("stime")[0].value;
if (stime===""){
alert ("Trip "+trip+"-> [Start Time] is required");
return;
}
// targ.getElementsByClassName("speed")[0].value = "345" //trial change backColor
// targ.getElementsByClassName("speed")[0].style.backgroundColor = "white"
var dist = targ.getElementsByClassName("dist")[0].value;
const time = targ.getElementsByClassName("time")[0].value;
var full_data='{"trip":"'+trip+'", "speed":"'+speed+'", "dist":"'+dist+'", "time":"'+time+'", "stime":"'+stime+'"}';
console.log(full_data);
sendjson(full_data);
};
function compare(name){
let name1=name || "";
console.log(name, name1)
return name1;
};
function sendjson(data){
var xhr = new XMLHttpRequest();
var url = "/rest/endpoint";
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
console.log(xhr.responseText);
if (xhr.readyState === 4 && xhr.status === 200) {
var json = JSON.parse(xhr.responseText);
console.log(json.trip + ", " + json.speed + ", " + json.dist + ", " + json.time + ", " + json.stime);
if (json.ok) {
var tripID = document.getElementById("trip"+json.trip);
const speed = tripID.getElementsByClassName("speed"+json.trip);
const dist = tripID.getElementsByClassName("dist"+json.trip);
const time = tripID.getElementsByClassName("time"+json.trip);
const stime = tripID.getElementsByClassName("stime"+json.trip);
speed.value = json.speed;
dist.value = json.dist;
time.value = json.time;
stime.value = json.stime;
speed.style.backgroundColor = "green"
dist.style.backgroundColor = "green"
time.style.backgroundColor = "green"
stime.style.backgroundColor = "green"
console.log("result:"+json.trip + ", " + speed.value + ", " + dist.value + ", " + time.value + ", " + stime.value);
}
<script>
// document.addEventListener("DOMContentLoaded", function() {
function loaded(){
var xhr = new XMLHttpRequest();
var url = "/rest/loadconst";
console.log("before open");
// for (var i=65; i<81; i++){
xhr.open("POST", url, true);
console.log("before setrequest");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
console.log(xhr.responseText);
if (xhr.readyState === 4 && xhr.status === 200) {
var jsonAllTrip = JSON.parse(xhr.responseText);
const jsonlen = Object.keys(jsonAllTrip.alltrip).length;
console.log(jsonAllTrip.alltrip[0]);
console.log("jsondlen="+jsonlen);
var jsontemp;
for (var i=0; i<jsonlen; i++){
jsontemp = jsonAllTrip.alltrip[i];
console.log(jsontemp);
var json = JSON.parse(JSON.stringify(jsontemp));
console.log(json);
}
};
console.log(data);
var datajson = JSON.stringify(data);
console.log(datajson);
xhr.send(data);
}
</script>
</body></html>
// if (json.ok) {
parsingjson(json);
}
//console.log(json.trip + ", " + json.speed + ", " + json.dist + ", " + json.time + ", " + json.stime);
console.log(json);
}
};
let data = '{"req":"B"}'
console.log(data);
var datajson = JSON.stringify(data);
console.log(datajson);
// console.log(String.fromCharCode(i));
// data = '{"req":"'+String.fromCharCode(i)+'"}'
xhr.send(data);
// }
};
function setConstanta(e){
e = e || window.event;
var targ1 = e.target || e.srcElement || e;
if (targ1.nodeType == 3) targ1 = targ1.parentNode; // defeat Safari bug
const targ = targ1.closest(".row");
const trip = targ.getElementsByClassName("trip")[0].textContent[0];
const speed = targ.getElementsByClassName("speed")[0].value;
const dist = targ.getElementsByClassName("dist")[0].value;
const time = targ.getElementsByClassName("time")[0].value;
if (!(dist<1000)){
alert ("Trip "+trip+"-> [Dist] cannot exceed 1000 Km");
return;
}
if (speed===""){
alert ("Trip "+trip+"-> [Speed] is required");
return;
}
if (!(speed<100)){
alert ("Trip "+trip+"-> [Speed] cannot exceed 100 Km/h");
return;
}
if (!(time<1000)){
alert ("Trip "+trip+"-> [Time] cannot exceed 1000 minutes");
return;
}
const stime = targ.getElementsByClassName("stime")[0].value;
if (stime===""){
alert ("Trip "+trip+"-> [Start Time] is required");
return;
}
// targ.getElementsByClassName("speed")[0].value = "345" //trial change backColor
// targ.getElementsByClassName("speed")[0].style.backgroundColor = "white"
var full_data='{"trip":"'+trip+'", "speed":"'+speed+'", "dist":"'+dist+'", "time":"'+time+'", "stime":"'+stime+'"}';
console.log(full_data);
sendjson(full_data);
};
function parsingjson(json){
console.log(json);
var tripID = document.getElementById("trip"+json.trip);
console.log(tripID);
const speed = tripID.getElementsByClassName("speed")[0];
const dist = tripID.getElementsByClassName("dist")[0];
const time = tripID.getElementsByClassName("time")[0];
const stime = tripID.getElementsByClassName("stime")[0];
setValBackColor(speed, json.speed);
setValBackColor(dist, json.dist);
setValBackColor(time, json.time);
setValBackColor(stime, json.stime);
// speed.value = json.speed;
// dist.value = json.dist;
// time.value = json.time;
// stime.value = json.stime;
// speed.style.backgroundColor = "#94C4E2"// #6495ED
// dist.style.backgroundColor = "#94C4E2"
// time.style.backgroundColor = "#94C4E2"
// stime.style.backgroundColor = "#94C4E2"
console.log("result ok:"+json.trip + ", " + speed.value + ", " + dist.value + ", " + time.value + ", " + stime.value);
};
function setValBackColor(elem, jsonval){
if (jsonval) {
elem.value = jsonval;
elem.style.backgroundColor = "#ABEBC6";//"#E5E7E9";//"#C0C0C0";//"#94C4E2";
} else {
elem.style.backgroundColor = "white";
}
};
function sendjson(data){
var xhr = new XMLHttpRequest();
var url = "/rest/endpoint";
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
console.log(xhr.responseText);
if (xhr.readyState === 4 && xhr.status === 200) {
var json = JSON.parse(xhr.responseText);
console.log(json.trip + ", " + json.speed + ", " + json.dist + ", " + json.time + ", " + json.stime);
if (json.ok) {
parsingjson(json);
}
//console.log(json.trip + ", " + json.speed + ", " + json.dist + ", " + json.time + ", " + json.stime);
console.log(json);
}
};
console.log(data);
var datajson = JSON.stringify(data);
console.log(datajson);
xhr.send(data);
}
</script>
</body></html>

View File

@ -17,7 +17,7 @@
<div class="card-header"><h1>MENU</h1></div>
<div class="card-body">
<div class="row align-self-end g-1">
<div class="col text-center "><button onclick="location.href='/startrally1';" id="startrally" name="startrally" class="btn btn-primary btn-lg me-2 mb-2">RALLY</button></div>
<div class="col text-center "><button onclick="location.href='/startrally';" id="startrally" name="startrally" class="btn btn-primary btn-lg me-2 mb-2">RALLY</button></div>
<div class="col text-center"><button onclick="location.href='/calibration';" id="calibration" name="calibration" class="btn btn-primary me-2 mb-2">CALIBRATION</button></div>
<div class="col text-center"><button onclick="location.href='/constanta';" id="constanta" name="constanta" class="btn btn-primary me-2 mb-2">CONSTANTA</button></div>
<div class="col text-center"><button onclick="location.href='/settime';" id="constanta" name="constanta" class="btn btn-primary me-2 mb-2">Set TIME</button></div>

View File

@ -1,199 +1,230 @@
const char HTML_CONSTHEADER[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
<title>Rally TerraTrip v1 Constanta</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<!--
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
-->
<link href="bootstrap.css" rel="stylesheet">
<script>
function onlyNumberKey(evt,e) {
// Only ASCII character in that range allowed
var ASCIICode = (evt.which) ? evt.which : evt.keyCode
if (ASCIICode > 31 && (ASCIICode < 48 || ASCIICode > 57) && ASCIICode !=46)
return false;
return true;
}
function chback(e){ //change background to yellow
e.style.backgroundColor = "yellow";
}
</script>
</head><body onload="loaded();">
<title>Rally TerraTrip v1 Constanta</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<!--
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
-->
<link href="bootstrap.css" rel="stylesheet">
<script>
function onlyNumberKey(evt,e) {
// Only ASCII character in that range allowed
var ASCIICode = (evt.which) ? evt.which : evt.keyCode
if (ASCIICode > 31 && (ASCIICode < 48 || ASCIICode > 57) && ASCIICode !=46)
return false;
}
function chback(e){ //change background to yellow
var val = e.value;
var okColor = "yellow"
var Warning = "red"
console.log(val);
console.log(e);
console.log(e.classList);
if(e.classList.contains("speed")) {
if(val<100) e.style.backgroundColor = okColor;
else e.style.backgroundColor = Warning;
} else if(e.classList.contains("time")) {
if(val<1000) e.style.backgroundColor = okColor;
else e.style.backgroundColor = Warning;
} else if(e.classList.contains("dist")) {
if(val<1000) e.style.backgroundColor = okColor;
else e.style.backgroundColor = Warning;
} else e.style.backgroundColor = okColor;
// if(val<100) e.style.backgroundColor = "yellow";
// console.log(e);
// if(e.classList.contains("speed")) e.style.backgroundColor = "red";
// e.style.backgroundColor = "yellow";
}
</script>
</head><body onload="loaded();">
<!--
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
-->
<script src="bootstrap.bundle.min.js"></script>
<div class="bg-info text-white">
<div class="bg-info text-white">
<!-- <div class="row">
<div class="col-2 mt-1"><h2><span id="counter">12345</span></h2></div>
<div class="col-3 mt-1"><h2>TRACK <span id="currenttrack">A</span></h2></div>
<div class="col mt-1"><h2 class="text-center">Time: <span id="currenttime">00:00:00</span></h2></div>
<div class="col-3 mt-1 text-end"><h2><span id="speed">123.4</span>Km/h</h2></div>
<hr>
</div>
<div class="col-2 mt-1"><h2><span id="counter">12345</span></h2></div>
<div class="col-3 mt-1"><h2>TRACK <span id="currenttrack">A</span></h2></div>
<div class="col mt-1"><h2 class="text-center">Time: <span id="currenttime">00:00:00</span></h2></div>
<div class="col-3 mt-1 text-end"><h2><span id="speed">123.4</span>Km/h</h2></div>
<hr>
</div>
-->
<!--//Constanta Menu-->
<div class="row g-2 align-items-center">
<div class="col-1"></div>
<div class="col-1 text-center "><label class="col-form-label fs-6 fw-bold">Dist(Km)</label></div>
<div class="col-1 text-end">= </div>
<div class="col-1 text-center "><label class="col-form-label fs-6 fw-bold">Speed</label></div>
<div class="col-1 text-center">X</div>
<div class="col-1 text-center "><label class="col-form-label fs-6 fw-bold">Time(min)</label></div>
<div class="col-1"></div>
<div class="col-2 text-center "><label class="col-form-label fs-6 fw-bold">Start Time</label></div>
</div>
<!--//Constanta Menu-->
<div class="row g-2 align-items-center">
<div class="col-1"></div>
<div class="col-1 text-center "><label class="col-form-label fs-6 fw-bold">Dist(Km)</label></div>
<div class="col-1 text-end">= </div>
<div class="col-1 text-center "><label class="col-form-label fs-6 fw-bold">Speed</label></div>
<div class="col-1 text-center">X</div>
<div class="col-1 text-center "><label class="col-form-label fs-6 fw-bold">Time(min)</label></div>
<div class="col-1"></div>
<div class="col-2 text-center "><label class="col-form-label fs-6 fw-bold">Start Time</label></div>
</div>
)rawliteral";
const char HTML_CONSTROW[] PROGMEM = R"rawliteral(
<div class="row g-2 align-items-center" id="trip%A%">
<div class="col-1 "><label for="%dist%" class="col-form-label fs-4 ms-1 trip">%A%></label></div>
<div class="col-2">
<input type="number" step="any" maxlength="6" required oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
id="%dist%" name="%dist%" class="form-control dist" onkeypress="return onlyNumberKey(event,this)" onchange="chback(this)"></div>
<div class="col-2 ">
<input type="number" step="any" maxlength="6" required oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
id="%speed%" name="%speed%" class="form-control speed" onkeypress="return onlyNumberKey(event,this)" onchange="chback(this)"></div>
<div class="col-2">
<input type="number" maxlength="5" required oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
id="%time%" name="%time%" class="form-control time" onkeypress="return onlyNumberKey(event,this)" onchange="chback(this)"></div>
<div class="col-2">
<input type="time" id="%stime%" name="%stime%" class="form-control stime" onchange="chback(this)"></div>
<div class="col-2">
<button class="btn btn-primary fw-bold" id="myBtn" onclick="setConstanta(this)">SET %A%</button></div>
</div>
<div class="row g-2 align-items-center" id="trip%A%">
<div class="col-1 "><label for="%dist%" class="col-form-label fs-4 ms-1 trip">%A%></label></div>
<div class="col-2">
<input type="number" step="any" maxlength="6" required oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
id="%dist%" name="%dist%" class="form-control dist" onkeypress="return onlyNumberKey(event,this)" onchange="chback(this)"></div>
<div class="col-2 ">
<input type="number" step="any" maxlength="6" required oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
id="%speed%" name="%speed%" class="form-control speed" onkeypress="return onlyNumberKey(event,this)" onchange="chback(this)"></div>
<div class="col-2">
<input type="number" maxlength="5" required oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
id="%time%" name="%time%" class="form-control time" onkeypress="return onlyNumberKey(event,this)" onchange="chback(this)"></div>
<div class="col-2">
<input type="time" id="%stime%" name="%stime%" class="form-control stime" onchange="chback(this)"></div>
<div class="col-2">
<button class="btn btn-primary fw-bold" id="myBtn" onclick="setConstanta(this)">SET %A%</button></div>
</div>
)rawliteral";
const char HTML_CONSTEND[] PROGMEM = R"rawliteral(
<button ondblclick="location.href='/menu';" class="btn btn-primary fw-bold btn-sm mt-2 mb-2 ms-3">Back to Menu</button>
</div>
<script>
// document.addEventListener("DOMContentLoaded", function() {
function loaded(){
var xhr = new XMLHttpRequest();
var url = "/rest/loadconst";
console.log("before open");
// for (var i=65; i<81; i++){
xhr.open("POST", url, true);
console.log("before setrequest");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
console.log(xhr.responseText);
if (xhr.readyState === 4 && xhr.status === 200) {
var jsonAllTrip = JSON.parse(xhr.responseText);
const jsonlen = Object.keys(jsonAllTrip.alltrip).length;
console.log(jsonAllTrip.alltrip[0]);
console.log("jsondlen="+jsonlen);
var jsontemp;
for (var i=0; i<jsonlen; i++){
jsontemp = jsonAllTrip.alltrip[i];
console.log(jsontemp);
var json = JSON.parse(JSON.stringify(jsontemp));
console.log(json);
// if (json.ok) {
parsingjson(json);
}
//console.log(json.trip + ", " + json.speed + ", " + json.dist + ", " + json.time + ", " + json.stime);
console.log(json);
}
};
let data = '{"req":"B"}'
console.log(data);
var datajson = JSON.stringify(data);
console.log(datajson);
// console.log(String.fromCharCode(i));
// data = '{"req":"'+String.fromCharCode(i)+'"}'
xhr.send(data);
// }
};
<button ondblclick="location.href='/menu';" class="btn btn-primary fw-bold btn-sm mt-2 mb-2 ms-3">Back to Menu</button>
</div>
function setConstanta(e){
e = e || window.event;
var targ1 = e.target || e.srcElement || e;
if (targ1.nodeType == 3) targ1 = targ1.parentNode; // defeat Safari bug
const targ = targ1.closest(".row");
const trip = targ.getElementsByClassName("trip")[0].textContent[0];
const speed = targ.getElementsByClassName("speed")[0].value;
if (speed===""){
alert ("Trip "+trip+"-> [Speed] is required");
return;
<script>
// document.addEventListener("DOMContentLoaded", function() {
function loaded(){
var xhr = new XMLHttpRequest();
var url = "/rest/loadconst";
console.log("before open");
// for (var i=65; i<81; i++){
xhr.open("POST", url, true);
console.log("before setrequest");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
console.log(xhr.responseText);
if (xhr.readyState === 4 && xhr.status === 200) {
var jsonAllTrip = JSON.parse(xhr.responseText);
const jsonlen = Object.keys(jsonAllTrip.alltrip).length;
console.log(jsonAllTrip.alltrip[0]);
console.log("jsondlen="+jsonlen);
var jsontemp;
for (var i=0; i<jsonlen; i++){
jsontemp = jsonAllTrip.alltrip[i];
console.log(jsontemp);
var json = JSON.parse(JSON.stringify(jsontemp));
console.log(json);
// if (json.ok) {
parsingjson(json);
}
//console.log(json.trip + ", " + json.speed + ", " + json.dist + ", " + json.time + ", " + json.stime);
console.log(json);
}
const stime = targ.getElementsByClassName("stime")[0].value;
if (stime===""){
alert ("Trip "+trip+"-> [Start Time] is required");
return;
}
// targ.getElementsByClassName("speed")[0].value = "345" //trial change backColor
// targ.getElementsByClassName("speed")[0].style.backgroundColor = "white"
const dist = targ.getElementsByClassName("dist")[0].value;
const time = targ.getElementsByClassName("time")[0].value;
};
let data = '{"req":"B"}'
console.log(data);
var datajson = JSON.stringify(data);
console.log(datajson);
var full_data='{"trip":"'+trip+'", "speed":"'+speed+'", "dist":"'+dist+'", "time":"'+time+'", "stime":"'+stime+'"}';
console.log(full_data);
sendjson(full_data);
};
// console.log(String.fromCharCode(i));
// data = '{"req":"'+String.fromCharCode(i)+'"}'
xhr.send(data);
// }
};
function parsingjson(json){
console.log(json);
var tripID = document.getElementById("trip"+json.trip);
console.log(tripID);
const speed = tripID.getElementsByClassName("speed")[0];
const dist = tripID.getElementsByClassName("dist")[0];
const time = tripID.getElementsByClassName("time")[0];
const stime = tripID.getElementsByClassName("stime")[0];
setValBackColor(speed, json.speed);
setValBackColor(dist, json.dist);
setValBackColor(time, json.time);
setValBackColor(stime, json.stime);
// speed.value = json.speed;
// dist.value = json.dist;
// time.value = json.time;
// stime.value = json.stime;
// speed.style.backgroundColor = "#94C4E2"// #6495ED
// dist.style.backgroundColor = "#94C4E2"
// time.style.backgroundColor = "#94C4E2"
// stime.style.backgroundColor = "#94C4E2"
console.log("result ok:"+json.trip + ", " + speed.value + ", " + dist.value + ", " + time.value + ", " + stime.value);
};
function setValBackColor(elem, jsonval){
if (jsonval) {
elem.value = jsonval;
elem.style.backgroundColor = "#ABEBC6";//"#E5E7E9";//"#C0C0C0";//"#94C4E2";
} else {
elem.style.backgroundColor = "white";
}
};
function sendjson(data){
var xhr = new XMLHttpRequest();
var url = "/rest/endpoint";
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
console.log(xhr.responseText);
if (xhr.readyState === 4 && xhr.status === 200) {
var json = JSON.parse(xhr.responseText);
console.log(json.trip + ", " + json.speed + ", " + json.dist + ", " + json.time + ", " + json.stime);
if (json.ok) {
parsingjson(json);
}
//console.log(json.trip + ", " + json.speed + ", " + json.dist + ", " + json.time + ", " + json.stime);
console.log(json);
}
};
console.log(data);
var datajson = JSON.stringify(data);
console.log(datajson);
xhr.send(data);
function setConstanta(e){
e = e || window.event;
var targ1 = e.target || e.srcElement || e;
if (targ1.nodeType == 3) targ1 = targ1.parentNode; // defeat Safari bug
const targ = targ1.closest(".row");
const trip = targ.getElementsByClassName("trip")[0].textContent[0];
const speed = targ.getElementsByClassName("speed")[0].value;
const dist = targ.getElementsByClassName("dist")[0].value;
const time = targ.getElementsByClassName("time")[0].value;
if (!(dist<1000)){
alert ("Trip "+trip+"-> [Dist] cannot exceed 1000 Km");
return;
}
</script>
</body></html>
if (speed===""){
alert ("Trip "+trip+"-> [Speed] is required");
return;
}
if (!(speed<100)){
alert ("Trip "+trip+"-> [Speed] cannot exceed 100 Km/h");
return;
}
if (!(time<1000)){
alert ("Trip "+trip+"-> [Time] cannot exceed 1000 minutes");
return;
}
const stime = targ.getElementsByClassName("stime")[0].value;
if (stime===""){
alert ("Trip "+trip+"-> [Start Time] is required");
return;
}
// targ.getElementsByClassName("speed")[0].value = "345" //trial change backColor
// targ.getElementsByClassName("speed")[0].style.backgroundColor = "white"
var full_data='{"trip":"'+trip+'", "speed":"'+speed+'", "dist":"'+dist+'", "time":"'+time+'", "stime":"'+stime+'"}';
console.log(full_data);
sendjson(full_data);
};
function parsingjson(json){
console.log(json);
var tripID = document.getElementById("trip"+json.trip);
console.log(tripID);
const speed = tripID.getElementsByClassName("speed")[0];
const dist = tripID.getElementsByClassName("dist")[0];
const time = tripID.getElementsByClassName("time")[0];
const stime = tripID.getElementsByClassName("stime")[0];
setValBackColor(speed, json.speed);
setValBackColor(dist, json.dist);
setValBackColor(time, json.time);
setValBackColor(stime, json.stime);
// speed.value = json.speed;
// dist.value = json.dist;
// time.value = json.time;
// stime.value = json.stime;
// speed.style.backgroundColor = "#94C4E2"// #6495ED
// dist.style.backgroundColor = "#94C4E2"
// time.style.backgroundColor = "#94C4E2"
// stime.style.backgroundColor = "#94C4E2"
console.log("result ok:"+json.trip + ", " + speed.value + ", " + dist.value + ", " + time.value + ", " + stime.value);
};
function setValBackColor(elem, jsonval){
if (jsonval) {
elem.value = jsonval;
elem.style.backgroundColor = "#ABEBC6";//"#E5E7E9";//"#C0C0C0";//"#94C4E2";
} else {
elem.style.backgroundColor = "white";
}
};
function sendjson(data){
var xhr = new XMLHttpRequest();
var url = "/rest/endpoint";
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
console.log(xhr.responseText);
if (xhr.readyState === 4 && xhr.status === 200) {
var json = JSON.parse(xhr.responseText);
console.log(json.trip + ", " + json.speed + ", " + json.dist + ", " + json.time + ", " + json.stime);
if (json.ok) {
parsingjson(json);
}
//console.log(json.trip + ", " + json.speed + ", " + json.dist + ", " + json.time + ", " + json.stime);
console.log(json);
}
};
console.log(data);
var datajson = JSON.stringify(data);
console.log(datajson);
xhr.send(data);
}
</script>
</body></html>
)rawliteral";

View File

@ -152,6 +152,7 @@ const int lcdRows = 4;
///lolin esp32 lite i2c pin
#define I2C_SDA 15
#define I2C_SCL 13
#define FREQHZ 400000U
#define LED_BUILTIN 22 // LED built in pada ESP32 Lolin32 Lite
// set LCD address, number of columns and rows
// if you don't know your display address, run an I2C scanner sketch
@ -981,6 +982,30 @@ void constantatodigit()
//digit6=(int)((constanta*10000 - (int)(constanta*10000))*10);
}
void setSpiffSpeedInConstanta(float mConstanta, uint8_t setSpiffcurTrip){
char filename[7] = "/tripZ";
setSpiffcurTrip+=65;
filename[5]=setSpiffcurTrip;
Serial.println(filename);
Serial.println(mConstanta);
String result = readFile(SPIFFS, filename);
result.reserve(128);
DynamicJsonDocument doc(128);
deserializeJson(doc, result);
if (doc["trip"].as<String>()=="null") doc["trip"]=String(char(setSpiffcurTrip));
if (doc["dist"].as<String>()=="null") doc["dist"]="";
if (doc["time"].as<String>()=="null") doc["time"]="";
if (doc["stime"].as<String>()=="null") doc["stime"]="";
String strConstanta = String(mConstanta,4);
Serial.println(strConstanta);
doc["speed"] = strConstanta;
result="";
serializeJson(doc,result);
writeFile(SPIFFS, filename, result.c_str());
Serial.print("Write speed:");Serial.println(result);
Trip[setSpiffcurTrip].speed = mConstanta;
}
void setMemSpeedInConstanta(float constanta, uint8_t setmemcurTrip){
int pointeradd = ((TRIPADDRESS+setmemcurTrip)*32);
mem.writeFloat(pointeradd, constanta);
@ -995,12 +1020,38 @@ float getMemSpeedInConstanta(uint8_t getmemSpeedcurTrip){
}
return x;
}
void setMemStime(unsigned long valuesettime, uint8_t setmemssTimecurTrip){
void setSpiffStime(unsigned long mvaluesettime, uint8_t setSpiffcurTrip){
char filename[7] = "/tripZ";
setSpiffcurTrip+=65;
filename[5]=setSpiffcurTrip;
Serial.println(filename);
Serial.println(mvaluesettime);
String result = readFile(SPIFFS, filename);
result.reserve(128);
DynamicJsonDocument doc(128);
deserializeJson(doc, result);
char msTime[6];
byte sHour, sMin;
sHour = mvaluesettime/65536;
sMin = (mvaluesettime/256)-sHour*256;
sprintf(msTime, "%02u:%02u", sHour, sMin);
Serial.print("dist:");Serial.print(doc["dist"].as<String>());Serial.println(";");
if (doc["trip"].as<String>()=="null") doc["trip"]=String(char(setSpiffcurTrip));
if (doc["dist"].as<String>()=="null") doc["dist"]="";
if (doc["speed"].as<String>()=="null") doc["speed"]="";
if (doc["time"].as<String>()=="null") doc["time"]="";
doc["stime"]=msTime;
result="";
serializeJson(doc,result);
writeFile(SPIFFS, filename, result.c_str());
Serial.print("Write sTime:");Serial.println(result);
}
void setMemStime(unsigned long mvaluesettime, uint8_t setmemssTimecurTrip){
int pointeradd = ((TRIPADDRESS+setmemssTimecurTrip)*32+4);
mem.writeLong(pointeradd, valuesettime);
Trip[setmemssTimecurTrip].startHour = (valuesettime/65536); //starttracthour;
Trip[setmemssTimecurTrip].startMin = (valuesettime/256)-Trip[setmemssTimecurTrip].startHour*256; // starttractmin;
Trip[setmemssTimecurTrip].startSec = valuesettime-((Trip[setmemssTimecurTrip].startHour*256 + Trip[curTrip].startMin)*256);//starttractsec;
mem.writeLong(pointeradd, mvaluesettime);
Trip[setmemssTimecurTrip].startHour = (mvaluesettime/65536); //starttracthour;
Trip[setmemssTimecurTrip].startMin = (mvaluesettime/256)-Trip[setmemssTimecurTrip].startHour*256; // starttractmin;
Trip[setmemssTimecurTrip].startSec = mvaluesettime-((Trip[setmemssTimecurTrip].startHour*256 + Trip[curTrip].startMin)*256);//starttractsec;
Serial.print(Trip[setmemssTimecurTrip].startHour);Serial.print(";");
Serial.print(Trip[setmemssTimecurTrip].startMin);Serial.print(";");
Serial.println(Trip[setmemssTimecurTrip].startSec);
@ -2228,6 +2279,42 @@ void fillTripArray(){
}
}
void handelSetWifi(AsyncWebServerRequest *request){
String inputMessage;
boolean bolrestart=false;
boolean POST=true;
Serial.print("/setwifi:");
// GET inputString value on <ESP_IP>/get?inputString=<inputMessage>
if (request->hasParam(PARAM_SSID, POST)) {
inputMessage = request->getParam(PARAM_SSID, POST )->value();
Serial.print(inputMessage);Serial.print(";");
if (inputMessage!=""){
Serial.print(inputMessage);
writeFile(SPIFFS, "/ssidString.txt", inputMessage.c_str());
delay(50);
bolrestart=true;
}
}
// GET inputPwd value on <ESP_IP>/wifi/get?inputPwd=<inputMessage>
if (request->hasParam(PARAM_PWD, POST)) {
inputMessage = request->getParam(PARAM_PWD, POST)->value();
Serial.print(inputMessage);Serial.print(";");
if (inputMessage!=""){
writeFile(SPIFFS, "/inputPwd.txt", inputMessage.c_str());
delay(50);
bolrestart=true;
}
}
else {
inputMessage = "No message sent";
}
Serial.println("");
if (bolrestart) {
ESP.restart();
}
// Serial.println("ini /setwifi aja");Serial.println(inputMessage);
request->send(200, "text/text", inputMessage);
}
void handleConstantaHTML(AsyncWebServerRequest *request) {
//PAGE.replace("%serveripaddress%", WiFi.localIP().toString());
//request->send_P(200, "text/html", HTML_CALIBRATION, processor);
@ -2335,7 +2422,6 @@ void handlesetConst(AsyncWebServerRequest *request, JsonVariant &json){
// request->send(200, "text/plain", hasil); // handle data and respond
serializeJson(data, *response);
request->send(response);
// request->send(200, "text/plain", hasil);
isloadingConst=false;
}
@ -2412,39 +2498,26 @@ void setup() {
//
//
//#ifdef DEBUG
Serial.begin(115200);
Serial.println("Starting Rally");
Serial.begin(115200);
Serial.println("Starting Rally");
//#endif
// pinMode(ledPin, OUTPUT);
uint32_t freqhz=400000;
// Wire.begin(15, 13, freqhx); //for lolin32lite sda=15; scl=13
pinMode(simulatorPWMPin,OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
pinMode(interruptPin, INPUT); //Pull down using resistor to ground
attachInterrupt(digitalPinToInterrupt(interruptPin), blink, FALLING);
pinMode(simulatorPWMPin,OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
pinMode(interruptPin, INPUT); //Pull down using resistor to ground
attachInterrupt(digitalPinToInterrupt(interruptPin), blink, FALLING);
// attachInterrupt(digitalPinToInterrupt(interruptPin), blink, FALLING);
// attachInterrupt(interruptPin, isr, FALLING);
// Wire.begin(I2C_SDA, I2C_SCL); //for lolin32lite sda=15; scl=13
// Wire.begin(15, 13); //for lolin32lite sda=15; scl=13
// pinMode(UP_pin, INPUT_PULLUP); ///
// pinMode(DOWN_pin, INPUT_PULLUP); ///
// pinMode(LEFT_pin, INPUT_PULLUP); ///
// pinMode(RIGHT_pin, INPUT_PULLUP); ///
// pinMode(OK_pin, INPUT_PULLUP); ///
btnUP.begin(); /// using JC_BUTTON harus ada begin
btnDN.begin();
btnLF.begin();
btnRF.begin();
btnOK.begin();
btnESC.begin();
//DS3231_init(DS3231_INTCN);
// //memset(recv, 0, BUFF_MAX);
btnUP.begin(); /// using JC_BUTTON harus ada begin
btnDN.begin();
btnLF.begin();
btnRF.begin();
btnOK.begin();
btnESC.begin();
//DS3231_init(DS3231_INTCN);
// //memset(recv, 0, BUFF_MAX);
#ifdef DEBUG
Serial.println("GET time");
Serial.println("GET time");
#endif
/*
Trip[0].sub = "A";
@ -2461,75 +2534,53 @@ Trip[9].startSec = 58;
//Serial.println(Trip[0].sub);Serial.println(Trip[0].speed);Serial.println(Trip[0].startHour);Serial.println(Trip[0].startMin);Serial.println(Trip[0].startSec);
//Serial.println(Trip[0].distance);
//Serial.println(Trip[0].subTime);
// uint32_t freqhz=400000;
Wire.begin(I2C_SDA, I2C_SCL, FREQHZ); //for lolin32lite sda=15; scl=13 //Dont move up or down
// lcd.init();
// lcd.backlight();
// lcd.begin(20, 4);
// // if(lcd.begin(20, 4))
// // {
// // // begin() failed so blink the onboard LED if possible
// // return; // this never returns
// // }
// lcd.setBacklight(0xff);
// // Wire.setClock(100000L); // set i2c clock bit rate, if asked
// lcd.print("i2c clock:");
// lcd.setCursor(0,1);
// lcd.print(Wire.getClock());
// lcd.print(" Hz");
// delay(3000);
Wire.begin(I2C_SDA, I2C_SCL, freqhz); //for lolin32lite sda=15; scl=13
//**************************LCD Setup********************************
//**************************LCD Setup********************************
delay(100);
// lcd.begin (20,4); // initialize the lcd
// lcd.init();
lcd.begin();
// lcd2.begin();
// Wire.begin(I2C_SDA, I2C_SCL); //for lolin32lite sda=15; scl=13
// Switch on the backlight
// lcd.begin (20,4); // initialize the lcd
// lcd.init();
lcd.begin();
// lcd2.begin();
// Switch on the backlight
/// lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
// lcd.backlight();
// lcd2.backlight();
// lcd.backlight();
// lcd2.backlight();
/// lcd.setBacklight(LED_ON);
// lcd2.print("hello rally20");
//***************************END LCD Setup********************************
getCalibJson.reserve(512);
getRallyJson.reserve(512);
// lcd2.print("hello rally20");
//***************************END LCD Setup********************************
getCalibJson.reserve(512);
getRallyJson.reserve(512);
#ifdef DEBUG
Serial.println("Setting time");
Serial.println("Setting time");
#endif
//char a[]="304022129022016";
DS3231_init(DS3231_CONTROL_INTCN);
DS3231_get(&t); //Get time
DS3231_init(DS3231_CONTROL_INTCN);
DS3231_get(&t); //Get time
blinkON=false;
sec60=t.sec;
min60=t.min;
hour24=t.hour;
blinkON=false;
sec60=t.sec;
min60=t.min;
hour24=t.hour;
delay(100); // delay for reading mem.read
//mainMenu();
printUPchar();
printDOWNchar();
count1 = memretrieveLong(count1Address, RRcountSIZE, count1Seq); //(int startaddress, byte RRsize, unsigned long seq)
Serial.println(count1Seq);
int countaddresspointer = count1count2diffAddress*32;
Serial.print(countaddresspointer);
count1count2diff = mem.readLong(countaddresspointer);
//count1count2diff = mem.readLong((count1count2diffAddress*32));
count2 = count1 - count1count2diff;
//printmemLong(0,20); //startaddress, size
Serial.print("count1=");Serial.print(count1);Serial.print(";count2=");Serial.print(count2);Serial.print("countdiff=");Serial.println(count1count2diff);
delay(100); // delay for reading mem.read
//mainMenu();
printUPchar();
printDOWNchar();
count1 = memretrieveLong(count1Address, RRcountSIZE, count1Seq); //(int startaddress, byte RRsize, unsigned long seq)
Serial.println(count1Seq);
int countaddresspointer = count1count2diffAddress*32;
Serial.print(countaddresspointer);
count1count2diff = mem.readLong(countaddresspointer);
//count1count2diff = mem.readLong((count1count2diffAddress*32));
count2 = count1 - count1count2diff;
//printmemLong(0,20); //startaddress, size
Serial.print("count1=");Serial.print(count1);Serial.print(";count2=");Serial.print(count2);Serial.print("countdiff=");Serial.println(count1count2diff);
// // TESTING MEM AT24cx EEPROM check the address in the library #define ..... 0x57
// Serial.println("Write 42 to address 12");
@ -2539,70 +2590,70 @@ DS3231_init(DS3231_CONTROL_INTCN);
// Serial.print("... read: ");
// Serial.println(b, DEC);
// Serial.println();
//count1Seq = 4294967290;
//count1Seq = 4294967290;
/*
for (int i=0; i<25 ; i++){
count1Seq++;
//Serial.println(count1Seq);
//memwritingLong(rrcountpointer1, count1Seq, count1+1, RRcountSIZE );
memwritingLong(count1Address, RRcountSIZE, count1Seq, count1);//(int startaddress, byte RRsize, unsigned long seq, unsigned long Data)
}
*/
//mem.writeLong(896, 110025); to reset CALIBRATION value to CRV
/*
starttracthour=mem.read(770);
starttractmin=mem.read(769);
starttractsec=mem.read(768);
*/
for (int i=0; i<25 ; i++){
count1Seq++;
//Serial.println(count1Seq);
//memwritingLong(rrcountpointer1, count1Seq, count1+1, RRcountSIZE );
memwritingLong(count1Address, RRcountSIZE, count1Seq, count1);//(int startaddress, byte RRsize, unsigned long seq, unsigned long Data)
}
*/
//mem.writeLong(896, 110025); to reset CALIBRATION value to CRV
/*
starttracthour=mem.read(770);
starttractmin=mem.read(769);
starttractsec=mem.read(768);
*/
// for (int i = 0; i<TRIPSIZE; i++) {
// }
for (int i = 0; i<TRIPSIZE; i++) { //reading Trip
Trip[i].sub = char(i+65);
memretrieveTrip(i, (TRIPADDRESS+i)*32);
for (int i = 0; i<TRIPSIZE; i++) { //reading Trip
Trip[i].sub = char(i+65);
memretrieveTrip(i, (TRIPADDRESS+i)*32);
// Serial.print(Trip[i].sub);Serial.print(Trip[i].speed,5); Serial.print(";"); Serial.print(Trip[i].startHour); Serial.print(":");
// Serial.print(Trip[i].startMin); Serial.print(":");Serial.print(Trip[i].startSec); Serial.println(";");
}
starttracthour=Trip[curTrip].startHour;
starttractmin=Trip[curTrip].startMin;
starttractsec=Trip[curTrip].startSec;
if (starttracthour>23) starttracthour = 23;
if (starttractmin>59) starttractmin = 59;
if (starttractsec>59) starttractsec = 59;
//constanta=mem.readFloat(800);
constanta = Trip[curTrip].speed;
if ((constanta > 150) || (constanta < 0)) constanta = 60; /// aslinya if ((constanta > 150) || (constanta < 0)) constanta = 60;
long m = mem.readLong(896); //read calibration value;
if (m > 0) {
Calibration = m;
} else Calibration = 110025;
// Calibration = 100000;
}
starttracthour=Trip[curTrip].startHour;
starttractmin=Trip[curTrip].startMin;
starttractsec=Trip[curTrip].startSec;
if (starttracthour>23) starttracthour = 23;
if (starttractmin>59) starttractmin = 59;
if (starttractsec>59) starttractsec = 59;
//constanta=mem.readFloat(800);
constanta = Trip[curTrip].speed;
if ((constanta > 150) || (constanta < 0)) constanta = 60; /// aslinya if ((constanta > 150) || (constanta < 0)) constanta = 60;
long m = mem.readLong(896); //read calibration value;
if (m > 0) {
Calibration = m;
} else Calibration = 110025;
// Calibration = 100000;
//#ifdef DEBUG
Serial.println("calibration and constanta");
Serial.println(m);
Serial.println(Calibration);
Serial.println(constanta);
Serial.println("calibration and constanta");
Serial.println(m);
Serial.println(Calibration);
Serial.println(constanta);
//#endif
constantatodigit();
constantatodigit();
// Serial.print(digit1);Serial.print(digit2); Serial.print(digit3); Serial.print(digit4);Serial.print(digit5);Serial.println(digit6);
// Serial.println(constanta,5);
//Serial.print(digitalRead(UP_pin));Serial.print(digitalRead(DOWN_pin));Serial.print(digitalRead(LEFT_pin));Serial.print(digitalRead(RIGHT_pin));Serial.println(digitalRead(OK_pin));
prevcount1 = count1;
prevcount2 = count2;
//Serial.print(digitalRead(UP_pin));Serial.print(digitalRead(DOWN_pin));Serial.print(digitalRead(LEFT_pin));Serial.print(digitalRead(RIGHT_pin));Serial.println(digitalRead(OK_pin));
prevcount1 = count1;
prevcount2 = count2;
prevcalibrationtime+=calibrationtimeinterval;
prevtempint+=tempinterval;
prevtemprally+=tempintervalrally;
prevsettime += intervalsettime;
startmillis+=1000;
prevcalibrationtime+=calibrationtimeinterval;
prevtempint+=tempinterval;
prevtemprally+=tempintervalrally;
prevsettime += intervalsettime;
startmillis+=1000;
mainMenu();
mainMenu();
//
@ -2649,7 +2700,7 @@ DS3231_init(DS3231_CONTROL_INTCN);
strncpy(password, yourInputPwd.c_str() , (sizeof password)-1);
// strncpy(password, yourInputPwd.c_str() , (sizeof yourInputPwd)-1);
}
Serial.print("try to connect to ssid:");Serial.print(ssid);Serial.print("; with pwd:");Serial.println(password);
Serial.print("try to connect to ssid:");Serial.print(ssid);Serial.print("; with pwd:");Serial.println(password);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi Failed!");
@ -2692,58 +2743,22 @@ Serial.print("try to connect to ssid:");Serial.print(ssid);Serial.print("; with
});
server.on("/wifi", HTTP_GET, [](AsyncWebServerRequest * request) {
if (ON_STA_FILTER(request)) {
//request->send(200, "text/plain", "Hello from STA");
request->send_P(200, "text/html", wifi_html, processor);
return;
} else if (ON_AP_FILTER(request)) {
//request->send(200, "text/plain", "Hello from AP");
Serial.println("on apfilter /wifi");
request->send_P(200, "text/html", wifi_html, processor);
return;
}
request->send(200, "text/plain", "Hello from undefined");
});
request->send(200, "text/plain", "Hello from undefined");
});
// Send a GET request to <ESP_IP>/get?inputString=<inputMessage>
server.on("/setwifi", HTTP_POST, [] (AsyncWebServerRequest *request) {
String inputMessage;
boolean bolrestart=false;
boolean POST=true;
Serial.print("/setwifi:");
// GET inputString value on <ESP_IP>/get?inputString=<inputMessage>
if (request->hasParam(PARAM_SSID, POST)) {
inputMessage = request->getParam(PARAM_SSID, POST )->value();
Serial.print(inputMessage);Serial.print(";");
if (inputMessage!=""){
Serial.print(inputMessage);
writeFile(SPIFFS, "/ssidString.txt", inputMessage.c_str());
delay(50);
bolrestart=true;
}
}
// GET inputPwd value on <ESP_IP>/wifi/get?inputPwd=<inputMessage>
if (request->hasParam(PARAM_PWD, POST)) {
inputMessage = request->getParam(PARAM_PWD, POST)->value();
Serial.print(inputMessage);Serial.print(";");
if (inputMessage!=""){
writeFile(SPIFFS, "/inputPwd.txt", inputMessage.c_str());
delay(50);
bolrestart=true;
}
}
else {
inputMessage = "No message sent";
}
Serial.println("");
if (bolrestart) {
ESP.restart();
}
// Serial.println("ini /setwifi aja");Serial.println(inputMessage);
request->send(200, "text/text", inputMessage);
handelSetWifi(request);
});
server.on("/menu", HTTP_GET, [] (AsyncWebServerRequest *request) {
@ -2752,21 +2767,21 @@ Serial.print("try to connect to ssid:");Serial.print(ssid);Serial.print("; with
request->send_P(200, "text/html", main_menu);
});
server.on("/startrallytest", HTTP_GET, [] (AsyncWebServerRequest *request) {
//String s = MAIN_page; //Read HTML contents
//request->send_P(200, "text/html", s); //Send web page
String PAGE;
PAGE += FPSTR(HTML_PAGEHEADER);
PAGE.replace("%serveripaddress%", WiFi.localIP().toString());
PAGE += FPSTR(HTML_DIVSTARTRALLY);
//PAGE += FPSTR(HTML_SCRIPTSETINTERVAL);
//PAGE += FPSTR(HTML_SCRIPTGETDATA);
PAGE += FPSTR(HTML_END);
//Serial.println(PAGE);
Serial.print("PAGE Size:");
Serial.println(PAGE.length());
request->send(200, "text/html", PAGE);
});
// server.on("/startrallytest", HTTP_GET, [] (AsyncWebServerRequest *request) {
// //String s = MAIN_page; //Read HTML contents
// //request->send_P(200, "text/html", s); //Send web page
// String PAGE;
// PAGE += FPSTR(HTML_PAGEHEADER);
// PAGE.replace("%serveripaddress%", WiFi.localIP().toString());
// PAGE += FPSTR(HTML_DIVSTARTRALLY);
// //PAGE += FPSTR(HTML_SCRIPTSETINTERVAL);
// //PAGE += FPSTR(HTML_SCRIPTGETDATA);
// PAGE += FPSTR(HTML_END);
// //Serial.println(PAGE);
// Serial.print("PAGE Size:");
// Serial.println(PAGE.length());
// request->send(200, "text/html", PAGE);
// });
server.on("/startrally", HTTP_GET, [] (AsyncWebServerRequest *request) {
request->send_P(200, "text/html", HTML_startrally, processor);
@ -2790,75 +2805,75 @@ Serial.print("try to connect to ssid:");Serial.print(ssid);Serial.print("; with
request->send(SPIFFS, "/bootstrap.min.js", "text/javascript");
});
server.on("/resetodo1", HTTP_GET, [] (AsyncWebServerRequest *request) {
Serial.println("ODORESET 1");
request->redirect("/startrally1");
});
// server.on("/resetodo1", HTTP_GET, [] (AsyncWebServerRequest *request) {
// Serial.println("ODORESET 1");
// request->redirect("/startrally1");
// });
server.on("/resetodo2", HTTP_GET, [] (AsyncWebServerRequest *request) {
Serial.println("ODORESET 22222");
request->redirect("/startrally1");
});
// server.on("/resetodo2", HTTP_GET, [] (AsyncWebServerRequest *request) {
// Serial.println("ODORESET 22222");
// request->redirect("/startrally1");
// });
server.on("/copytoodo2", HTTP_GET, [] (AsyncWebServerRequest *request) {
Serial.println("COPY ODO 1 to 2");
request->redirect("/startrally1");
});
// server.on("/copytoodo2", HTTP_GET, [] (AsyncWebServerRequest *request) {
// Serial.println("COPY ODO 1 to 2");
// request->redirect("/startrally1");
// });
server.on("/copytoodo1", HTTP_GET, [] (AsyncWebServerRequest *request) {
Serial.println("COPY ODO 2 to 1");
request->redirect("/startrally1");
});
server.on("/DIR", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
String inputParam;
if (request->hasParam("DIR1")){
inputMessage=request->getParam("DIR1")->value();
Serial.print("DIR 1->");Serial.println(inputMessage);
switch(inputMessage[0]){
case 'F':
Serial.println("FW1");
break;
case 'S':
Serial.println("ST1");
break;
case 'B':
Serial.println("BACK1");
break;
default:
Serial.println("Default VAL1");
}
}
else if (request->hasParam("DIR2")){
inputMessage=request->getParam("DIR2")->value();
Serial.print("DIR 2->");Serial.println(inputMessage);
switch(inputMessage[0]){
case 'F':
Serial.println("FW2");
break;
case 'S':
Serial.println("ST2");
break;
case 'B':
Serial.println("BACK2");
break;
default:
Serial.println("Default VAL2");
}
}
request->redirect("/startrally1");
});
// server.on("/copytoodo1", HTTP_GET, [] (AsyncWebServerRequest *request) {
// Serial.println("COPY ODO 2 to 1");
// request->redirect("/startrally1");
// });
// server.on("/DIR", HTTP_GET, [] (AsyncWebServerRequest *request) {
// String inputMessage;
// String inputParam;
// if (request->hasParam("DIR1")){
// inputMessage=request->getParam("DIR1")->value();
// Serial.print("DIR 1->");Serial.println(inputMessage);
// switch(inputMessage[0]){
// case 'F':
// Serial.println("FW1");
// break;
// case 'S':
// Serial.println("ST1");
// break;
// case 'B':
// Serial.println("BACK1");
// break;
// default:
// Serial.println("Default VAL1");
// }
// }
// else if (request->hasParam("DIR2")){
// inputMessage=request->getParam("DIR2")->value();
// Serial.print("DIR 2->");Serial.println(inputMessage);
// switch(inputMessage[0]){
// case 'F':
// Serial.println("FW2");
// break;
// case 'S':
// Serial.println("ST2");
// break;
// case 'B':
// Serial.println("BACK2");
// break;
// default:
// Serial.println("Default VAL2");
// }
// }
// request->redirect("/startrally1");
// });
server.on("/TG1", HTTP_GET, [] (AsyncWebServerRequest *request) {
Serial.println("TOGGLE 1");
request->redirect("/startrally1");
});
// server.on("/TG1", HTTP_GET, [] (AsyncWebServerRequest *request) {
// Serial.println("TOGGLE 1");
// request->redirect("/startrally1");
// });
server.on("/TG2", HTTP_GET, [] (AsyncWebServerRequest *request) {
Serial.println("TOGGLE 2");
request->redirect("/startrally1");
});
// server.on("/TG2", HTTP_GET, [] (AsyncWebServerRequest *request) {
// Serial.println("TOGGLE 2");
// request->redirect("/startrally1");
// });
server.on("/calibration", HTTP_GET, [] (AsyncWebServerRequest *request) {
int params = request->params(); //showing all params
@ -2921,20 +2936,16 @@ Serial.print("try to connect to ssid:");Serial.print(ssid);Serial.print("; with
}
}
}
// handleloadConst(request, json);
// auto&& data = json.as<JsonObject>();
});
server.addHandler(setconst);
server.addHandler(loadconst);
Serial.println("before onevent");
Serial.println("before onevent");
ws.onEvent(onWsEvent); //add ws event
wscal.onEvent(onWsEvent2); //add ws event
server.addHandler(&ws);
server.addHandler(&wscal);
Serial.println("after onevent");
Serial.println("after onevent");
server.onNotFound(notFound);
Serial.println("onnotfound");
@ -3495,6 +3506,7 @@ void loop() //loop from VSS RALLY V2
//mem.writeFloat(800, constanta);
setMemSpeedInConstanta(constanta, curTrip);
setSpiffSpeedInConstanta(constanta, curTrip);
// int pointeradd = ((TRIPADDRESS+curTrip)*32);
// mem.writeFloat(pointeradd, constanta);
// Trip[curTrip].speed = constanta;
@ -3512,6 +3524,7 @@ void loop() //loop from VSS RALLY V2
//mem.writeLong(768,valuesettime);
setMemStime(valuesettime, curTrip); ///added for esp32
setSpiffStime(valuesettime, curTrip);
// int pointeradd = ((TRIPADDRESS+curTrip)*32+4);
// mem.writeLong(pointeradd, valuesettime);
// Trip[curTrip].startHour = starttracthour;

View File

@ -212,7 +212,7 @@ const char main_menu[] PROGMEM = R"rawliteral(
<div class="card-header"><h1>MENU</h1></div>
<div class="card-body">
<div class="row align-self-end g-1">
<div class="col text-center "><button onclick="location.href='/startrally1';" id="startrally" name="startrally" class="btn btn-primary btn-lg me-2 mb-2">RALLY</button></div>
<div class="col text-center "><button onclick="location.href='/startrally';" id="startrally" name="startrally" class="btn btn-primary btn-lg me-2 mb-2">RALLY</button></div>
<div class="col text-center"><button onclick="location.href='/calibration';" id="calibration" name="calibration" class="btn btn-primary me-2 mb-2">CALIBRATION</button></div>
<div class="col text-center"><button onclick="location.href='/constanta';" id="constanta" name="constanta" class="btn btn-primary me-2 mb-2">CONSTANTA</button></div>
<div class="col text-center"><button onclick="location.href='/settime';" id="constanta" name="constanta" class="btn btn-primary me-2 mb-2">Set TIME</button></div>