🛠 Serveur web embarqué : YunServer, YunClient et pages dynamiques
Objectives
Move beyond the generic REST API to write YOUR OWN web server: the YunServer library opens a TCP port on the Linux side (via the avrbridge daemon), and YunClient represents each connection. You will serve an HTML page and a JSON endpoint read by a real sensor, understanding that HTTP is handled by Linux while the 32U4 remains the only component touching the pins.
Hardware
- 1 Arduino Yún online
- 1 analog sensor on A1 (potentiometer or LDR + 10 kΩ voltage divider)
- Browser on the same network
- Basic knowledge of HTTP (request/response, Content-Type) is sufficient
Complete Code
// Serveur HTTP minimal sur le port 5555 : page + JSON capteur.
#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>
YunServer serveur;
const uint8_t CAPTEUR = A1;
void setup {
Bridge.begin;
serveur.listenOnLocalhost; // écoute côté Linux
serveur.begin;
}
void loop {
YunClient client = serveur.accept;
if (!client) return; // aucune connexion en attente
process(client);
client.stop; // toujours fermer la connexion
}
void process(YunClient client) {
String methode = client.readStringUntil('\t'); // GET /temperature HTTP/1.1
String chemin = client.readStringUntil('\t');
client.readStringUntil('\r'); // reste de la ligne HTTP
client.readStringUntil('\n');
// Vide les en-têtes jusqu'à la ligne vide (sinon ils seront lus comme le corps)
String ligne;
while ((ligne = client.readStringUntil('\n')).length > 1) { }
if (chemin == "/temperature") {
int v = analogRead(CAPTEUR);
client.print(F("HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n"
"Connection: close\r\n\r\n"));
client.print(F("{\"capteur\":A1,\"brut\":"));
client.print(v);
client.println(F(",\"unite\":\"adc10\"}"));
} else if (chemin == "/") {
client.print(F("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n"
"Connection: close\r\n\r\n"
"<h1>Yun vivante</h1>"
"<p><a href='/temperature'>/temperature</a></p>"));
} else {
client.print(F("HTTP/1.1 404 Not Found\r\nConnection: close\r\n\r\n"));
}
}
Expected Verification
http://arduino.local:5555/temperature returns a JSON with the sensor reading (0–1023), refreshed on each request. curl -v shows the Connection: close header and a clean connection. Open two tabs: YunServer serializes requests — a blocking request (poorly placed sleep) freezes the site, hence the requirement for short handlers.
Common Errors
- Forgetting to drain the headers: remaining lines are consumed by your path parser — the classic symptom is a path starting with “User-Agent”.
- Forgetting
client.stop: connections pile up, and the server saturates after a few refreshes. - Writing the response without the final
\r\n\r\n: the browser displays “waiting” indefinitely. - Trying to implement long-polling or WebSockets with YunServer: the model is short request/response; for real-time updates, polling the JSON every 500 ms remains the simplest approach (the YunWebsocket examples in the IDE explore another path on the Linux side).
- Confusing
listenOnLocalhostandlistenOnAllIPs: by default, the port is accessible ONLY from Linux itself (thus from the network via the uhttpd proxy on port 8080) —listenOnAllIPsexposes the raw port, which is a double-edged sword. - Blocking inside
process: eachdelay(1000)is one second of freeze for all clients; offload slow tasks to the Linux side if possible.
Other tutorials for this board
- Premiers pas sur la Yún : Bridge, Console et LED
- Connecter la Yún au WiFi et piloter une broche depuis le navigateur
- Envoyer un capteur analogique sur le réseau : potentiomètre et Bridge REST
- runShellCommandOnLinux : faire exécuter des commandes Linux depuis le sketch
- L'API REST du Bridge en détail : /arduino, /data et routes personnalisées
- Alerte email : bouton sur la Yún et envoi via sendmail
Code examples for this board
clignotant-rest.inoArduinoconsole-bridge.inoArduinovaleurs-partagees.inoArduinoprocess-shell.inoArduinoserveur-json.inoArduinolecture-fichier.inoArduino