nel listato che allego vorrei passare la variabile double temp; dentro la funzione void http_server_on_temp(), in particolare vorrei eguagliarla alla variabile javascript, così
Per cortesia, anziché mettere un link a un sito esterno che richiede anche l'approvazione per l'accesso, copia il programma nel messaggio usando il tasto CODE, così sarà facilmente e immediatamente visibile.
Dovresti mettere anche il contenuto della pagina web dove c'è il JavaScript a cui fai riferimento.
Ad ogni modo, devi fare una chiamata http passando come argomento la variabile JavaScript che vuoi confrontare.
Nella funzione http_server_on_temp() recuperi questo argomento e lo confronti con la variabile dello sketch che vuoi.
Fai riferimento agli esempi inclusi nella libreria WebServer.h per vedere come
il mio problema è che ho due variabili in due linguaggi differenti e voglio passare quella in C dentro allo script.
Mi manca proprio la sintassi su cosa fare: qual'è la sintassi per passare dentro ad uno script una variabile C? $temp? .temp? !temp? sparo alcune ipotesi
In sostanza vorrei visualizzare il valore di temp nel knob che mi sono costruito (vedi figura)
Non è questione di sintassi! Non puoi scambiare direttamente delle variabili da un ambiente runtime (Javascript) ad un altro ambiente runtime (il microcontrollore che esegue il suo firmware). Hai bisogno di un sistema che "sta nel mezzo" con un suo protocollo di comunicazione a usare per scambiare informazioni.
Nel tuo caso stai usando un browser e quindi il protocollo usato può essere l'HTTP.
Se vuoi "recuperare" una variabile dal microcontrollore e visualizzarla nella tua pagina web, dovrai fare una chiamata HTTP al webserver che gira sul micro il quale risponderà in modo opportuno.
Ad esempio il seguente snippet HTML+ javascript, svolge due funzioni:
la prima è richiamare una volta al secondo la funzione Javascript getTemperature() per inviare una richiesta GET al webserver (che gira sul microcontrollore) cosi da ottenere indietro come risposta il valore della temperatura aggiornato e visualizzarlo sulla pagina.
la seconda invece associa una funzione al pulsante che quando premuto invierà una seconda richiesta GET al microcontrollore dove però questa volta saranno passati anche due argomenti numerici che andranno poi elaborati dal micro.
<html>
<head>
<title>A simple webpage</title>
</head>
<body>
<div>
<p><span id="temperature">25.5<span> °C</p>
</div>
<div>
<input id="arg1" type="number" value="11" />
<input id="arg2" type="number" value="22" />
<button id="set-data">INVIA DATI</button>
</div>
<script>
function getTemperature() {
// Esegue una chiamata GET, la risposta aggiorna il testo dell'elemento HTML con id="temperature"
var url = new URL("http://" + `${window.location.hostname}` + "/getTemperature");
fetch(url)
.then(response => response.text())
.then(data => {
console.log(data);
document.getElementById("temperature").innerHTML = data;
});
}
function setData() {
var url = new URL("http://" + `${window.location.hostname}` + "/setData");
var params = new URLSearchParams({
arg1: document.getElementById("arg1").value,
arg2: document.getElementById("arg2").value
});
// Esegue una chiamata GET passando i due parametri
fetch(url + "?" + params)
.then(response => response.text())
.then(data => {
console.log(data);
});
}
// Chiama getTemperature() ogni secondo
setInterval(getTemperature, 1000);
// Associa il listener al pulsante con id="set-data" per l'evento "click"
document.getElementById("set-data").addEventListener("click", setData);
</script>
</body>
</html>
Lato microcontrollore dovrai gestire opportunamente queste due richieste HTTP, ad esempio:
(le funzioni per brevità le ho definite direttamente nel metodo come funzioni "anonime", ma puoi continuare anche come hai già fatto, non cambia nulla)
A quanto ho visto dove ho messo i punti interrogativi dovrei mettere la mia variabile 'temp'
Ora mi sembra che l'interfaccia per tirarsi dentro in HTML 'temp' sia la funzione
<script>
function getTemperature() {
// Esegue una chiamata GET, la risposta aggiorna il testo dell'elemento HTML con id="temperature"
var url = new URL("http://" + `${window.location.hostname}` + "/getTemperature");
fetch(url)
.then(response => response.text())
.then(data => {
console.log(data);
document.getElementById("temperature").innerHTML = data;
});
</script>
Giusto il mio ragionamento?
Devo incrociare l'Id "temperature" con "double temp"?
Nella tua pagina web stai usando la libreria JQuery e quindi la sintassi è leggermente diversa, ma il succo non cambia.
Non devi inserire righe a caso sperando che vadano bene, ma analizzare quanto già fa la tua pagina, capirlo in ogni suo passaggio e poi modificare di conseguenza, per tutto il resto c'è Google.
Nel dettaglio, questo snippet fa due cose fondamentalmente:
Per fare quello che vuoi tu a questo punto, ti basta richiamare la funzione knobfunction() quando ottieni in risposta dal micro il nuovo valore:
function getTemperature() {
// Esegue una chiamata GET, la risposta aggiorna il testo dell'elemento HTML con id="temperature"
var url = new URL("http://" + `${window.location.hostname}` + "/getTemperature");
fetch(url) // Invia una richiesta al webserver
.then(response => response.text()) // Quando si avrà la risposta, questa dovrà essere interpretata come testo semplice
.then(data => { // Qui arrivano i dati, cosa dobbiamo farne?
// console.log(data); // Stampa sulla console il valore ricevuto
// Chiama la funzione knobfunction()
knobfunction(parseFloat(data));
});
}
// Ora sarà questa funzione ad essere richiamata ogni 3 secondi e non più la funzione anonima di prima
$(document).ready( function(){ // Evento 'ready' di document (ovvero la pagina è pronta)
setInterval(getTemperature, 3000); // Ogni 3 secondi chiama getTemperature()
});
Per rendere il tutto più "affidabile" ci sarebbe da aggiungere la gestione degli errori:
ad esempio cosa succede se il webserver non risponde perché offline?
oppure se la risposta non è di tipo float come ci si aspetta?
La variabile window.location.hostnameè l'indirizzo del webserver.
Se ci fai attenzione la stringa viene costruita usando la sequenza di caratteri `${nome variabile}` (da notare che ` è diverso da ').
Questo modo di concatenare le stringhe è detto template literal
In realtà non è necessario passare l'indirizzo nella richiesta in questo caso. Ho messo l'istruzione perché ho fatto copia/incolla da un mio progetto dove era necessario per altre ragioni.
Puoi scrivere più semplicemente in questo modo e funzionerà senza problemi
function getTemperature() {
fetch( "/getTemperature") // Invia una richiesta al webserver
.then(response => response.text()) //
.then(data => {
knobfunction(parseFloat(data));
});
}
data è una stringa di testo che rappresenta una valore float, quindi per assegnare il nuovo valore all'elemento knob (che di base è una progress bar) devi convertire da testo a float, cosa che fa per l'appunto l'istruzione parseFloat()
Comunque, mi ripeto.
Possiamo andare avanti a mozzichi e bocconi all'infinito con il JavaScript, ma se hai intenzione di proseguire in questo tipo di sviluppo (interfacce web) prima o poi dovrai deciderti ad affrontare di petto la materia e studiarla con metodo.
Ci sono migliaia di libri sull'argomento e tantissimi anche in lingua Italiana.
Ben detto... ma devo precisare un paio di cose:
in passato ho fatto dei progetti con EmonCms e Arduino e ho visto dei Dial molto più performanti di questa cosa ;
ho lavorato anche con Labview per visualizzare questi tipi di dati e sensori vari.
Ho una minima infarinatura di HTML e PHP, e quasi nulla di JavaScript (come hai bene visto).
Dal punto di vista didattico mi sembra molto accattivante e introduttivo pensare ad una visualizzazione in questi termini (vedi la funzione knobfuntion che voglio utilizzare).
Inoltre non sto utilizzando l'IDE , ma ArduinoBlocks, che a parer mio è un figata, e che devo continuamente adattare alle esigenze del caso.
Detto questo non sono tanto distante dal risolvere questa mia 'piva mentale', anche se devo continuamente passare dal testuale ai blocchi.
A parer mio invece è un giocattolino buono dal punto di vista didattico (non a caso nei corsi di coding per ragazzi si usa molto spesso), ma troppo limitante per sviluppare davvero, ma è solo la mia personale opinione.
Quel che conta quando si sviluppa software, non è il linguaggio, ma l'algoritmo che si implementa con il linguaggio scelto.
Si. Io non ti ho suggerito che puoi fare cosi
var url = new URL("/temp");`
perché il costruttore URL vuole una stringa tipo http://etctect
Ho scritto invece che puoi fare cosi, cosa diversa.
fetch("/temp")
etc etc
Se abiliti gli strumenti di sviluppo del browser (tasto F12) vedi tutti gli eventuali errori nella console e fai presto a debuggare.