Recupération de données dans un fichier xml

Bonjour à tous,
Je suis actuellement à la recherche d’une solution pour réaliser mon projet sur une arduino mega 2560 et le shield Ethernet arduino.
Je vous explique, je n’arrive pas à récupérer les données de mon document XML stocker sur ma carte micro sd. Voici mon document xml :

<conf>
	<network>
		<ip value=192.168.10.240 />
		<dns value=192.168.10.254/>
		<gw value=192.168.10.240/>
		<mask value=255.255.255.0/>
		<MAC value=01:23:45:67:89:AB/>
	</network>
	<listcapteurs>
		<capteur name="temp_humidite1">
			<pin>53<pin>
			<label>entré</zone>
			<type>T-H</type>
		</capteur>
		<capteur name="temp_humidite2">
			<pin>54<pin>
			<label>couloir chaud</zone>
			<type>T-H</type>
		</capteur>
		<capteur name="temp_humidite3">
			<pin>55<pin>
			<label>fond</zone>
			<type>T-H</type>
		</capteur>
		<capteur name="mouvement">
			<pin>56<pin>
			<label>porte</zone>
			<type>mouv</type>
		</capteur>
		<capteur name="lumière">
			<pin>A1<pin>
			<label>entré</zone>
			<type>Lumière</type>
		</capteur>
	</listcapteurs>
</conf>

Je recherche une solution qui pourrait me permettre de compter le nombre de capteur pour un futur ajout et aussi savoir si je suis obligé de découper les adresses pour les récupérer?? :confused:

J’espère avoir était clair n’hésitez pas à m’aider ou a poser des questions si ce sujet vous intéresse aussi.

Merci d’avance,
Scroum

Salut

Paramétrer un système avec du XML part d’un bon sentiment, à partir du moment ou le système est lui-même souple et dynamique.
Par exemple on peut imaginer un driver de capteurs de température / humidité acceptant un nombre de capteurs indéterminé au démarrage. Le driver crée le nombre de devices en fonction du paramétrage.
C’est souple et cela peut être intéressant.

Ne pas oublier qu’un parser XML est un outil puissant, mais lourd en terme de quantité de code et d’occupation mémoire RAM.
Il va lire un fichier XML et ranger les données dans une structure arborescente et totalement dynamique.

Bien, mais la cible ARDUINO est-elle bien dimensionnée pour ce genre de chose ?
Il y a bien d’autres manières de paramétrer un système embarqué léger.
Par exemple :

network.ip=192.168.10.240
network.dns=192.168.10.254
network.gw=192.168.10.240
network.mask=255.255.255.0
network.MAC=01:23:45:67:89:AB

Les données sont lues dans un seul tableau de structures du type variable = valeur, tout simplement.
Dans mon entreprise nous utilisons ce type de paramétrage facile à parser, sur une cible LINUX tournant sur un processeur Exynos et 256Ko de RAM. Le logiciel est écrit en PYTHON.
Pas grand chose à voir avec une cible ARDUINO MEGA comme tu peux le constater.

Et pourtant, en matière de paramétrage nous évitons XML. Trop lourd.

Ensuite pour répondre à ta question de savoir s’il faut découper les adresses IP, tout dépend de ce que tu vas en faire par la suite.
En particulier cela va dépendre de la librairie ethernet ou WIFI que tu vas utiliser.
Attend t-elle des adresses IP sous forme de tableaux de 4 unsigned char ou un seul unsigned long ?

A toi d’adapter en fonction de l’utilisation.

@+

+1 avec hbachetti. Quitte à faire un fichier de données "propriétaire", autant se simplifier la vie et créer un "protocole" qui le rend facile à exploiter. Par exemple, chaque ligne est au format :

descripteur = donnée

Pour lire la donnée, il suffit de chercher la position du caractère "=" et d'ajouter 1, de lire le reste de la ligne et de le caster dans le type qui va bien.

Bonjour,

Merci pour vos réponse je vais voir se que je peux faire avec vos info pour l'adresse ip je pense que c'est un tableau de 4 byte puisque j'utilise la librairie Ethernet.h.

Du coup vous me conseiller de juste lire un fichier conf.txt qui se qui sera beaucoup plus simple à lire et beaucoup moins lourd si j'ai bien compris ?

Si XML n'est pas une obligation, oui.

@+

D'accord du coup une proposition de librairie simple pour réaliser ça ? :slight_smile:

A priori la bibliothèque string, mais le langage C a des fonctions qui peuvent t’aider : traitement des strings, voir chapitre 8.

Voir aussi ici

D'accord du coup une proposition de librairie simple pour réaliser ça ?

Réaliser la lecture du fichier de paramètres ou le découpage d'une adresse IP en bytes ?

hbachetti:
Réaliser la lecture du fichier de paramètres ou le découpage d'une adresse IP en bytes ?

pour la lecture du fichier de paramètres

Apparemment on trouve des choses :

Merci à vous deux je vais essayer :slight_smile:

Super grâce a vos conseil j'ai pu réussir cette partie de mon projet il ne me reste plus qu'à lire les capteurs pour que je me l'affiche sur une page html :wink:
Savez-vous si l'on peut attendre une requête client tout en voulant actualiser les valeurs des capteurs toute les 5 minutes par exemple car je ne connais que le delay() pour attendre mais si je fais cela je ne pourrais plus recevoir de requête pendant le temps du delay?

Salut

Pourquoi ne pas utiliser un timer avec une gestion par interruption.
Avec la librairle MsTimer2 par exemple.

@+

Merci hbachetti pour ces précieux conseil,

Je me suis un peu emballé je suis actuellement bloqué sur la récupération des mes requettes http.

Voilà je fais une requête comme celle si: /?nom=TempN, je cherche comment extraire TempN de cette requette pour l'utilisé dans la suite de mon programme.

    Serial.println("Client en ligne\n"); //on le dit...
    if (client.connected()) { // si le client est en connecté
      while (client.available()) { // tant qu'il a des infos à transmettre
        char c = client.read(); // on lit le caractère
        Serial.write(c);// on l'écrit sur le moniteur série
        delay(1); //délai de lecture

En partant de cette base je me dit qu'il doit être assez facile d'utilisé cela pour récupérer ma requête seulement beaucoup d'explications sont en anglais sur ce sujet et j'ai du mal à comprendre.

Salut

Il y a ce tuto, en français.
Chapitre “Interpréter l’URL”.

@+

GET /?test=TempN HTTP/1.1

J'ai réussi a extraire ceci de ma requête dans une variable de type String il ne me reste plus qu'a récupérer le TempN j'essaye plein de chose mais je n'arrive jamais à extraire juste le TempN aurais tu une petite idée à me donner :slight_smile:

Quelque chose comme ça :

#include <stdio.h>
#include <string.h>

int getVar(const char *s, const char*var, char *value)
{
	char *p = strstr(s, "nom");
	if (p != NULL) {
		printf("trouvé %s\n", p);
		p += strlen("nom");
		if (*p == '=') {
			char *e;
			printf("trouvé =\n");
			p++;
			e = strchr(p, '&');
			if (e == NULL) {
				printf("dernier argument\n");
				strcpy(value, p);
			}
			else {
				strncpy(value, p, e-p);
				value[e-p] = '\0';
			}
			return 1;
		}
		else {
			printf("pas trouvé =\n");
		}
	}
	return 0;
}

int main(void)
{
	char value[10];
	char *s = "/?nom=1000";
	if (getVar(s, "nom", value)) {
		printf("valeur=%d\n", atoi(value));
	}
	s = "/?nom=1000&num=456";
	if (getVar(s, "nom", value)) {
		printf("valeur=%d\n", atoi(value));
	}

}

Dans ce code on considère qu’il n’y a pas d’espace avant et après le signe ‘=’.
La valeur est récupérée dans value.
J’ai compilé ça sous GCC d’où le main() et les printf().
Je te laisse extraire le code utile et virer les printf() ou les remplacer par des Serial.print().

@+

Salut,

Un petit message de remerciement , j’ai réussi à finir mon projet tout fonctionne parfaitement la lecture du fichier conf que j’ai choisi de garder en xml au final, j’ai ensuite créer mon petit serveur web sur lequel j’ai créer une petite page html pour avoir mes données dans un tableau, puis avec mes requête http j’affiche uniquement la valeur du capteur sur une page web. Grâce à un script je viens exécuter ces requêtes pour récupérer les valeurs avec lesquelles je peux au final créer des graphiques :).

Pensez-vous qu’il serez intéressant que je mette mon code final dans le topic ?

En tout cas merci à vous deux pour votre aide :slight_smile:

Bravo.

Bien sûr, ce n’est jamais inutile.

@+

Bonjour,

voici le code final de la partie lecture des fichiers xml, TextFinder est une librairie de recherche dans le texte ce n’est pas qu’une librairie pour lire des fichiers xml. En espérant que cela servira aux personnes en difficultés comme moi :slight_smile:

#include <Ethernet.h>
#include <TextFinder.h>
#include <dht11.h>
bool modedebug=false;
byte mac[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; //adresse mac de votre carte
byte ip[] = {0, 0, 0, 0}; //adresse IP
byte dnServer[] = {0, 0, 0, 0}; //adresse IP
byte mask[]= {0, 0, 0, 0}; //mask
byte gw[]= {0, 0, 0, 0}; //gateway
EthernetServer serveur(80); // déclare l'objet serveur au port d'écoute 80

typedef struct
{
  int pin;
  String type;
  String label;
  String nom;
  float mesure=15;
}capteur;

File conf;
capteur* tcapteur;
int NBcapteur=0;
unsigned long long previousMillis = 0;

void parseBytes(const char* str, char sep, byte* bytes, int maxBytes, int base) {
      for (int i = 0; i < maxBytes; i++) {
        bytes[i] = strtoul(str, NULL, base);  // Convert byte
        str = strchr(str, sep);               // Find next separator
        if (str == NULL || *str == '\0') {
            break;                            // No more separators, exit
        }
        str++;                                // Point to next character after separator
      }
}



    
void setup() {
  // put your setup code here, to run once:
 Serial.begin(9600);
  pinMode(10, OUTPUT);
  digitalWrite(10,HIGH);
  int temp;
  char buff[50];
  String debug="";
  if (!SD.begin(4)) { // Gère les erreurs
    //Serial.println("Erreur de carte SD !");
    for(;;);
    }
    
    conf=SD.open("config.xml", FILE_READ);
    TextFinder finder(conf);
    //Mode Debug
    conf.seek(0);
    temp=finder.getString("<debug>","</debug>",buff,50);
    debug=buff;
    if(debug.startsWith("oui"))
    {
      modedebug=true;
    }
    //Analyse reseau\\
    conf.seek(0);
    temp=finder.getString("<ip>","</ip>",buff,50);
    parseBytes(buff, '.', ip, 4, 10);
    //
    temp=finder.getString("<dns>","</dns>",buff,50);
    parseBytes(buff, '.',dnServer, 4, 10);
    //
    temp=finder.getString("<gw>","</gw>",buff,50);
    parseBytes(buff, '.',gw, 4, 10);
    //
    temp=finder.getString("<mask>","</mask>",buff,50);
    parseBytes(buff, '.',mask, 4, 10);
    //
    temp=finder.getString("<mac>","</mac>",buff,50);
    parseBytes(buff, ':',mac, 6, 16);
    Ethernet.begin(mac,ip,dnServer,gw,mask);
    Serial.println(Ethernet.localIP());
    if(modedebug==true){
      Serial.println("configuration réseaux");
      Serial.println("adresse IP:");
      Serial.println(ip[0]);Serial.println(ip[1]);Serial.println(ip[2]);Serial.println(ip[3]);
      Serial.println("adresse dns:");
      Serial.println(dnServer[0]);Serial.println(dnServer[1]);Serial.println(dnServer[2]);Serial.println(dnServer[3]);
      Serial.println("adresse GW:");
      Serial.println(gw[0]);Serial.println(gw[1]);Serial.println(gw[2]);Serial.println(gw[3]);
      Serial.println("adresse Mask:");
      Serial.println(mask[0]);Serial.println(mask[1]);Serial.println(mask[2]);Serial.println(mask[3]);
      Serial.println("adresse MAC:");
      Serial.println(mac[0],HEX);Serial.println(mac[1],HEX);Serial.println(mac[2],HEX);Serial.println(mac[3],HEX);Serial.println(mac[4],HEX);Serial.println(mac[5],HEX);
    }
    
    
    
    //analyse des capteurs\\
    conf.seek(0);
    while(finder.find("<capteur>"))
    {
      NBcapteur++;
    }
    tcapteur=new capteur[NBcapteur];
    
  
    //rangements des pins des capteurs
    conf.seek(0);
    for(int i=0;i<NBcapteur;i++){
      finder.find("<pin>");
      temp=finder.getValue();
      tcapteur[i].pin=temp;
    }

    //rangement des noms des capteurs 
    conf.seek(0);
    for(int i=0;i<NBcapteur;i++){
    temp=finder.getString("<nom>","</nom>",buff,50);
    tcapteur[i].nom=buff;
    }

    //rangement des labels des capteurs 
    conf.seek(0);
    for(int i=0;i<NBcapteur;i++){
    temp=finder.getString("<label>","</label>",buff,50);
    tcapteur[i].label=buff;
    }

    //rangement des types de capteurs 
    conf.seek(0);
    for(int i=0;i<NBcapteur;i++){
    temp=finder.getString("<type>","</type>",buff,50);
    tcapteur[i].type=buff;
    }

    if(modedebug==true){
      Serial.print("NBcapteur: ");Serial.println(NBcapteur);
      Serial.println("analyse des capteurs");
      Serial.print("nom du capteur | ");Serial.print("type du capteur | ");Serial.print("label du capteur | ");Serial.println("pin du capteur | ");
      for(int i=0;i<NBcapteur;i++){
      Serial.print(tcapteur[i].nom);Serial.print(" | ");Serial.print(tcapteur[i].type);
      Serial.print(" | ");Serial.print(tcapteur[i].label);Serial.print(" | ");Serial.println(tcapteur[i].pin);
      }
    }