Loading...
Pages: [1]   Go Down
Author Topic: [RESOLU] Lecture de paramètres sur fichier texte  (Read 603 times)
0 Members and 1 Guest are viewing this topic.
La Roche sur Yon - France
Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour,

J'utilise une Arduino Mega 2560 et un shiel Ethernet + SD.

Je stock l'adresse de mes sondes DS18B20 (sonde de température numérique) dans des tableaux de byte.
Code:
byte sonde1[8] = {0x28,0x12,0x21,0x8B,0x03,0x00,0x00,0xB7};
byte sonde2[8] = {0x28,0xAD,0x2D,0x8B,0x03,0x00,0x00,0xB5};

Ce que je souhaite faire c'est stocké ces données dans un fichier de config texte pour ne pas avoir à re-compiler mon code si je rajoute une sonde ou si j'en change une, et donc l'adresse.

Je stock donc dans un fichier texte les adresses des sondes DS18B20.
Voici le contenu de mon fichier :
Code:
28 12 21 8B 03 00 00 B7
28 AD 2D 8B 03 00 00 B5

Je parviens à lire le contenu de mon fichier, par contre, j'obtiens un résultat sous forme de String ou de tableau de char.
En analysant le tableau caractère par caractère, j'arrive à détecter les retours à la ligne (adresse suivante) et les espaces (composante d'adresse suivante)

Mon problème c'est que je n'arrive pas à convertir les char "2" et "8" en byte 0x28.

L'autre difficulté c'est que je peux avoir un nombre de sondes variable, là c'est 2 mais je peux très bien en avoir 3,4, ou plus encore.

J'ai bien essayer avec les fonctions sscanf et strtok pour coupé ma chaine automatiquement sur le caractère espace.
Rien ne fonctionne.

Je pense que j'ai des lacunes en terme de type de variable, de pointeur et autre joyeuseté du langage C  smiley-red

Si quelqu'un peut m'aider ou m'expliquer certaines choses ce sera avec grand plaisir.
Merci
« Last Edit: May 17, 2012, 08:57:27 am by jmatgou » Logged

Arduino Mega 2560 R2
Shield Ethernet + SD
Arduino 1.0

Ile-de-France (92 sud), France
Offline Offline
Edison Member
*
Karma: 22
Posts: 1817
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


Une petite fonction de conversion hexa vers nombre par exemple :

Code:
byte hex2int( char c )
{
  return 0x0F & (( c >= "A" ) ? (c - 'A' + 10) : (c - '0'));
}

et puis par exemple pour convertir 2 caractères en 1 octet :

Code:
byte x = hex2int( p[i] ) << 4 | hex2int( p[i+1] );

Pas le plus optimisé mais simple à comprendre.

Avec çà tu devrais pouvoir avancer
Logged

Barbuduino: Arduino sur Breadboard & VinciDuino: Clone Leonardo // WR703: Mini-routeur hacké // LauchPad MSP430 et Stellaris // Panda II Arduino-like .NetMF sous VisualC#
RTFC: Read That F.....g Code / RTFD: Read That F.....g Doc / RTFDS: Read That F.....g DataSheet / RTFS: Read That F.....g Schematic / Wot da ya wanna D.I.Y. today ?

France
Offline Offline
Faraday Member
**
Karma: 36
Posts: 4451
Arduino Hacker
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Salut,

Si tu veut "lire" des données en hexa depuis un tableau de char tu peut utiliser la fonction sscanf smiley-wink
http://www.cplusplus.com/reference/clibrary/cstdio/sscanf/
Logged

Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

La Roche sur Yon - France
Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour,

Merci pour vos indications.
J'ai avancé grâce à "sscanf" mais tout n'est pas gagné.

Je parviens à lire la première ligne de mon fichier et à stoker les données dans un tableau de byte.

Voici mon code :
Code:
#include <SD.h> //pour utiliser le lecteur SD

// pour la gestion des chaines de caractères
#include "print.h"
#include "string.h"
#include "stdio.h"

byte adr[8];

void setup() {
  Serial.begin(57600);
 
  pinMode(53, OUTPUT);
  SD.begin(4);
 
  File sondeFile = SD.open("SONDES.TXT", FILE_READ);
  byte inByte = 0 ;
  char ligne[40] = "";
  byte nbChar = 0;
  byte adr[8];

  while (sondeFile.available()) {   //tant qu'il y a des caractères à lire dans mon fichier
    inByte = sondeFile.read(); //je stocke le caractère qui arrive
    Serial.write(inByte); //je l'ecrit pour controler
    if(inByte == 0x0D) { break; } // si c'est une fin de ligne, je sors
    ligne[nbChar] = inByte; // je stock ce caractère dans mon tableau
    nbChar++; // j’incrémente l'index de mon tableau
  }
  sondeFile.close();
  Serial.println();

  //je "parse" ma ligne (tableau de char) et je colle chaque "paquet" de l'adresse dans mon tableau
  sscanf (ligne,"%x %x %x %x %x %x %x %x ",&adr[0],&adr[1],&adr[2],&adr[3],&adr[4],&adr[5],&adr[6],&adr[7]);

  // une petite boucle pour controler
  for(int i = 0; i < 8; i++) {
    Serial.println(adr[i], HEX);
  }
}

void loop() {}

Au final ça me donne bien le résultat escompté.
C'est comme si j'avais déclaré mon tableau d'adresse en dur:
Code:
byte adr[8] = {0x28,0x12,0x21,0x8B,0x03,0x00,0x00,0xB7};

Par contre comment gérer les x lignes suivantes, je rappel que mon fichier texte est composé de la manière suivante :
Code:
28 12 21 8B 03 00 00 B7
28 AD 2D 8B 03 00 00 B5
...
...

Je ne vois pas comment stocker dynamiquement les x adresses suivantes.
J'imagine qu'il faut utiliser un tableau de tableau (ou tableau à 2 dimensions) de taille dynamique mais là je sèche.

Si quelqu'un à une idée.
Merci d'avance
Logged

Arduino Mega 2560 R2
Shield Ethernet + SD
Arduino 1.0

Ile-de-France (92 sud), France
Offline Offline
Edison Member
*
Karma: 22
Posts: 1817
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Oui il faut un tableau a 2 dimensions :
Code:
#define NBMAX_SONDES     8
int adr[NBMAX_SONDES][8];
int nbSondes = 0;

et dans ta boucle
Code:
if( inByte == 0x0D)
{
    sscanf (ligne,"%x %x %x %x %x %x %x %x ",&adr[nbSondes][0],&adr[nbSondes][1],&adr[nbSondes][2],&adr[nbSondes][3],&adr[nbSondes][4],&adr[nbSondes][5],&adr[nbSondes][6],&adr[nbSondes][7]);
    nbSondes++;
    nbChar = 0;
}
else
{
    ligne[nbChar] = inByte; // je stock ce caractère dans mon tableau
    nbChar++; // j’incrémente l'index de mon tableau
}

Attention sscanf( ligne , "%x" , ) attend un pointeur sur int, pas sur byte.
A la fin du va jardiner en dehors de ton tableau.

Au lieu de faire la boucle à la main tu peux aussi utiliser readBytesUntil()
« Last Edit: May 17, 2012, 08:31:24 am by barbudor » Logged

Barbuduino: Arduino sur Breadboard & VinciDuino: Clone Leonardo // WR703: Mini-routeur hacké // LauchPad MSP430 et Stellaris // Panda II Arduino-like .NetMF sous VisualC#
RTFC: Read That F.....g Code / RTFD: Read That F.....g Doc / RTFDS: Read That F.....g DataSheet / RTFS: Read That F.....g Schematic / Wot da ya wanna D.I.Y. today ?

La Roche sur Yon - France
Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Merci pour ton aide.
Je pensais bien faire quelque chose comme ça, mais ça m'ennuie de déclarer une valeur MAX, même si effectivement j'en aurais jamais plus de 8.

Je vais partir la dessus.
Par contre je ne comprend pas ce que tu veux dire par
Quote
Attention sscanf( ligne , "%x" , ) attend un pointeur sur int, pas sur byte.
A la fin du va jardiner en dehors de ton tableau.
Logged

Arduino Mega 2560 R2
Shield Ethernet + SD
Arduino 1.0

Ile-de-France (92 sud), France
Offline Offline
Edison Member
*
Karma: 22
Posts: 1817
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

sscanf( , "%x", &variable ) va écrire un int sur 2 octets et pas juste un byte.
Donc lorsque sscanf parcours la chaine et trouve la première valeur elle l'écrit sur les 2 octets à partir de &adr[0], c'est à dire sur adr[0] et sur adr[1] qui est l'octet suivant.
Là c'est pas top grave.
mais sur le dernier octet, sscanf écrit sur adr[7] et adr[8] qui estune case mémoir en dehors de ton tableau et qui peut être utilisé par une autre variable.
C'est ce qu'on appelle le jardinage ou écrasement mémoire. Cela peut conduire aller d'un programme qui ne fait pas ce qu'on s'attend, ou des plantages violents genre auto-reset.

Logged

Barbuduino: Arduino sur Breadboard & VinciDuino: Clone Leonardo // WR703: Mini-routeur hacké // LauchPad MSP430 et Stellaris // Panda II Arduino-like .NetMF sous VisualC#
RTFC: Read That F.....g Code / RTFD: Read That F.....g Doc / RTFDS: Read That F.....g DataSheet / RTFS: Read That F.....g Schematic / Wot da ya wanna D.I.Y. today ?

La Roche sur Yon - France
Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok, j'ai compris, c'est pour cela que le tableau adr n'est plus de type byte mais int.

En tout cas, merci beaucoup, ça fonctionne !  smiley
Logged

Arduino Mega 2560 R2
Shield Ethernet + SD
Arduino 1.0

Ile-de-France (92 sud), France
Offline Offline
Edison Member
*
Karma: 22
Posts: 1817
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Sinon, tu peux garder des byte mais en ajoutant un élément inutile :
Code:
byte adr[NBMAX_SONDES][9];
Ca gagne de la mémoire.
Logged

Barbuduino: Arduino sur Breadboard & VinciDuino: Clone Leonardo // WR703: Mini-routeur hacké // LauchPad MSP430 et Stellaris // Panda II Arduino-like .NetMF sous VisualC#
RTFC: Read That F.....g Code / RTFD: Read That F.....g Doc / RTFDS: Read That F.....g DataSheet / RTFS: Read That F.....g Schematic / Wot da ya wanna D.I.Y. today ?

Pages: [1]   Go Up
Print
 
Jump to: