[Arduino] Transferer et Parser des données Arduino

L’espace pour parler de tout ce qui concerne l’électronique embarquée
Avatar de l’utilisateur
papy94
Messages : 653
Inscription : 23 janv. 2010 14:31
Localisation : Champigny sur marne
Contact :

[Arduino] Transferer et Parser des données Arduino

Message par papy94 »

Geeks :siffle:

J’ai besoin de tes lumières

Le but : 2 arduino uno relies par en série avec 2 fils (RX/TX) ,récupérer les données
Un arduino uno envoi des valeurs de plusieurs capteurs
L’autre arduino uno récupère les valeurs et travaille avec ces valeurs

La trame comprend du texte, des entiers et des nombre à virgule, séparé par des points virgules
Exemple : A1;260;35;23.55;11.65
Cela correspond à :
A1= numéro d’alarme
260 = profondeur
35 = niveau
23.55 = température
11.65 = voltage
Le séparateur point-virgule il me servira pour créer un fichier texte sur une SD branché sur le 2ieme aduino pour ensuite le lire avec Excel et faire des courbes

En gros transférer et mapper les données et pouvoir utiliser cees données

Quelque chose de simple, mais qui peut être facilement modifiable si on veut mettre, par exemple un fload a la place du premier texte, ou un texte a la place d’un entier
Donc j’envoi

Code : Tout sélectionner

  Serial.print("Alarm");Serial.print(Alarm);Serial.print(";");
  Serial.print(Val_X - Ang_Milieu);Serial.print(";");
  Serial.print(Pression_Relative);Serial.print(";");
  Serial.print(bmp.readTemperature());Serial.print(";");
  Serial.print(Tension);Serial.print(";");
  Serial.println();
J’ai bien trouvé un programme de skyduino, mais je tourne en rond avec

Code : Tout sélectionner

#include <SoftwareSerial.h>
SoftwareSerial serial(1, 0); // RX, TX pour Nano

#define TAILLE_MAX 32
char texte[TAILLE_MAX / 2], unite;
int valeur, index, diviseur;

void setup() {
  Serial.begin(9600);
}

void loop() {
  if(recupInfo(texte, &valeur, &index, &diviseur, &unite)) {
    Serial.println("Erreur de trame !");
    return;
  }
  Serial.print("Texte: ");
  Serial.println(texte);
  Serial.print("Valeur: ");
  Serial.println(valeur);
  Serial.print("Index: ");
  Serial.println(index);
  Serial.print("Diviseur: ");
  Serial.println(diviseur);
  Serial.print("Unité: ");
  Serial.println(unite);
}

/*
 * Parse une chaine au format $ texte;valeur;index;diviseur;°c/f;
 * Et retourne la valeur des differents champs.
 */
int recupInfo(char *texte, int *valeur, int *index, int *diviseur, char *unite) {
  char c, buf[TAILLE_MAX + 1];
  unsigned char i = 0;

  do { /* Attente du $ espace */
    while(Serial.available() < 2); /* Attente de 2 char sur le port série */
  }
  while(Serial.read() != '$' && Serial.read() != ' ');

  do{ /* Remplissage du buffer */
    if(i == (TAILLE_MAX + 1)) /* Si la chaine a dépassé la taille max du buffer*/
      return 1; /* retourne 1 -> erreur */
     while(Serial.available() < 1); /* Attente d'un char sur le port série */
  }
  
  while((buf[i++] = Serial.read()) != 0x1A);/* Tant que char != 0x1A (fléche) -> boucle */

  buf[i] = '\0'; /* Cloture la chaine de char */

  i = 0;/* Copie le texte au début de buf[] dans texte[] */
  while((texte[i] = buf[i]) != ';') i++;
  texte[i] = '\0';

  if(sscanf(buf + i, ";%d;%d;%d;%*c%c;", valeur, index, diviseur, unite) != 4) /* Parse la chaine de caractére et extrait les champs */
    return 1; /* Si sscanf n'as pas pu extraire les 4 champs -> erreur*/
  return 0; /* retourne 0 -> pas d'erreur */
Peux-tu m’aider à modifier ce programme pour que ma trame s’adapte à lui

Merci d'avance
Dernière modification par papy94 le 26 juin 2013 18:43, modifié 1 fois.
Avatar de l’utilisateur
laurent0091
Messages : 187
Inscription : 06 mars 2011 00:00
Localisation : Essone (91)
Contact :

Re: Transfer et Parser des données Arduino

Message par laurent0091 »

Bonjour Thierry,
tu aurais un petit schéma à nous monter pour voir la câblage entre tes deux cartes Nano et ton lecteur de carte SD il est branché comment?
Tu arrives à écrire sur ta carte Sd quand tu n'utilises qu'une seule carte Nano?

Laurent
Avatar de l’utilisateur
Geeks
Messages : 3593
Inscription : 03 juil. 2010 21:04
Localisation : Brive la Gaillarde (Correze 19)

Re: Transfer et Parser des données Arduino

Message par Geeks »

Oui, alors je pense que tu devra faire ton développement en 2 parties.

Il va falloir travaillé intelligement. Déjà, je pense aux routines. C'est des fonctions isolés qui vont travaillé à la demande en dehors de la boucle. On les appèlera dans la boucle au moment oportun.

Cas de la fonction émission:

Code : Tout sélectionner

/* DEFINITIONS */
#define SIZE_INFOS 5 //Pour 5 infos de 0 à 4

/* TABLEAUX GLOBAUX */
char tblInfos[SIZE_INFOS];	Ici on déclare un tableau de 5 cases, de 0 à 4

/* INITIALISATION */
void setup() {
	Serial.begin(9600); //Port Tx / Rx par défaut
}

/* BOUCLE */
void loop() {
	
	//Réceptionner les données
	tblInfos[0] = "A1";		//Info 1
	tblInfos[1] = "260";	//Info 2
	tblInfos[2] = "35";		//Info 3
	tblInfos[3] = "23.55";	//Info 4
	tblInfos[4] = "11.65";	//Info 5
	
	//Transmission des données
	envoyerTrame();

        delay(90);
}


/* FONCTION : envoyerTrame() */
void envoyerTrame() {
	Sring trame;
	
	//Parcourir les infos
	for(int i = 0; i < (SIZE_INFOS); i++) {
		trame += tblInfos[i]; //Pour chaque valeur de i de 0 à SIZE_INFOS
		
		//Si ce n'est pas la dernière info
		if(i <= (SIZE_INFOS-2)) {
			trame += ";"; //Ajoute un séparateur
		}
	}
	
	Serial.print(trame);	//Envoie la trame constitué
}
Bon là je t'ai fais un code complet qui va constituer des trames en théorie dans un tableau d'ont on a pris soins d'inquiquer le nombre de case "SIZE_INFOS". Si tu à plus de valeur, faut agrandir le nombre de case. Attention à ne pas dépasser les limites. Voir la doc à ce sujet.

Autre chose. Je ne suis pas certains que dans un char un nombre à virgule passera. Donc essaye, peut-être avec des chiffres entiers et voir si il ne faut pas non plus virer les guillemets.

Pour la réception, la je t'avouerais que c'est pas très compliquer. Il faut juste comprendre que la réception fait tomber les valeur dans un buffer qui se créera caractère par caractère. Et à ce titre, in risque d'avoir des confusions. Donc je vais essayer de te concocter un source simple pour comprendre.

Code : Tout sélectionner

/* DEFINITIONS */
#define SIZE_INFOS 5 //Pour 5 infos de 0 à 4

/* TABLEAUX GLOBAUX */
byte tblInfos[SIZE_INFOS];	Ici on déclare un tableau de 5 cases, de 0 à 4

/* INITIALISATION */
void setup() {
	Serial.begin(9600); //Port Tx / Rx par défaut
}

/* BOUCLE */
void loop() {
	
	//Reception des données
	receptionTrame();
	
	//Traitements
	//ici tblInfos[0] contiendra l'info 1
	//ici tblInfos[1] contiendra l'info 2
	//ici tblInfos[2] contiendra l'info 3
	//ici tblInfos[3] contiendra l'info 4
	//ici tblInfos[4] contiendra l'info 5
	
	delay(90ms);
}


/* FONCTION : receptionTrame() */
void receptionTrame() {
	
	int i=0;
	char* inf[SIZE_INFOS];
	char *ptr, buffer[SIZE_INFOS];	//Buffer
	
	memset(buffer, 0, SIZE_INFOS);	//Mise à 0 du buffer
	
	//Si on a une trame
	if(Serial.available() > 0) {
		
		//Pour chaque caractères reçu
		while(Serial.available() > 0) {
			
			buffer[i] = Serial.read();	//Contenu "read()" dans le buffer
			delay(3);
			++i;	//Incrémenter - Ici ne pas confondre avec i++.
		}
		
		//Parser les données
		inf[0] = strtok_r(buffer, ";", &ptr);	//Parse la chaine et sort la première info
		
		//Pour toutes les autres infos
		for(int i = 1; j < (SIZE_INFOS); j++) {
			cmds[j] = strtok_r(NULL, ";", &ptr); //Parse la chaine de nouveau et sirt la commande suivante
		}
		
		//Transformer chaque commande en plaçant dans le tableau final les infos.
		for(int k = 0; k < (SIZE_INFOS); k++) {
			tblInfos[k] = atoi(cmds[k]); 	//Ici Atoi transforme pour sortir du byte.
		}
	}
}

J'ai volontairement omis le code de la carte SD pour le moment car déjà tu dois pouvoir faire cela.
Code la carte émétrice. Scrute avec l'USB en mode série ce qu'envoie la carte. Si c'est Ok, code la deconde carte et envoie lui des données. Colle y un if (tblInfos[0] != 0) { //allumer une led, attendre 1s, eteindre la led... }
Cela prouvera que tes cartes communique.

Pour la carte SD, ce que j'ai mis là, c'est 1/10 de ce qu'il faut pour la suite. Dis moi si déjà cela te conviens ensuite, on passera à un exemple de carte SD. Moi, j'ai fais que la lecture et je me suis cassé les dents dessus ! Donc j'ai bien peur... Enfin bon, je sait que ma transmission fonctionne car, comme certains ont pu le voir à Jonzac, je manipule un engin spécial avec.
A défaut d'avoir la science infuse, j'infuse la science. - Racleur de fond depuis Pons 2014.
Sous-marin en état de repos sur cale : Minimog 01
Avatar de l’utilisateur
papy94
Messages : 653
Inscription : 23 janv. 2010 14:31
Localisation : Champigny sur marne
Contact :

Re: Transfer et Parser des données Arduino

Message par papy94 »

Déjà ,merci beaucoup Geeks de m'aider et de ta rapidité

donc si j'ai bien compris:

_pour la carte émettrice , je crée un tableau, et en fin de boucle je met mes valeurs dedans et j’envoie en fin de boucle
je testerais avec le serial monitor les données affichéess

_pour la carte réceptrice, je vais coller ton code et je verrais aussi avec le serial monitor



Donc ,mon but est de faire reagir ma carte réceptrice avec les données du tableau,et ensuite avec une trame recomposée de l'heure et des donnée reçus et de nouvelles données de la carte réceptrice, les envoyer sur une carte SD en tant que fichier texte avec comme delimateur de données le ";" , et ensuite récupérer le fichier en fin de navigation pour l'analyser et faire de jolies courbe avec Excel

Laurent :
Pour la carte émettrice ,je n'est plus de place pour ajouter des branchements, donc je met une autre carte relié entre elles par 3 fils (masse ,RX et TX croisés

pour le lecteur de carte SD, elle est la ,mais je n'ai pas encore essayé

le but ultime est pour plus tard,
transmettre avec émetteur/ récepteur 433mhz (que j'ai dans un tiroir),quand le soum est en surface ,envoyer les données sur un arduino,sur lequel j'aurais un écran et suivre donc certains paramètres et aussi pouvoir renvoyer des information au soum......... mais beaucoup plus tard ça ce fera

Laurent de toute façon je vais avoir besoin de Geeks, car les Types de variables me prennent le choux,et je pense que j'aurais souvent besoin de lui ,donc au fur et a mesure ce post va se garnir d'informations qui je pense te servirons
Dernière modification par papy94 le 07 juin 2013 07:19, modifié 1 fois.
Avatar de l’utilisateur
Geeks
Messages : 3593
Inscription : 03 juil. 2010 21:04
Localisation : Brive la Gaillarde (Correze 19)

Re: Transfer et Parser des données Arduino

Message par Geeks »

Ah oui mais à propos...

Tu aurais pu gagner de la place avec de l'I2C... :bave:

Il faut vraiment que je vous ouvre un sujet la dessus. Certains risque de décroché à force. Bien que bien que !
Ta solution d'une nouvelle carte est tout à fait acceptable et même démontre les possibilités de ce petit joyau technologique. Tu en a compris les précepts, il ne te reste plus qu'à développer tranquilement, sans tout faire à donf.

Là, j'ai pas pu essayer. Je me suis simplement basé sur ce que j'avais déjà fait moi et qui est assez similaire à ta demande :Up:

Bon, pour en revenir au fait d'avoir séparer le sujet. C'est une très bonne chose. Merci aux modérateurs qui l'ont fait. Ça devenais nécessaire.

Papy, panique pas si ça plante. Isole les codes afin de recherché ce qui ne va pas. Tente un coup de google avec le message d'erreur, parfois ça met sur la piste. ;)

Il me restera à demander un avis dans le bar (ou sous forme de sondage), pour savoir si vous voulez ce petit cours d'i2c :Up:

Merci.

Geeks, celui qui a deux cônes moteurs plus cher que le soum lui-même et qui est content d'aider Papy dans son projet :fete:
A défaut d'avoir la science infuse, j'infuse la science. - Racleur de fond depuis Pons 2014.
Sous-marin en état de repos sur cale : Minimog 01
Avatar de l’utilisateur
papy94
Messages : 653
Inscription : 23 janv. 2010 14:31
Localisation : Champigny sur marne
Contact :

Re: Transfer et Parser des données Arduino

Message par papy94 »

Je testerais ce week-end Geeks, et nous verrons si mes variables passent bien, mes int et mes fload, car mes capteurs envois avec le point décimal,et d' autres des entiers

Geeks a écrit :Ah oui mais à propos...
Tu aurais pu gagner de la place avec de l'I2C... :bave:
oui mais je n'ai que le capteur de pression en I2C


le lecteur de carte SD:
Image

433Mhz émetteur récepteur:
Image
Avatar de l’utilisateur
Geeks
Messages : 3593
Inscription : 03 juil. 2010 21:04
Localisation : Brive la Gaillarde (Correze 19)

Re: Transfer et Parser des données Arduino

Message par Geeks »

Ah oui, c'est cool ton histoire de 433 Mhz.
Je ne sait pas si sans une bonne antenne bien taillé, ça passera sous l'eau. Je dois faire des expérimentations dans ce sens là mais pour 2014. :Up:
A défaut d'avoir la science infuse, j'infuse la science. - Racleur de fond depuis Pons 2014.
Sous-marin en état de repos sur cale : Minimog 01
Avatar de l’utilisateur
papy94
Messages : 653
Inscription : 23 janv. 2010 14:31
Localisation : Champigny sur marne
Contact :

Re: Transfer et Parser des données Arduino

Message par papy94 »

c'est pour plus tard et pour l’émission réception, quand mon capteur de pression détectera une profondeur <10 cm, c'est a dire périscope sorties,j’emmétrai seulement a ce moment la donc cela devrait etre bon pour les ondes
Avatar de l’utilisateur
coaxial
Messages : 3673
Inscription : 23 janv. 2010 19:35
Localisation : saint orens 31

Re: Transfer et Parser des données Arduino

Message par coaxial »

Oups sont balaises ses moustachus :Up:


Bonne continuation , je me garde le lien du topic sous le coude , pour copier un peu plus tard ;)




:applaudi:
Moins je réfléchis plus fort et plus j'agis moins vite
Les bons crus font les bonnes cuites => Pierre Dac .
.... la simplicité est-ce bien la plus simple solution ..........?
La femme est l'avenir de l'homme .
Avatar de l’utilisateur
papy94
Messages : 653
Inscription : 23 janv. 2010 14:31
Localisation : Champigny sur marne
Contact :

Re: Transfer et Parser des données Arduino

Message par papy94 »

dans la partie émission :
mes variables sont déclarées ainsi

Code : Tout sélectionner

int Alarm = 0;
int Pression_Relative;
int Val_X = 0;
je lit direct la valeur du capteur :bmp.readTemperature())
float Tension = 14.50;
j'envois :

Code : Tout sélectionner

Serial.print(Alarm);Serial.print(";");
  Serial.print(Val_X - Ang_Milieu);Serial.print(";");
  Serial.print(Pression_Relative);Serial.print(";");
  Serial.print(bmp.readTemperature());Serial.print(";");
  Serial.print(Tension);
j'ai des erreur de variables quand je met ton code,mais bon je pense que mon programme sans ton code envoi les bonnes valeurs car je sort

Code : Tout sélectionner

1;-4;-1;27.54;4.89
6;-5;-5;27.54;4.74
6;-4;6;27.56;4.74
1;-2;-4;27.56;4.88
7;-6;9;27.56;4.88
1;-2;4;27.53;4.88
6;-4;2;27.52;4.74
6;-4;1;27.57;4.74
1;-2;0;27.57;4.89
---------------------------------
Dans la partie réception ; qui me bloque pour tester la réception

Code : Tout sélectionner

//Pour toutes les autres infos
      for(int i = 1; j < (SIZE_INFOS); j++) {
         cmds[j] = strtok_r(NULL, ";", &ptr); //Parse la chaine de nouveau et sirt la commande suivante
dans le "for" je pense que c'est j=1 a la place de i=1
et il me dis que cmd[j] n'est pas déclaré; je met quoi comme déclaration de variable
la je suis bloque, pour aller plus loin
Répondre