[débutant ][résolu]afficher des adresses de DS18B20 sur MI0283QT2.

Bonjour a tous ,
dans mon projet j'utilise des sonde DS18B20 avec la librairie :

#include <DallasTemperature.h>

il existe une fonction qui permet de visualiser sur le serial l'adresse d'une sonde :

void printAddress(DeviceAddress deviceAddress)
{
    
  for (uint8_t i = 0; i < 8; i++)
  {
    if (deviceAddress[i] < 16){ 
         Serial.print("0");   
     };
         Serial.print(deviceAddress[i], HEX);    
     }
 
}

je cherche a crée un tableau pour stocker les adresse sous forme de string mais je n'y arrive pas je dirai meme que j'avais completement planter mon arduino mega avec le code que j'ai ecrit que voici:

String *adresse_sonde; //Pointeur de tableau pour enregistrer nos adresse de sonde

DeviceAddress adresse_de_sonde; // Nous allons utiliser cette variable pour stocker une adresse de périphérique trouvé

int nombre_de_sonde; // Nombre de dispositifs de température trouvé

dans le setup:

//création d'un tableau de "n case"=nombre_de_sonde;  pour acceuillire les valeur des adresse des differente sonde  

 adresse_sonde= (String*)malloc(nombre_de_sonde);
  
String adresse[20];

 for( int index=0;index<nombre_de_sonde;index++){
   
   sondes.getAddress(adresse_de_sonde, index);
   
    for (uint8_t i=0; i<8; i++)
  {
    if (adresse_de_sonde[i]<16){ 
     
    Serial.print("0");   
     
  };
     
    Serial.print(adresse_de_sonde[i], HEX);    
     adresse=(adresse_de_sonde[i], HEX);
     
  }
              adresse_sonde[index]=adresse;//remplissage des casse du tableau
             
             Serial.print ("index : ");//affichage de l'index du tableau des valeur de sonde
              Serial.println (index);
              Serial.print ("adresse sonde : ");//affichage de la valeurde l'adresse de sonde pour l'index précité
              Serial.println (adresse_sonde[index]);
              adresse="";//remise a zero de la variable adresse
            }

comme je ne maîtrise pas bien les String je pense que je fait pas mal d'éreur au final , j'ai réussi pour les température avec le même type de système mais je n'y arrive pas pour les adresses.

le but étant de stocker toute les adresses de sonde dans un tableau pour pouvoir les afficher sur mon ecrant lcd

Bonjour, aie aie aie, tu es mal ^^ bref bon je pense que tu n'a pas saisie que un string est déjà un tableau de char et qu'il est impossible en C d'avoir un tableau de string, en python ou en C# ou autre oui, C C++ c'est pas la même chose, après on ne sais pas ce que tu entend par adresse? "nom"? "ak64d6d"? octet? int? il va falloir nous informer, la on ne peut pas t'aider,

Dit nous :

Format.
Rendu voulue.

après on pourra t'aidé la c'est incompréhensible...

Skizo !

Et les tableaux de tableaux alors cela n'existe pas ?
Je n'ai jamais encore essayé mais au hasard de la première recherche google je trouve
Tableaux de chaînes de caractères.

Je pense que tu devrais un petit peu vérifier tes affirmations, il y a ici des débutants qui, et c'est normal quand on débute, croient sur parole.

Amicalement
Bernard

Bonjour,

Pour skizoh (qui n'as pas du bien suivi ses cours) :
String n'est pas un tableau de char !
C'est une classe portant le nom "String" avec pour but de stocker des caractéres.

Il est donc tout fait possible de faire un tableau de string :

String tab[3]; // Ceci est un tableau de 3 String
tab[0] = "toto";
tab[1] = "titi";
tab[2] = "tata";

Ensuite en standard C89 un tableau de caractéres ce déclare comme suit :

char tab[5]; // Ceci est un tableau de 5 char

Un tableau de tableau (= tableau à plusieurs dimensions) ce déclare comme suit :

char tab[5][10]; // Ceci est un tableau de 5 tableaux de 10 char

--

Pour Heloderma-kris :
DeviceAddress est un type défini dans la librairie DallasTemperature.
Comme tout les autres types tu peut en faire des tableaux.

Exemple :

DeviceAddress tab[5]; // Ceci est un tableau de 5 DeviceAddress

Cependant je ne connais pas le typede DeviceAddress (est-ce une classe, un typedef, une struct ?) donc la méthode d'affectation sera à définir par toi même.
Si c'est une classe : tab[0] = adresse_truc
Si c'est un typedef ou une struct :

for(byte i = 0; i < sizeof(DeviceAddress); ++i)
  tab[0][i] = adresse_truc[i];

Remarque :
Sur un microcontrôleur il faut éviter à tout prix les allocations dynamique (2Ko de ram -> malloc = risque de fragmentation = crash, reset, ...) !
Dans ton cas le mieux est de fixer un nombre maximum de sonde (un nombre pas trop élevé de préférence) et de faire un tableau statique de DeviceAddress;

Merci pour vos reponse je commençai a avoir peur d'avoir rien compris , sa me rassure au final ,
j'ai regarder dans la librairie et j'ai trouver cela:

typedef uint8_t DeviceAddress[8];

si je comprend bien deviceAddresse et donc un tableau de 8 entier non signer (j'ai du mal encors avec uint8_t)!
si c'est bien cela il va falloire transformer les entier en char et les char en string non?

Pour skizo:
l'adresse et de la forme 28540656020000EE et est unique a chaque sonde !

skywodd: je vais essayer ton code pour voir si j'arrive a me depatouiller!

Salut,

j'ai un p'tit programme tout simple qui joue avec 2 sondes qui réponds pas exactement a ta question, mais pas loin.
Je te le mets, au cas ou ca te donne de l'inspiration

#include <OneWire.h> // librairie pour capteur OneWire

//---- code des instructions du capteur
const int modeLecture=0xBE;
const int lancerMesure=0x44;

// --- constantes des broches ---
const int broche_OneWire=2; // declaration constante de broche des capteurs
const int ledPin = 13;      // LED connectée à la broche n°13
const int inPin = 7;        // un bouton poussoir connecté à la broche 7 
                            // avec une résistance de pulldown


// --- Déclaration des variables globales ---
//byte data[12]; // Tableau de 12 octets pour lecture des 9 registres de RAM et des 3 registres d'EEPROM du capteur One Wire

// --- Déclaration des objets utiles pour les fonctionnalités utilisées ---
OneWire  capteur(broche_OneWire);  // crée un objet One Wire sur la broche voulue

void setup()   {
  pinMode(ledPin, OUTPUT);  // configure la broche 13 en SORTIE
  pinMode(inPin, INPUT);    // configure la broche 7 en ENTREE
  Serial.begin(115200);     // initialise connexion série à 115200 bauds
} 

void loop(){
  unsigned long time;
  int Temp1=0;
  byte Adresse2[8]={0x28,0xBF,0xF5,0x33,0x03,0x00,0x00,0x6D};
  int Temp2=0;
  byte Adresse1[8]={0x28,0x4D,0xF0,0x33,0x03,0x00,0x00,0xA3};
delay (500);
 while (1){
  Temp1=capteurMesureTemp(Adresse1)*10;
  Serial.print (Temp1,DEC);
  Temp2=capteurMesureTemp(Adresse2)*10;
  Serial.print (":");Serial.println(Temp2,DEC);
  digitalWrite(ledPin,0);
  time=millis()+28500; // 30-1.5 secondes pour 2 pts/minute
  while (millis()<time)
    {// petite tempo dont on peut sortir si un clic
     if (digitalRead(inPin)) break;
     if (Serial.available() > 0) {Serial.flush(); break;}
    }
  digitalWrite(ledPin,1);
 }
}

float capteurMesureTemp(byte adressecapteur[8]) { //fonction qui renvoie résultat float et ne reçoit rien
  //-------- variable locale de la fonction ----------
  byte data[12]; // Tableau de 12 octets pour lecture des 9 registres de RAM et des 3 registres d'EEPROM du capteur One Wire 
  int tempet=0; // variable pour resultat brute  de la mesure
  float tempetf=0.0; // variable pour resultat à virgule de la mesure
  // XXXXXXXXXXXXXXXXXXXXXX Lancement d'une mesure et lecture du résultat XXXXXXXXXXXXXXXXXXXXXXX 
  // Serial.println("**** Acquisition d'une mesure de la temperature **** "); 
  // avant chaque nouvelle instruction, il faut : 
  //    * initialiser le bus 1-wire
  //    * sélectionner le capteur détecté
  //    * envoyer l'instruction 
  //--------- lancer une mesure --------
  capteur.reset(); // initialise le bus 1-wire avant la communication avec un capteur donné
  capteur.select(adressecapteur); // sélectionne le capteur ayant l'adresse 64 bits contenue dans le tableau envoyé à la fonction
  capteur.write(lancerMesure,1); // lance la mesure et alimente le capteur par la broche de donnée
  //-------- pause d'une seconde ----- 
  delay(750);     // au moins 750 ms
  // il faudrait mettre une instruction capteur.depower ici, mais le reset va le faire
  //---------- passer en mode LECTURE ------------- 
  capteur.reset(); // initialise le bus 1-wire avant la communication avec un capteur donné
  capteur.select(adressecapteur); // sélectionne le capteur ayant l'adresse 64 bits contenue dans le tableau envoyé à la fonction
  capteur.write(modeLecture,1); // passe en mode lecture de la RAM du capteur
  // ----------- lire les 9 octets de la RAM (appelé Scratchpad) ----
  for ( int i = 0; i < 9; i++) {           // 9 octets de RAM stockés dans 9 octets
    data[i] = capteur.read();             // lecture de l'octet de rang i stocké dans tableau data
  }
  //----- caclul de la température mesurée (enfin!) ---------
  /*data[1]=data[1] & B10000111; // met à 0 les bits de signes inutiles
  tempet=data[1]; // bits de poids fort
  tempet=tempet<<8; 
  tempet=tempet+data[0]; // bits de poids faible
  */
  tempet=(data[1]<<8)|data[0]; // a l'arrache style !
  // --- en mode 12 bits, la résolution est de 0.0625°C - cf datasheet DS18B20
  tempetf=float(tempet)*6.25;
  tempetf=tempetf/100.0;
  return (tempetf);
}

Merci MiGaNuTs pour ton code avec ton code je pense que j'ai compris un peut mon erreure (je suis pas encors sur)! je me suis longment ploger dans l'explication de la librairie onewire sur mon_club_elec, et j'ai fait ça :

byte adresse[8]; // Tableau de 8 octets pour stockage du code d'adresse 64 bits du composant One Wire
String string_adresse[8];//
word c;
//--- affichage des 64 bits d'adresse au format hexadécimal

   for(int i = 0; i < 8; i++) { // l'adresse renvoyée par la fonction search est stockée sur 8 octets

    if (adresse[i]<16) {
      Serial.print('0');
      c=word(adresse[i], HEX);}; // pour affichage des O poids fort au format hexadécimal
    
    Serial.print(adresse[i], HEX); // affiche 1 à 1 les 8 octets du tableau adresse au format hexadécimal
    c=word(adresse[i], HEX);
    Serial.print(" ");
    string_adresse[i]=c;
    
  }

je ne suis pas chez moi en ce moment ce qui ne me permet pas de tester , penser vous que cela puisse fonctioner?
je vous joint un jpg de ce que j'ai compris et de ce que je souhaite faire car mes explication sont peut'etre pas trés clair

Tu peut aussi utiliser sprint pour faire la conversion hexa -> char[]
http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/

Regarde le mode %X et les arguments d'affichage (exemple %.4X = valeur hexa sur 4 digits avec zéro devant si besoin)

Salut,

Salut,

J'utilise cette fonction pour faire ce que tu veux :

// adresse to string
void addr2str(DeviceAddress deviceAddress, char* return_me)
{
     static char *hex = "0123456789ABCDEF";
     uint8_t i, j;

     for (i=0, j=0; i<8; i++)
     {
          return_me[j++] = hex[deviceAddress[i] / 16];
          return_me[j++] = hex[deviceAddress[i] & 15];
     }
     return_me[j] = '\0';
}

olebrun: je ne comprend pas ton code trop compliqué pour moi a decortiqué !
en fait j'ai essayer le code directe dans mon programe pour faire afficher par le LCD l'adresse au format hex comme on le ferai sur le serial
avec : lcd.print( addr2str(0,X));

je n'arrive pas a compiler , j'imagine que mon X ne a pas bien avec le pointeur !

bon j'ai réusi a obtenir un resultat qui me permet d'ecrire l'adresse de ma sonde sur le lcd sa donne sa :

void printAddress2(int index)
{
  
 char octet_lu[2];
 sondes.getAddress(adresse_de_sonde, index);
 for (uint8_t i = 0; i < 8; i++)
  {
    if (adresse_de_sonde[i] < 16){ 
     lcd.print("0");   
  };
     sprintf(octet_lu,"%.X", adresse_de_sonde[i]);
     lcd.print(octet_lu); 
    }
    
}

je n'arrive toujours pas a enregistrer mes adresse dans un tableau mais a la limite je m'en fout car je peux sauvegarder le numéro d'index de la sonde et sa me suffi pour, en cas de redémarrage système de réaffecter directement la sonde voulu a mes boucle de contrôle , puisque les sonde sont toujours classer par ordre d'adresse( enfin il me semble que sa marche comme sa!)

merci a vous tous pour vos réponse , mes question sont peut-être bette mais j'ai commencé la programmation en janvier sans connaissance en programmation , et en ce moment je me retrouve directement confronter a mes lacune et incompréhension, résultat mon projet avance a reculons !!! :grin:

Heloderma-kris:
je n'arrive toujours pas a enregistrer mes adresse dans un tableau mais a la limite je m'en fout car je peux sauvegarder le numéro d'index de la sonde et sa me suffi pour, en cas de redémarrage système de réaffecter directement la sonde voulu a mes boucle de contrôle , puisque les sonde sont toujours classer par ordre d'adresse( enfin il me semble que sa marche comme sa!)

merci a vous tous pour vos réponse , mes question sont peut-être bette mais j'ai commencé la programmation en janvier sans connaissance en programmation , et en ce moment je me retrouve directement confronter a mes lacune et incompréhension, résultat mon projet avance a reculons !!! :grin:

Bonjour Heloderma
je reprend là
je n'ai pas bien compris ton "probleme" 8)

je resume : 8)
tu fais de l'acquisition de T° capteurs 18B20
cette acquisition en 1W sur capteurs multiples fonctionne bien ?
sonde 1 T°=OK
sonde 2 T°= OK
..........
Sonde X T°=OK

Ton probleme là n'est qu'un "simple" probleme d'affichage sur LCD de l'adresse 1W du capteur en family 28 (18B20) ?
tu voudrais lire/afficher
28 XX XX XX ... CK ?

en fait au debut je voulais stoker les valeur des differente adresse dans un tableau pour les afficher lorsque sur mon ecrant tactile je recherche ma sonde sur la quelle je souhaite faire mes boucle de regulation.
et si besoint enregister l'adresse corespondant a ma sonde sur ma carte SD.
mais j'ai réusi grace a la fonction sprintf a obtenire l'afichage sur mon lcd de adresse de la sonde et je me suis rendu compte en relisant la librairie
#include <DallasTemperature.h>
que les adresse des differente sonde étaient toute enregistrer dans un tableau suivant un ordre qui est toujour le meme donc a moins de rajouter une sonde entre temps , a chaque demarage si je demande la sonde a l'adresse qui a pour index 2 j'aurrais toujour la meme sonde pour faire mes boucle de regulation!
le but etant lorsque l'on a une dizaine de sonde de pas galerer a savoir qui et qui , la il me sufi avant d'instaler me sonde de lire leur adresse une a une de le marque sur ma sonde et hop quand elle sont toute relier je choisi celle que je veux grace a son adresse!

j'esper que j'ai ete asser clair :grin:

Heloderma-kris:
...
que les adresse des differente sonde étaient toute enregistrer dans un tableau suivant un ordre qui est toujour le meme donc a moins de rajouter une sonde entre temps , a chaque demarage si je demande la sonde a l'adresse qui a pour index 2 j'aurrais toujour la meme sonde pour faire mes boucle de regulation!
le but etant lorsque l'on a une dizaine de sonde de pas galerer a savoir qui et qui , la il me sufi avant d'instaler me sonde de lire leur adresse une a une de le marque sur ma sonde et hop quand elle sont toute relier je choisi celle que je veux grace a son adresse!

j'esper que j'ai ete asser clair :grin:

  1. j'ai bien compris
    Attention incidemment à un point à ne pas occulter :
    si le bus 1W est très agréable à utiliser , c'est quand meme un bus "très lent" ( qui a dit comme les suisses ? :smiley: ) , un 18B20 en standard
    est donné pour une conversion en 750 ms , perso je tape sur la seconde , et indépendamment de l'occupation de l'arduino , c'est une notion à bien prendre en compte.

Mettre en place un processus d'acquisition temporel des sondes de l'ordre de 2/3 minutes par sonde est une solution.
dans la majorité des processus d'acquisition T°= "évolution meteo naturelle" c'est plus la courbe/tendance de progression que la valeur absolue instantanée qui est importante

pour pallier a ce problème je place mes valeur de température dans un tableau toute les 30seconde comme sa l'arduino peut faire autre chose!
j'ai utiliser sa pour l'affichage notament , apres dans mes regule je choisie la valeur corspondant a ma sonde
dans l'entete declarative :
float *temp_sonde; //Pointeur de tableau pour enregistrer nos temperature de sonde
dans le setup:

//création d'un tableau de "n case"=nombre_de_sonde;  pour acceuillire les valeur de temperature des differente sonde  
 temp_sonde= (float*)malloc(nombre_de_sonde);

et enfin dans le loop:

  if (temps()-temps_aquisition_sonde >30){ 
      for(int index=0;index<nombre_de_sonde;index++){
              temp_sonde[index]=temperatureX(index);//remplissage des casse du tableau
             #ifdef DEBUG_SERIAL Serial.print ("index : ");//affichage de l'index du tableau des valeur de sonde
              Serial.println (index);
              Serial.print ("temperature : ");//affichage de la valeur de sonde pour l'index précité
              Serial.println (temp_sonde[index]);
              #endif
}
temps_aquisition_sonde=temps();//réinitialisation de la variable temps d'aquisition avec temps
};

avec la fonction suivante:

/*_____________________________________________________________fonction mesure et conversion de la temperature_____________________________*/

float temperatureX(int index){
  sondes.requestTemperatures(); // Send the command to get temperatures
  float tempC = sondes.getTempCByIndex(index);
  return tempC; 
}

Heloderma-kris:
olebrun: je ne comprend pas ton code trop compliqué pour moi a decortiqué !
en fait j'ai essayer le code directe dans mon programe pour faire afficher par le LCD l'adresse au format hex comme on le ferai sur le serial
avec : lcd.print( addr2str(0,X));

je n'arrive pas a compiler , j'imagine que mon X ne a pas bien avec le pointeur !

Désolé, je n'ai pas détaillé. Juste à titre d'info vu que tu as trouvé un autre moyen :

char addr[17];
addr2str(ton_DeviceAddress_a_convertir_en_chaine_de_caractere, addr)
lcd.print(addr);

Merci sa m'aide a comprend en tout cas ! :grin: