First of all, many thanks to Q_ro for his help.
Here's how I managed to solve my problem: In the same order as last time, first comes the Arduino code
#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>
//variable constante que guarda la cantidad de puertas
#define CANT_PUERTAS 2
//variable tipo array que guarda los estados de las diferentes puertas
int estado[CANT_PUERTAS];
// Listen on default port 5555, the webserver on the Yun
// will forward there all the HTTP requests for us.
YunServer server;
void setup() {
Serial.begin(9600);
// Bridge startup
Bridge.begin();
//Pines que van a monitorear las puertas a partir de D2
for (int i = 0; i < CANT_PUERTAS; i++) {
pinMode(2 + i, INPUT_PULLUP);
}
// Listen for incoming connection only from localhost
// (no one from the external network could connect)
server.listenOnLocalhost();
server.begin();
}
void loop() {
//hacer poll de estado de puertas
pollPuertas(estado);
// Get clients coming from server
YunClient client = server.accept();
// There is a new client?
if (client) {
// Process request
process(client);
// Close connection and free resources.
client.stop();
}
delay(50); // Poll every 50ms
}
My only changes here were in void setup(){}
, where instead of manually declaring the pins to monitor, I created a for loop
to automatically set them up based on the amount of pins to monitor; and in pollPuertas
, where I changed the arguments passed to it.
void pollPuertas(int estado[]) {
for (int i = 0; i < CANT_PUERTAS; i++) {
estado[i] = digitalRead(2 + i);
}
}
Like I said before, I changed the arguments to this function. Decided to just go with my previously defined constant.
void process(YunClient client) {
// read the command
String command = client.readStringUntil('/');
command.trim();
//confirmar que el comando recibido es el correcto
if (command == "estado") {
client.println("Status: 200");
client.println("Content-type: application/json");
client.println();
//Inicio del array JSON
client.print("[");
//Valores del array
for (int i = 0; i < CANT_PUERTAS; i++) {
client.print(estado[i]);
//Si no es el ultimo valor del array, intercalar una coma
if (i < (CANT_PUERTAS - 1)) client.print(",");
}
//Cerrar array JSON
client.print("]");
}
}
And last but certainly not least, my process(YunClient client)
. Here is where the biggest changes happened (at least Arduino-side).
Taking the link Q_ro suggested as a guide, changed my REST calls from my original structure (arduinoyun.local/arduino/estado/PIN
) where I had an individual "webpage" per PIN, to a new structure (arduinoyun.local/arduino/estado
) where I would put all my currently monitored PINs in a single "webpage" as a JSON object (an array, in this case).
I want to make a special remark here: during my testing, I came to realize (the hard way) the importance of trimming whitespaces. Don't know why so don't ask me, but it wasn't until I did command.trim();
that my code worked. Maybe the browser inserts some whitespaces when querying the page or something, I dunno. What I do know is that was already banging my head against the wall trying to figure out why arduinoyun.local/arduino/estado
wouldn't bring out anything by the time I noticed the trim()
in Grallator's code.
Anyway, after the command is properly verified, I print a header that tells the browser this is a JSON object.
After that, I just print out an array with this form: [value, value, value]
. You can get all the details in the Sources.
And that's about it on this side of the equation.
HTML and JavaScript
<!DOCTYPE html>
<html>
<head>
<title>Cambio de CSS con JSON</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-2.1.1.js"></script>
<script type="text/javascript">
var Timer =setInterval(function(){cambiarColor()},500);
function cambiarColor(){
var i=0;
$.getJSON("/arduino/estado/",function(json){
var LENGTH = json.length;
for(i; i < LENGTH; i++){
if(json[i]==0){
$("#puerta"+i).css("color","green");
} else{
$("#puerta"+i).css("color","red");
}//cierra if
}//cierra for
}); //cierra $.getJSON
} //cierra cambiarColor();
</script>
</head>
<body>
<p id="puerta0">Puerta 1</p>
<p id="puerta1">Puerta 2</p>
</body>
</html>
var Timer =setInterval(function(){cambiarColor()},500);
simply sets up a timer so that function cambiarColor()
is called upon periodically.
As per cambiarColor()
itself, it's changed quite a bit. You can read up on the details of how function $.getJSON
works in the Sources, but here's the gist:
- assuming the JSON object is properly formatted server-side, $-getJSON() returns either a JS object or a JS array (an array in my case)
- pass the array to variable
json
- create a variable to hold the length of the
json
array - do a
for loop
to go through the values inside ofjson
- change CSS values using jQuery based on the values of the JSON object, obtained from the Arduino yaaaayyy
@Q_ro I found out how to concatenate the i
to the jQuery selector so that I could work by IDs! Wooo!
So there you go. Once again, bunch of thanks to Q_ro for helping me out. Hope that this is useful to somebody else in the future.
One tip to remember (I know I forgot about this for longer than I care to admit): the $.getJSON section of the code is closed with a });
, not just a }
.
Sources
- http://grallator.wordpress.com/2014/01/13/json-and-the-arduino-yun/
- http://jquerytipsntricks.wordpress.com/2013/07/06/parse-json-data-using-jquery-getjson/
- json(dot)org (site is being derpy and won't let me add more than 2 links)
- api(dot)jquery(dot)com
There's a bunch of helpful tools at the end of that last page. jsoneditoronline(dot)org in particular proved quite useful to me; helped me visualize the JSON object structure a little better.