Partage
  • Partager sur Facebook
  • Partager sur Twitter

Réaliser un mini serveur WEB sur arduino

13 avril 2015 à 19:02:36

EDIT by Lorrio : mise en forme.

[...]

Un petit Bonjour ici

[...]

Une description du problème ici

[...]

Un petit texte du genre : "Voici mon code :" ici

 #include < SPI.h >

 #include < Ethernet.h >

 #include < SD.h >

 byte mac[] = {
 	0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
 };

 IPAddress ip(172, 16, 22, 249);

 EthernetServer server(80);

 void setup() {

 	Serial.begin(9600);

 	while (!Serial) {

 		;

 	}

 	pinMode(10, OUTPUT);

 	Ethernet.begin(mac, ip);

 	server.begin();

 	Serial.print("server is at ");

 	Serial.println(Ethernet.localIP());

 	if (!SD.begin(4)) {

 		Serial.println("initialization SD failed!");

 		return;

 	} else Serial.println("SD ok .");

 }

 #define BUFFER_SIZE 128

 #define PATH_SIZE 128

 #define PARAMS_SIZE 128

 char buffer[BUFFER_SIZE];

 char tmp[BUFFER_SIZE];

 //POST

 char LOGIN[BUFFER_SIZE];

 char PASS[BUFFER_SIZE];

 struct HTTPDATA {

 	boolean isGET;

 	boolean isPOST;

 	char path[PATH_SIZE];

 	char params[PARAMS_SIZE];

 };

 File myFile;

 char sending;

 void loop() {

 	EthernetClient client = server.available();

 	if (client) {

 		Serial.println("----------------------");

 		HTTPDATA info = httpRequest(client);

 		if (info.isGET) {

 			sendPage(info.path, client, 0);

 		}

 		Serial.println(info.isGET);

 		Serial.println(info.path);

 		Serial.println(info.params);

 		Serial.println("----------------------");

 		client.stop();

 	}

 }

 struct HTTPDATA httpRequest(EthernetClient client) {

 	while (client.connected()) {

 		if (client.available()) {

 			int bufferIndex;

 			char c;

 			HTTPDATA data;

 			data.isGET = false;

 			data.isPOST = false;

 			data.path[0] = '\0';

 			data.params[0] = '\0';

 			buffer[0] = client.read();

 			buffer[1] = client.read();

 			bufferIndex = 2;

 			while (buffer[bufferIndex - 2] != '\r' && buffer[bufferIndex - 1] != '\n') {

 				c = client.read();

 				if (bufferIndex < BUFFER_SIZE) buffer[bufferIndex] = c;

 				bufferIndex++;

 			}

 			if (strncmp(buffer, "GET ", 4) == 0) {

 				Serial.println("-------------GET-------------");

 				data.isGET = true;

 				data.isPOST = false;

 				strncpy(data.path, (buffer + 4), bufferIndex - 11);

 				data.path[bufferIndex - 15] = '\0';

 				bufferIndex = bufferIndex - 15;

 				int pos = 0;

 				while (data.path[pos] != '?') {

 					pos++;

 					if (pos == bufferIndex) break;

 				}

 				strncpy(data.params, (data.path + pos), bufferIndex - pos);

 				data.params[bufferIndex - pos] = '\0';

 				data.path[pos] = '\0';

 				return data;

 			} else if (strncmp(buffer, "POST ", 5) == 0) {

 				Serial.println("-------------POST-------------");

 				data.isGET = false;

 				data.isPOST = true;

 				strncpy(data.path, (buffer + 5), bufferIndex - 11);

 				data.path[bufferIndex - 16] = '\0';

 				Serial.println("--------------------------");

 				buffer[0] = client.read();

 				buffer[1] = client.read();

 				buffer[2] = client.read();

 				buffer[3] = client.read();

 				bufferIndex = 4;

 				while (buffer[bufferIndex - 4] != '\r' && buffer[bufferIndex - 3] != '\n' && buffer[bufferIndex - 2] != '\r' && buffer[bufferIndex - 1] != '\n')

 				{

 					c = client.read();

 					bufferIndex++;

 				}

 				for (int j = 0; j < 8; j++) {

 					c = client.read();

 					bufferIndex++;

 				}



 				Serial.println(bufferIndex);

 				Serial.println("--------------------------");

 				while (client.available()) {

 					c = client.read();

 					if (bufferIndex < BUFFER_SIZE) buffer[bufferIndex] = c;

 					bufferIndex++;



 				}

 				Serial.println("nbre de carac stocker ds tab");

 				Serial.println(bufferIndex);

 				int pos = 0;

 				while (buffer[pos] != '&') {

 					pos++;

 					if (pos == bufferIndex) break;

 				}

 				strncpy(PASS, (buffer + pos), bufferIndex - pos);

 				PASS[bufferIndex - pos] = '\0';

 				strncpy(LOGIN, (buffer), pos);

 				LOGIN[pos] = '\0';

 				//if (strncmp(LOGIN,"login=",6)==0){

 				strncpy(LOGIN, (LOGIN + 6), pos);

 				LOGIN[pos - 6] = '\0';

 				//}

 				//else

 				// Serial.println("----------------------");

 				// if (strncmp(PASS,"pass=",5)==0){

 				strncpy(PASS, (PASS + 5), bufferIndex - (pos + 5));

 				PASS[bufferIndex - (pos + 5)] = '\0';

 				// }

 				for (int j = 0; j < (pos - 6); j++) {

 					c = LOGIN[j];

 					Serial.println(c);

 				}

 				for (int j = 0; j < (bufferIndex - (pos + 5)); j++) {

 					c = PASS[j];

 					Serial.println(c);

 				}



 				return data;

 			}

 		}

 	}

 }



 void sendPage(char * path, EthernetClient client, int len) {

 	File myFile = SD.open(path);

 	char sp;

 	if (myFile) {

 		if (len == 0) {

 			while (myFile.available()) {

 				sp = myFile.read();

 				client.print(sp);

 			}

 		} else {

 			for (int j = 0; j < len; j++) {

 				sp = myFile.read();

 				client.print(sp);

 			}

 		}

 		myFile.close();

 	} else {

 		client.print("NOT FOUND");

 	}

 }

[...]

Un Merci ici

[...]

-
Edité par lorrio 13 avril 2015 à 19:44:11

  • Partager sur Facebook
  • Partager sur Twitter
13 avril 2015 à 19:49:05

Hum, mettre uniquement ton code sans rien autours, ça va être assez compliqué de t'aider (surtout pour ceux qui n'ont pas lu ton ancien sujet).

Je viens d'éditer ton message afin d'y mettre les balises codes et un début de trame (bonjour/description/code/merci).

Je te laisse donc éditer ton message (le petit bouton "éditer" en haut à droite de ton message) pour remplacer mes texte du genre "une description ici" par quelque chose de concret.

-
Edité par lorrio 13 avril 2015 à 20:24:15

  • Partager sur Facebook
  • Partager sur Twitter
13 avril 2015 à 19:51:41

Effectivement, j'ai rien compris !

Cdt,

  • Partager sur Facebook
  • Partager sur Twitter
Linux est à Windows ce qu'une jolie fille est à une prostituée : la jolie fille, il faut la séduire pour obtenir ce que l'on désire alors que la prostituée , il suffit de la payer, et surtout bien se protéger.
13 avril 2015 à 20:21:53

IvanDelano: bah c'est normal, un code tout seul, ça dit pas où est le problème. du coup... bah c'est dur de deviner...

-
Edité par remace 13 avril 2015 à 20:23:00

  • Partager sur Facebook
  • Partager sur Twitter

oui. non. enfin je regarde et je te dis.

13 avril 2015 à 20:59:34

le probleme est j'ai pas recupérer les données du "post" pour terminer ce projet...donc svp etes vous m'aider ou bien de donner une autre programme qui permet de réaliser un serveur web à base du arduino en utilisant HTMLet mrc bcp
  • Partager sur Facebook
  • Partager sur Twitter
13 avril 2015 à 21:19:46

Un header HTTP, cela ressemble à ça :

POST /dossier/page.html HTTP/1.1
Host: ndd.comm
User-Agent: Mozilla/5.0 ...
Accept: ...
Accept-Language: ...
Accept-Encoding: ...
Referer: ...
Connection: ...

name1=value1&name2=value2&...

On peut voir ça ainsi :

1/ la première ligne qui contient l'URL

2/ pleins de ligne inutile

3/ une ligne vide

4/ le contenu du post

Je t'encourage donc vivement à faire une fonction readLine() qui s'occupe de lire une ligne entière dans un buffer.

Ainsi, tu pourras faire quelque chose du genre :

// Dès qu'un client se connect

// Lecture de l'URL
readLine(client, buffer);

// ICI: ton code pour analyser l'url sachant qu'il suffit de couper suivant les espaces
// La première partie contiendra alors GET ou POST
// La seconde partie contiendra l'URL
// La dernière partie contiendra HTTP/1.1

// Lecture dans le vide jusqu'à trouver la ligne vide
do {
    readLine(client, buffer);
} while ( buffer[0] == '\0' ); // Une ligne vide, c'est une chaine vide donc [0] == '\0'

// Si c'est un post, lecture d'une dernière ligne
if ( /* is post ? */ ) {

    readLine(client, buffer);

    // ICI: ton code pour analyser le POST sachant qu'il suffit de découper suivant les & et les =

}

Allez, en bonus, la fonction readLine en question :

void readLine(EthernetClient &client, char *buffer) {

	int idx = 0;
	
	// Bouble infinie de lecture
	while ( 1 ) {
		
		// Si une donnée est disponible
		if ( client.available() ) {
				
			// On lit la donnée en question
			char c = client.read();
			
			// Si c'est un \n
			if ( c == '\n' ) {
				// Alors c'est la fin de la ligne
				// Donc on peut couper la boucle infinie
				break;
			}
			
			// Et si ce n'est pas un \n, on ajoute le caractère au buffer
			buffer[idx++] = c;
			
		// Si il n'y a pas de donnée disponible
		} else {
			// Et qu'en plus, le client est déconnecté
			if ( !client.connected() ) {
				// Alors on ne pourra plus rien recevoir
				// Donc on peut couper la boucle infinie aussi
				break;
			}
		}
		
	}
	
	// Fin de la boucle, la ligne est terminée
	
	// Petite protection pour supprimer le \r
	// (car certains navigateurs envoient \r\n et pas seulement \n)
	if ( ( idx > 0 ) && ( buffer[idx-1] == '\r' ) ) {
		idx--;
	}
	
	// Ajout du '\0' (caractère de fin de chaine)
	buffer[idx] = '\0';
	
	// Fin !
	
}

Avec tout ça, tu as toutes les billes pour réussir ;)

-
Edité par lorrio 13 avril 2015 à 21:31:43

  • Partager sur Facebook
  • Partager sur Twitter
13 avril 2015 à 21:22:24

  • Partager sur Facebook
  • Partager sur Twitter

oui. non. enfin je regarde et je te dis.

13 avril 2015 à 21:35:28

remace a écrit:

lien (clique)

Généralement, les exemples de Web serveur sont assez basique en ne gérant qu'une URL basique en GET.

J'ai bien l'impression qu'il veut allé plus loin en gérant GET & POST ainsi que les données du POST.

  • Partager sur Facebook
  • Partager sur Twitter
13 avril 2015 à 21:54:11

arf je savais que t'allais passer lui donner un exemple bien complet tôt ou tard, c'était juste pour lui faire comprendre que c'est pas à nous de faire son taf, surtout sur la recherche google et la lecture de sa lib...

-
Edité par remace 13 avril 2015 à 21:54:31

  • Partager sur Facebook
  • Partager sur Twitter

oui. non. enfin je regarde et je te dis.

13 avril 2015 à 22:02:17

merci Mr pour cette effort et pour me donner cette occasion pour discuter avec vous. est ce que si possible de rassembler se programme avec celui que je t'envoyer pour donner un  programme finale qui permet de réaliser un serveur web par les deux methodes (POST et GET)...comme j'ai dit mon prof il a dit que vous pouvez utiliser seulement HTML pas(PHP)..et j'ai  communiquer avec vous parce que c'est la première fois que j'ai travaille avec ARDUINO et je veux soutenire ce projet la fin du ce mois et merci  bcp
  • Partager sur Facebook
  • Partager sur Twitter
13 avril 2015 à 22:10:06

faiçalrouchmi a écrit:

est ce que si possible de rassembler se programme avec celui que je t'envoyer pour donner un  programme finale qui permet de réaliser un serveur web par les deux methodes (POST et GET)...

Bien sûre que c'est possible.

C'est même vivement conseillé si tu veux avoir un programme qui fonctionne relativement correctement sans avoir 36000 lignes de code.

Par contre, ce n'est clairement pas à moi de faire ça.

C'est ton projet, je veux bien t'aider en te mettant sur la voie (voir même en te donnant un beau moreau de code avec la fonction readLine) mais je ne vais pas coder tout le projet à ta place.


faiçalrouchmi a écrit:

il a dit que vous pouvez utiliser seulement HTML pas(PHP)..

En même temps, cela parait logique.

PHP est un langage interprété de haut niveau que l'arduino n'est pas capable d'exécuter.

Donc l'ensemble de tes pages devront effectivement être au format HTML, stockée dans un fichier de ta carte SD.

Par contre, rien ne t’empêche de générer du HTML avec du code arduino.

  • Partager sur Facebook
  • Partager sur Twitter
13 avril 2015 à 22:29:33

oui Mr j'ai stocker mes pages web dans SD..et mon professeur dit à moi de terminer par cette méthode et il ma dit de terminer ce projet cette semaine pour passer à la réalisation du rapport finale que je doit soutenir...donc svp est ce que tu peut me continuer à moi pour terminer ça et mrc parce que j'ai arrêté 2 semaines j'ai rien ajouter à ce programme parce que j'ai pas  compris beaucoup ce langage ARDUINO
  • Partager sur Facebook
  • Partager sur Twitter
13 avril 2015 à 23:23:07

Un projet qui demande 2 semaines de préparation pour une soutenance, ça ne se boucle pas en une semaine donc j'avoue ne pas trop comprendre...

- Soit ton professeur ne sait pas vraiment ce qu'il dit pour l'établissement des plannings

- Soit cela fait plusieurs semaines (voir mois) que tu es au courant de ce projet et tu te réveille une semaine avant la dead line

Mais dans tous les cas, la réponse est non : je ne ferais pas tout le code ta place pour que tu es juste à faire un copié/collé en disant à tes profs "vous voyez, ça marche très bien, vous pouvez me mettre une bonne note".

Donc il falloir que tu fasses un effort.

Si tu as réussi à faire un code de 345 ligne, c'est que tu as quand même de bonnes bases en programmation donc tu ne devrais pas avoir de mal à comprendre les quelques conseils que je t'ai déjà donné sur ce message : (lient direct ici).

  • Partager sur Facebook
  • Partager sur Twitter
13 avril 2015 à 23:30:26

Bah t'as pas compris, on ne va pas te donner la solution.

Nous aussi on est passer par des phases où on a eu du mal à comprendre certaines notions, mais on est resté bloqué, on a bossé, cherché des informations et finalement on a réussi à s'en sortir.

Te donner la solution ne t'apportera qu'une note à peu près correcte (peut-être une très bonne note si ton professeur ne cherche pas trop en te posant des questions pour savoir si tu as compris ce que tu as fait), mais tu ne comprendra jamais ce que tu as fait, or c'est le plus important.

(Pas la peine de faire semblant d'être d'accord, que c'est la seule et unique fois où cela arrive, j'ai été étudiant et j'ai vu cette situation des centaines de fois...)

Le seul conseil que je peux te donner, si tu n'as pas compris le programme que tu as posté, c'est de mettre un commentaire à peu près à chaque ligne en disant ce qu'elle fait. Parce que là, un code de 350 lignes sans aucun commentaire, c'est soit que tu es très fort car tu n'as rien compris, soit c'est du copié/collé.

@lorrio, je t'ai déjà fait une remarque sur tes réponses détaillées, tu continue ;)

D'ailleurs je ne sais pas ce que tu fais de tes journées pour passer ton temps à faire du code Arduino personnalisé :o

  • Partager sur Facebook
  • Partager sur Twitter
13 avril 2015 à 23:47:32

@zeqL:

zeqL a écrit:

@lorrio, je t'ai déjà fait une remarque sur tes réponses détaillées, tu continue ;)

Je sais... j'essaie de me modérer moi même mais on n'efface plus plusieurs mois (années?) de mauvaises pratique comme ça.

Depuis ton message, je rédige progressivement de moins en moins de code direct et de plus en plus de pseudo code voir simple explication.

D'ailleurs, à part cette fonction readLine (que je n'aurais probablement pas du donner), je n'ai donné aucun autre code à copier/coller.

  • Partager sur Facebook
  • Partager sur Twitter
20 avril 2015 à 18:29:33

Mr lorrio dzl pour le dirongement..Donc j'ai récupéré les données du post ça marche.. mais mon prof demande a moi de lire un fichier XML sur ARDUINO et faire des échanges  donc jai finir le code HTML mais j'ai compris comment en veut le changer sur ARDUINO bien suyr en utilisant SD card..etes vous m'aider svp!!!!
  • Partager sur Facebook
  • Partager sur Twitter
20 avril 2015 à 18:49:41

Eh... jusque là, j'ai plus ou moins réussi à comprendre ce que tu voulais faire mais là... ce que tu viens d'écrire ne veut strictement rien dire.

Bref, ton prof te demande quoi ?

  • Partager sur Facebook
  • Partager sur Twitter
20 avril 2015 à 19:16:28

il lui demande de faire un parseur XML...
  • Partager sur Facebook
  • Partager sur Twitter

oui. non. enfin je regarde et je te dis.

21 avril 2015 à 10:31:39

bonjour. il demande de creer une pages web qui contient des lamps et des prises est je le fait ..mais la deuxieme question est de changer l'etat de ces lamps et prises à l'aide d'un programme sur arduino c-a-d lire SD card (c-a-d lire un fichier XML et changer l'etat de ces lamps et prises (ci 1 vous les remplacer par 0)
  • Partager sur Facebook
  • Partager sur Twitter
21 avril 2015 à 12:11:49

Ok, donc ton programme arduino doit lire un fichier XML et commander l'état des lampes en fonction de ce fichier.

Cependant, cela ne dit pas comment se fichier arrive jusqu'à l'arduino...

=> Est-ce que ce fichier arrive directement par la carte SD (et dans ce cas, l'arduino doit détecter l'insertion de la carte SD et ouvrir le fichier qui s'y trouve) ?

ou

=> Est-ce que ce fichier arrive par le réseau avec un formulaire d'upload de fichier (et dans ce cas, l'arduino doit analyser le contenu du formulaire d'upload) ?

  • Partager sur Facebook
  • Partager sur Twitter
21 avril 2015 à 13:20:32

@lorrio - extrait des règles du forum

La politesse

En commençant un nouveau sujet vous vous engagez à respecter la première règle du site : la politesse.
Un sujet doit obligatoirement commencer par "Bonjour" ou tout autre forme de politesse équivalente et se terminer éventuellement par "Merci" ou toute autre forme de politesse équivalente.
Un sujet ne respectant pas cette règle sera soit fermé soit surveillé par un modérateur qui vous demandera d'éditer votre sujet.

L'écriture

Nous vous demandons de soigner un minimum votre écriture lorsque vous postez un nouveau sujet sur les forums.
L'écriture SMS est bien entendu strictement interdite.

=> Quelques outils pour vous aider à soigner votre écriture :

Faites une recherche avant de poster

Lorsque vous créez un nouveau sujet nous vous encourageons à faire une recherche pour voir si votre sujet n'a pas déjà été traité (généralement lorsqu'il s'agit d'une demande d'aide).

Ce forum ne fait pas vos devoirs !

Nos forums sont là uniquement pour vous aider à trouver une réponse dans le domaine de l'électronique et non pour réaliser vos devoirs. 
Bien entendu, vous pouvez poser une question en rapport avec un cours ou un exercice que vous n'avez pas compris, à condition que vous ayez déjà réfléchi un minimum dessus.

-
Edité par zeqL 21 avril 2015 à 13:20:56

  • Partager sur Facebook
  • Partager sur Twitter
21 avril 2015 à 14:22:10

Bien vu, je prend note.

Il n'y a en effet aucune raison que je n'applique pas ces règles que j'applique ailleurs sous prétexte que je participe au sujet.

Je ferme donc ce sujet pour les causes évoquées ci dessus (aucune formule de politesse sur le premier message, aucune description réelle du problème, manque d'effort du l'orthographe).

@faiçalrouchmi :

Je t'invite à ré-ouvrir un nouveau sujet en prenant soin de décrire correctement ta problématique (avec un petit effort sur l'orthographe) et en postant ton code sans oublier les balises codes (le petit bouton </> au dessus de l'éditeur).

-
Edité par lorrio 21 avril 2015 à 14:22:45

  • Partager sur Facebook
  • Partager sur Twitter