Go Down

Topic: [Résolu]Comment bien comprendre/utiliser les bytes, les doubles et les char (Read 1 time) previous topic - next topic

pierrot10

Bonjour,
Je suis dans le train et je viens d'essayer la solution que j'ai faite ce matin.
En fait, je pense que je me SUIS COMPLIQUER la vie.

Au lieux d'empiler en byte, j'empile en char et dès que tous mes variable sont dans mon buffer, je converti.

Ca fonctionne

Code: [Select]

    sprintln(F("\nValeurs des capteurs actifs"),2);
    sprintln(F("---------------------------------------"),2);
    sprint(F("Nombre de capteurs: "),2);
    sprintln(nbMaxCapteurs,2);
    sprint(F("Nombre de capteurs actifs: "),2);
    sprintln(nbCapteurActif,2);
   
    sprint(F("Valeurs:\t"),2);

    // Clean char_buffer
    memset(char_buffer,'\0',BUFFERSIZE);
    // Loop la strcture des capteurs
    for (byte i = 0; i < nbMaxCapteurs; i++) {
      if (mesCapteur[i].actif) { // si le capteur n'est pas actif on n'imprime pas
     
        // PRINT LES MESURES MESUREES
        sprint(mesCapteur[i].nomDuCapteur,2);
        sprint(F(":"),2);
        sprint(mesMesures[i][mesCapteur[i].idDuCapteur].valeur,2);
        if (i < nbCapteurActif+1) sprint(F(","),2);
       

        // --------------------------------------------------------
        // EMPILE LES VALERUS MESUREE DANS mydata POUR LES ENVOYER A TTN

        if(i==0)
        {
          //strcpy(char_buffer, mesCapteur[i].nomDuCapteur);
          // Ajoute 0 à la fin du text
          char_buffer[strlen(mesCapteur[i].nomDuCapteur)]='\0';
          //strcat(char_buffer, ":");
          strcpy(char_buffer, mesMesures[i][mesCapteur[i].idDuCapteur].valeur);
        }
        else
        {
          //strcat(char_buffer, mesCapteur[i].nomDuCapteur);
          //strcat(char_buffer, ":");
          strcat(char_buffer, mesMesures[i][mesCapteur[i].idDuCapteur].valeur);
        }
       
        if (i < nbCapteurActif+1)
        {
          strcat(char_buffer, ",");
        }
        char_buffer[strlen(char_buffer)]='\0';


      }
    }
    sprintln(F("\n"),2);
       
 
    // JE CONVERTI EN BYTE DANS MYDATA
    memset(mydata, 0xFF, tailleMax);
    // DEBUG
    printData();
   
    strcpy((char *) mydata, char_buffer);
    printData();
     

// J ENVOIE
    sprint(F("\nOpmode check: "),2);
    LMIC_setTxData2(1, mydata, strlen((char *)mydata), 0);


Le premier printData affiche
Quote
mydata = { FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF }
Et le deuxieme
Quote
mydata = { 34 2E 33 31 2C 32 32 34 37 2C 2D 31 34 33 31 33 2C 34 32 34 30 30 2C 33 34 35 30 2C 31 34 30 31 34 35 2C 2C 2C 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF }
Par contre, j'ai aussi remarqué que mydata est trop petit pour tout avoir, dans le cas ou j'active tous mes capteur. Donc j'ai supprimer le nom et les :. Il faudra encore que je réfléchisse comment mieux faire, pour la leture des données reçues au serveur.

Par contre, je ne vais pas rester là, ce soir j'appliquerai votre exemple
1) par respect à votre travail et aide
2) pour mieux me familiarisé avec les pointeurs (c'est sujet que je ne maitrise vraiment pas)
3) et surement parce que c'est meiux  :)

Aussi la fonction printData m'a bien aider de voir le contenu de mydata et réaliser que j'avais trop de caracteres pour mydata.

... (je dois sortir du train..)
Bon finaprès-midi
Il ne suffit pas de tout savoir, la persévérance, c'est déjà presque tout!
You can not know everything, perseverance, it is almost everything!

J-M-L

Quote
// JE CONVERTI EN BYTE DANS MYDATA
    strcpy((char *) mydata, char_buffer);
ça ne sert à rien.

Vous avez déjà des BYTEs dans char_buffer, il n'y a rien à convertir... vous dupliquez simplement les données avec strcpy (et je n'ai pas regardé si vous aviez bien mis un '\0' à la fin)

je vous laisse lire mon exemple
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

pierrot10

#17
Sep 19, 2017, 08:37 pm Last Edit: Sep 19, 2017, 09:12 pm by pierrot10 Reason: Supressio d'un commentaire
Bonjour,
Je pense que j'arrive au bout.
Le problème qu'il y avec ton exemple c'st vous utilisez des byte pour les valeur.

Par ecemple ici:
Code: [Select]

allMesures[batterie][0].mesure = 0xDD33;

Vous définissez une valeur
et ici vous l'exploiter
Code: [Select]
* ((uint16_t *) ptr) = allMesures[s][m].mesure;
// Dans mon casallMesures[s][m].mesure est un char


Quand je compile, j'ai ce message
Quote
invalid conversion from 'char*' to 'uint16_t {aka short unsigned int}' [-fpermissive]
Le problème est que ce vous utilisez des bit, dans votre exemple.
Mes fonctions prendre les valeurs des capteurs me retourne un char
Code: [Select]

void get_luminosity(char * luminosity)

{

[...code...]
dtostrf(lux,4,0,luminosity); // lux est un double
}




Donc je me retrouve toujours bloqué avec ce passage....


Il ne suffit pas de tout savoir, la persévérance, c'est déjà presque tout!
You can not know everything, perseverance, it is almost everything!

J-M-L

Pourquoi ne pas retourner lux ou mieux encore la lecture de l'échantillon ?

Dans votre cas vous n'avez pas besoin d'une représentation ASCII des données
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

pierrot10

Ben chais pas. Je me prends le chou :)
La réflection est bonne
Toute mes fonctions mesures de valerus en double.

C'est moi qui ai ajouté un bout de code pour
1. garder deux decimal
2. retoruner le tout en char

dtostrf(lux, 4, 0, luminosity);


Pour répondre à votre question lux est un double et dans votre exemple vous utiliser des uint8_t et unit16_t

Ce que j'essaye de faire maintenant, c'est que ma fonction me retourne la valeur hexa.
Par exemple si lux est egal à 24.65, ma fonction me retorunerai un uint8_t avec la valeur de

Quote
32 34 2e 36 35
ou encore mieux, pour supprimer la virgule, je multiplie par cent et me fonction me retorunerai
Quote
32 34 36 35
Je ne sais pas si je pense juste, mais ainsi, je pourrai reprendre votre exemple
Code: [Select]
* ((uint16_t *) ptr) = allMesures[s][m].mesure


Est-ce que je ferai bien de me préoccuper sur le type de la valeur retournée? Au fond, "tout raisonne" en bit, finallement...  :o  :o


Il ne suffit pas de tout savoir, la persévérance, c'est déjà presque tout!
You can not know everything, perseverance, it is almost everything!

pierrot10

Code: [Select]

//void get_luminosity(char * luminosity)
void get_luminosity(uint8_t lum)
{
  /*
    LUMINOSITY
  */
#ifdef SENSOR_TSL2561
  if (millis() > scheduler_lux)
  {
    scheduler_lux = millis() + INTERVAL_LUX;

    sprintln(F("\nLuminosity Sensor"), 2);
    sprintln(F("******************************"), 2);


    // ms = 1000;
    // light.manualStart();
    // delay(ms);
    // light.manualStop();

    unsigned int data0, data1;

    if (light.getData(data0, data1))
    {
      
      double lux;    // Resulting lux value
      boolean good;  // True if neither sensor is saturated

      // Perform lux calculation:
      good = light.getLux(gain, ms, data0, data1, lux);

      // Print out the results:

      //Serial.print(" lux: ");
      sprint(lux, 2);
      if (good)
        sprintln(F(" (good)"), 2);
      else
        sprintln(F(" (BAD)"), 2);

      //Serial.print(F("\t"));

      lux = lux * 100;
      Serial.print(F("DEBUG: uint8_t ")); Serial.println(lux);
      dtostrf(lux, 4, 0, luminosity);
      Serial.print(F("DEBUG: uint8_t ")); Serial.println(luminosity);
      lum = (uint8_t)atoi(luminosity);
      Serial.print(F("DEBUG: uint8_t ")); Serial.println(lum);
      Serial.print(F("DEBUG: uint8_t ")); Serial.println(lum,HEX);
      
      
     // dtostrf(lux, 4, 0, luminosity);

    }
    else
    {
      // getData() returned false because of an I2C error, inform the user.

      byte error = light.getError();
      printError(error);
    }
  }
#else
  sprintln(F("\nSENSOR_TSL2561 (Luminosity) unactive"), 2);
#endif
}
Il ne suffit pas de tout savoir, la persévérance, c'est déjà presque tout!
You can not know everything, perseverance, it is almost everything!

J-M-L

Il faut décider où vous voulez faire les calculs

Un double c'est 4 octets sur un arduino « standard » donc similaire à ce que je fais pour chrono
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

pierrot10

Je perds patience :)
Je vais lassiser mes fonctions comme elles sont. Elle fonctionne sauf "qu'elle returne les valeur en char"  :)

Je sais pas si vous avez encore le courage de me suivre  :)  mais en tout cas merci

Je vais rapidement résumer ma situation en fonction des exemple que vous m'avez donner entre hier et aujourd'hui.

D'abord, je déclare de structure
Code: [Select]

const byte capteur_battery_id = 0;
const byte capteur_temperature_id = 1;
const byte capteur_pression_id = 2;
const byte capteur_alt_id = 3;
const byte capteur_humidity_id = 4;
const byte capteur_moisture_id = 5;
const byte capteur_luminosity_id = 6;
const byte capteur_uv_id = 7;
const byte capteur_latitude_id = 8;
const byte capteur_longitude_id = 9;
const byte capteur_datetime_id = 10;


// JE NE LES METS PAS TOUS; MAIS C EST LA MEME CHOSE POUR LES AUTRES CAPTEURS
#ifdef SENSOR_BATTERY
bool battery_active = true;
#else
bool battery_active = false;
#endif

#ifdef SENSOR_TSL2561
bool luminosity_active = true;
#else
bool luminosity_active = false;
#endif

struct capteur
{
  uint8_t idDuCapteur;
  boolean actif;
  char nomDuCapteur[2];
};
/*
J'ai changer les noms des capteurs, qui sont certe pas trop parlant, mais je voulais prendre des élment qui prend le moins de bit possible
Donc ceci est devenu
ba = a
te = b
pr = c
al = d
hu = e
mo = f
lu = g
uv = h
la = j
lo = k
da = l
*/




capteur mesCapteur[] = {
  {capteur_battery_id, battery_active, "a"},
  {capteur_temperature_id, temperature_active, "b"},
  {capteur_pression_id, pression_active, "c"},
  {capteur_alt_id, alt_active, "d"},
  {capteur_humidity_id, humidity_active, "e"},
  {capteur_moisture_id, moisture_active, "f"},
  {capteur_luminosity_id, luminosity_active, "g"},
  {capteur_uv_id, uv_active, 'h'},
  {capteur_latitude_id, latitude_active, "j"},
  {capteur_longitude_id, longitude_active, "k"},
  {capteur_datetime_id, datetime_active, "l"},
};



enum : byte {c_battery = 0, c_temperature, c_pression, c_alt, c_humidity, c_moisture, c_luminosity, c_uv, c_latitude, c_longitude, c_datetime}; // dans le même ordre que mesCapteurs
const byte nbMaxCapteurs = sizeof(mesCapteur) / sizeof(mesCapteur[0]);

struct mesure {
  uint16_t id_capteur;
  char when[20]; // moment de la mesure
  char valeur[20]; // valeur mesurée (adapter le type)
  // autre chose de pertinent à mémoriser lors d'une mesure ?
};

const byte tailleHistorique = 11; // Ce chiffre doit correspondre aux nombres de capteurs. Voir capteur mesCapteur[] = {
mesure mesMesures[nbMaxCapteurs][tailleHistorique];


Dans ma fonction do_send qui envoie les données au serveur,
je fais appelle à plusieurs fonction come
Code: [Select]

// La variable passées en paramètre sont de char
// char humidity[20];
get_luminosity(luminosity);
get_luminosity(humidity);


Et voicl le fameux passage qui me cause tant de cheveux blanc  :)

(je me suis basé sur votre exemple d'aujourd'hui)
Une fois que j'ai tout mes valaurs de capteur

Code: [Select]



void do_send(osjob_t* j)
{
/*
* [.. code ..] J'appelle mes fonctions "capteurs" comme ci-dessous
*/
#ifdef SENSOR_BMP180
    get_baro(mesMesures[c_temperature][capteur_temperature_id].valeur, mesMesures[c_pression][capteur_pression_id].valeur, mesMesures[c_alt][capteur_alt_id].valeur);
#endif
#ifdef SENSOR_DTH22
    get_humidity(mesMesures[c_humidity][capteur_humidity_id].valeur);
#endif
#ifdef SENSOR_TSL2561
    get_luminosity(mesMesures[c_luminosity][capteur_luminosity_id].valeur);
#endif


// PLUS HAUT, J AI MES FONCTION QUI VONT ME PERMETRE D AVOIR LES VALEUR DE MES CAPTEURS

// CODE BASE SUR L EXEMPLE D HIER
    // http://forum.arduino.cc/index.php?topic=500386.new#new
    // imprimer la liste des capteurs
    sprintln(F("\nListe des capteurs"), 2);
    sprintln(F("---------------------------------------"), 2);

    byte nbCapteurActif = 0;
    for (byte i = 0; i < nbMaxCapteurs; i++) {
      sprint(F("Capteur: ["), 2);
      sprint(mesCapteur[i].nomDuCapteur, 2);
      sprint(F("]\t"), 2);
      sprint(F("actif: "), 2); sprint(mesCapteur[i].actif ? F("VRAI") : F("FAUX"), 2);
      if (mesCapteur[i].actif)nbCapteurActif++;
      sprint(F("\tID: "), 2); sprintln(mesCapteur[i].idDuCapteur, 2);
    }
 

 // CI-DESSUS, CA FONCTIONNE TRES BIEN


 
    sprintln(F("\nValeurs des capteurs actifs"), 2);
    sprintln(F("---------------------------------------"), 2);
    sprint(F("Nombre de capteurs: "), 2);
    sprintln(nbMaxCapteurs, 2);
    sprint(F("Nombre de capteurs actifs: "), 2);
    sprintln(nbCapteurActif, 2);

    sprint(F("Valeurs:\t"), 2);

    // Loop la strcture des capteurs

    uint8_t * ptr = mydata; // expl d'ajourd'hui

    for (byte i = 0; i < nbMaxCapteurs; i++) {
      if (mesCapteur[i].actif) { // si le capteur n'est pas actif on n'imprime pas

        // PRINT LES MESURES MESUREES
        sprint(mesCapteur[i].nomDuCapteur, 2);
        sprint(F(":"), 2);
        sprint(mesMesures[i][mesCapteur[i].idDuCapteur].valeur, 2);
        if (i < nbCapteurActif + 1) sprint(F(","), 2);
 
// CI-DESSUS, CA FONCTIONNE TRES BIEN


        // --------------------------------------------------------
        // EMPILE LES VALERUS MESUREE DANS mydata POUR LES ENVOYER A TTN

// BASE SUR L EXEMPLE D HIER ET SURTOUT D AUJOURD'HUI
        /*
 * JE NE SUIS PAS SURE DE GARDER LE NOM DU CAPTEUR, SI TOUT NE DEVAIT PAS RENTRE DANS mydata[64]
 * JE CROIS QUE TTN NE PERMET D ENVOYER PLUS. DANS CE CAS J'AJOUTE DES VIRGULE POUR AVOIR UN TRUC DU GENRE
 * mydata = {3.7,234,56.66,,,,453,,34}
 * les vides entre les virgule sont des capteurs inactif. Ainsi, au niveau du serveur je saurai qu a la position
 * 1 ca sera toujours la batterie, positon 2 toujours temperature, pos 3 toujours pression, etc
 */
 
 /* MON PROBLEM */
 
 // J'ajoute le nom du capteur, mais mesCapteur[i].nomDuCapteur; est un char. Comment e convertir en hex
 // pour que mon terminal ne m'affiche pas une erreur. Dans votre exmple, vous utliser des hex comme valeur
 *ptr = mesCapteur[i].nomDuCapteur; // Le nome du capteur est une lettre comme a
        ptr += sizeof(char); // Je deplace mon pointeur

 // IDEM QUE PLUS HAUT, J AJOUTE la valeur, mais c'est un CHAR
        * ((uint16_t *) ptr) = mesMesures[i][mesCapteur[i].idDuCapteur].valeur;
        ptr += (uint16_t); // Je deplace mon pointeur

 // SI CE N EST PAS LE DERNIER CAPTEUR, J AJOUTE UNEVIRGULE
        if (i < nbCapteurActif+1)
        {
          *ptr = '2C'; // virgule
          ptr += (char); // JE DEPLACE MONPOINTEUR
        }
 
 printData();
 /*
 * PRINT DATA DEVRAIT M AFFICHER L'EQUIVAENCE DE
 * a3.6,b24.44,c345.55,d424.33,h33.33
 * ou
 * 3.6,24.44,345.55,424.33,,,,33.33,,
 * Si je n'utilisait pas les noms des capteurs. Mais il faudra que mes capteurs s'inscrivent toujours dans le meme ordre
 * Je pesne que cette derniere option ne sera pas compliquée a traitée, cote serveur
 */
  
  
      }
  else
  {
 // SI INACTIE, AJOUTE UNE VIRGULE POUR LES CAPTEURS INACTIF
 
  }
    }
    sprintln(F("\n"), 2);

    // On met le buffer à zero partout
    // (pas nécessaire juste pour montrer, une variable globale sera à 0 la première fois)
    //memset(mydata, 0xFF, tailleMax);
    // DEBUG
    printData();

    //strcpy((char *) mydata, char_buffer);
    //printData();

// ENVOIE DES DONNEES. CECI FONCTIONNE TRES BIEN
    sprint(F("\nOpmode check: "), 2);
    LMIC_setTxData2(1, mydata, strlen((char *)mydata), 0);
}


J'epère que je suis sur la bonne voie. Mais mon probleme est vraiment de convertir des char en hex/uint8_t/bits...

:o  :)  :smiley-confuse:
Il ne suffit pas de tout savoir, la persévérance, c'est déjà presque tout!
You can not know everything, perseverance, it is almost everything!

fdufnews

Code: [Select]
enum : byte {c_battery = 0, c_temperature, c_pression, c_alt, c_humidity, c_moisture, c_luminosity, c_uv, c_latitude, c_longitude, c_datetime}; // dans le même ordre que mesCapteurs
const byte nbMaxCapteurs = sizeof(mesCapteur) / sizeof(mesCapteur[0]);

struct mesure {
  uint16_t id_capteur;
  char when[20]; // moment de la mesure
  char valeur[20]; // valeur mesurée (adapter le type)
  // autre chose de pertinent à mémoriser lors d'une mesure ?
};

const byte tailleHistorique = 11; // Ce chiffre doit correspondre aux nombres de capteurs. Voir capteur mesCapteur[] = {
mesure mesMesures[nbMaxCapteurs][tailleHistorique];

Donc on a:
    11 capteurs
    une structure mémorisant une mesure d'une taille de 42 octets par capteurs
    un historique de 11 mesures

Ce qui fait 11 x 11 x 42 = 5082 octets
D'où la question, pourquoi stocker les résultats des mesures sous forme d'une chaîne de caractères au lieu d'un long ou d'un float?
On arriverait alors à une taille de 11 x 11 x 10 = 1210 octets
Tu peux faire la conversion en chaîne de caractères au moment de l'envoi ce qui est beaucoup plus économique en matière de gestion de la mémoire.

Comme te l'a déjà expliqué J-M-L, byte, char et uint8_t sont la même chose ce sont des octets. C'est la manière de les interpréter qui change.

Vue le nombre de capteur et le contenu des mesures, les informations à envoyer consommeront toujours plus de 64 octets. Il suffit tout simplement de compter les octets que tu empiles dans mydata et de déclencher l'émission des données lorsque le compte arrive à 64 et de reprendre le remplissage du tampon après que l'envoi est terminé.

J-M-L

Vous faites
Code: [Select]
struct capteur
{
  uint8_t idDuCapteur;
  boolean actif;
  char nomDuCapteur[2];
};
--> le nom du capteur est donc un tableau de caractère, une c-string avec un char suivi d'un '\0'.... c'est un peu ballot.. autant déclarer le nom comme étant juste un char. (cf mon dernier exemple)

donc ça ne peut pas marcher (quand vous dites "mais mesCapteur[i].nomDuCapteur; est un char" ce n'est pas le cas, c'est un pointeur en mémoire sur un tableau de 2 caractères)

Code: [Select]
// J'ajoute le nom du capteur, mais mesCapteur[i].nomDuCapteur; est un char. Comment e convertir en hex
 // pour que mon terminal ne m'affiche pas une erreur. Dans votre exmple, vous utliser des hex comme valeur
 *ptr = mesCapteur[i].nomDuCapteur; // Le nome du capteur est une lettre comme a
        ptr += sizeof(char); // Je deplace mon pointeur
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

pierrot10

@J-M-L
Oui, excuse moi, j'avais mal corrigé
Code: [Select]

struct capteur
{
  uint8_t idDuCapteur;
  boolean actif;
  const char * nomDuCapteur;
};


@fdufnews
Merci de te joindre  :)

Quote
Donc on a:
    11 capteurs
    une structure mémorisant une mesure d'une taille de 42 octets par capteurs
    un historique de 11 mesures
Oui disons que je prévois des options. En fonction du besoin je pourrais en activer au pas, Mais évidemment, je fais en sorte que toutes les valeurs peuvent être envoyée..
Code: [Select]

//#define SENSOR_BATTERY      // Battery Voltage
//#define SENSOR_GPS        // latitude, longitude, datetime
//#define SENSOR_MEMORY     // Free memory
//#define SENSOR_BMP180       // Barometer (temperature/pression/alt)
#define SENSOR_TSL2561      // Luminoisty
//#define SENSOR_DTH22        // Humidity (Temrature)
//#define SENSOR_MOISTURE
//#define SENSOR_UV

#ifdef SENSOR_BATTERY
bool battery_active=true;
#else
bool battery_active=false;
#endif
//etc..


Quote
D'où la question, pourquoi stocker les résultats des mesures sous forme d'une chaîne de caractères au lieu d'un long ou d'un float?
Mais c'est une très bonne réflection et je me siuos penché la dessus hier...

Il faudrait alors que mes fonctions me retournent de long ou des float, au lieux de chaine de caractère. Je suis tout à fait d'accord d'aller ainsi. Surtout si On arriverait alors à une taille de 11 x 11 x 10 = 1210 octets.

Je vais donc modifier mes fonctions pour avoir des floats

Mais j'ai un problème que je n'arrive pas encore à cerner, et désolé si j'arrive pas encore à maitriser ceci.
Sachant que
Quote
To send data back and forth over The Things Network you'll need to use bytes.
Technically, you can send 51 bytes. But, the more bytes you'll send, the more airtime the package will cost you and the sooner you'll hit your maximum allotted time. So, don't ask yourself how many you can possibly send but rather ask how few could do the job.
je dois utiliser des bytes pour l'envoi des donnée
Quote
Comme te l'a déjà expliqué J-M-L, byte, char et uint8_t sont la même chose ce sont des octets. C'est la manière de les interpréter qui change.
D'accord.Mais que veux-tu dire par
Quote
C'est la manière de les interpréter qui change.
Je crois que ca, je n'ai encore pas compris  :(  :(

Code: [Select]
Tu peux faire la conversion en chaîne de caractères au moment de l'envoi ce qui est beaucoup plus économique en matière de gestion de la mémoire.
Mais oui. C'est un peu ce que j'avais fait ici

Je pense que mon problème est surtout comment interpreter mes valeurs des capteurs et la conversion des types de variable

Quote
Vue le nombre de capteur et le contenu des mesures, les informations à envoyer consommeront toujours plus de 64 octets. Il suffit tout simplement de compter les octets que tu empiles dans mydata et de déclencher l'émission des données lorsque le compte arrive à 64 et de reprendre le remplissage du tampon après que l'envoi est terminé.
Oui en effet  :) Je sais qu'il y a moyen d'envoyer par séquence. Je vaus regarderceci après.

Dans tous les cas, je dois faire l'empilement des valeurs, la conersion des types et l'envoi, proprement :o)

Si je suis bien vos suggestions propositions et exemple, je vais
  • Revenir sur ce que j'avais commencer hier, modifier mes fonctions pour qu'elles me retorunent le valeurs de capteurs en float. Il va falloir que je trouve comment convertir des double en float, et surtout limiter les valeurs à deux décimal après la virgule
  • Péparer la chaine* à envoyer qui sera sur cette forme {3.75,24.00,345.66,424.50,,,,4.6,,,} en gardant toujours le même ordre
  • Traiter cette chaine pour que l'envoie se fasse en bits et vérifier qu'elle ne dépasse pas 64 (et encapsuler le reste dans mydata2)


* Le problème est que ceci doit etre un char truc[22], non? On peut pas avoir plusieurs virgules dans une valeurs! Si je veux ne pas utiliser des char comme tu les dis ici
Quote
Ce qui fait 11 x 11 x 42 = 5082 octets
D'où la question, pourquoi stocker les résultats des mesures sous forme d'une chaîne de caractères au lieu d'un long ou d'un float?
On arriverait alors à une taille de 11 x 11 x 10 = 1210 octets
Tu peux faire la conversion en chaîne de caractères au moment de l'envoi ce qui est beaucoup plus économique en matière de gestion de la mémoire.
Il faudrait mieux suivre l'exemple de J-M-L ou il encapsule les valeurs dans la variable mydata dans la boucle.

Donc je me retrouve bloqué toujours ici (voir les *** dans le code ci-dessous).

Je suis au travail, et je peux pas tester ceci maintenant, mais je pensais donc faire un truc comme ceci. En espérant que je suis bien vos commentaires



Code: [Select]

uint8_t * ptr = mydata;

    for (byte i = 0; i < nbMaxCapteurs; i++) {

      if (mesCapteur[i].actif) { // si le capteur n'est pas actif on n'imprime pas

        // PRINT LES MESURES MESUREES
        sprint(mesCapteur[i].nomDuCapteur, 2);
        sprint(F(":"), 2);
        sprint(mesMesures[i][mesCapteur[i].idDuCapteur].valeur, 2);
        if (i < nbCapteurActif + 1) sprint(F(","), 2);


        // --------------------------------------------------------
        // EMPILE LES VALERUS MESUREE DANS mydata POUR LES ENVOYER A TTN

        //Je ne veux plus envoyer le nom du capteur
        //*ptr = mesCapteur[i].nomDuCapteur;
        //ptr += sizeof(char);

        //float test = 234.56;

       // *** En partant du principe que mesMesures[i][mesCapteur[i].idDuCapteur].valeur n'est plus une chaine de caractere mais un float. Est-ce que ceci va fonctionner pour avoir des bytes
       ((uint16_t *) ptr) = mesMesures[i][mesCapteur[i].idDuCapteur].valeur;
       // * ((uint16_t *) ptr) = test;
         ptr += sizeof(uint16_t); // deplace le capteur

        if (i < nbCapteurActif+1)
        {
          *ptr = '2C'; // virgule
          ptr += sizeof(char);
        }
      }
      else
      {
        *ptr = '2C'; // virgulepour les capteurs inactifs
        ptr += sizeof(char);
      }
    }
    *ptr = '00'; // Je ferme avec un \0
    ptr += sizeof(char);

printData();


printData() devrait m'afficher
Quote
33 2e 37 35 2c 32 34 2e 30 30 2c 33 34 35 2e 36 36 2c 34 32 34 2e 35 30 2c 2c 2c 2c 34 2e 36 2c 2c 2c
Si l'empilation des valeurs des capteurs est
3.75,24.00,345.66,424.50,,,,4.6,,,

J'aimerais beaucoup faire ceci proprement, après je regarderai comment spliter ceci si ca dépasse la limite de mydata. Ce soir je modifie mes fonctions pour qu'elle me retorune des float...

Milles mercis pour vos lumières et votre suivi  :)  :)  :)  :)


Est- ce que ca vous semble bien/correct ou je suis encore à côté de la plaque  :)  :)


Il ne suffit pas de tout savoir, la persévérance, c'est déjà presque tout!
You can not know everything, perseverance, it is almost everything!

J-M-L

Si vous envoyez en binaire et que vous connaissez le format du payload, pas besoin de virgule... ça aide que si vous envoyez en ascii car un double n'est pas représenté en nombre constant d'octes sous forme de caractères ascii (10 en a 2, 10.234 en a 6) mais ils seront tous représentés sous forme de 4 octets

En programmation si vous faites

double X = 21.1234;

Vous avez alloué 4 octets en mémoire (sous norme IEEE) qui est une représentation binaire de votre nombre. Donc si vous prenez les 4 octets en mémoire (ce que fais mon code plus haut) c'est ce dont vous avez besoin

Si vous voulez vous simplifier encore plus la vie, vu que vos capteurs actifs semble être définis à la complication avec vos #define, vous pourriez aussi avoir des #ifdef dans la structure et donc avoir une structure adaptéé au besoin ce qui fait que le payload deviendrait immédiatement votre tableau de mesures
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

pierrot10

Bonjour,

Merci pour votre retour.
Je ne m'en sors plus >:( . Je nage toujours au même point.
J'ose vous demander encore un petit moment?

J'espère n'être pas parti du mauvais côté

Je viens de modifier toutes mes fonctions qui me retorunent les valuers de mes capteurs.

Je récupère maintenant mes valuers en float (pas en double, mais s'il le faut, je corrige.

(J'ai activé 5 capteurs)
La boucle for
Code: [Select]


    sprintln(F("\nValeurs des capteurs actifs"), 2);
    sprintln(F("---------------------------------------"), 2);
    sprint(F("Nombre de capteurs: "), 2);
    sprintln(nbMaxCapteurs, 2);
    sprint(F("Nombre de capteurs actifs: "), 2);
    sprintln(nbCapteurActif, 2);

    sprintln(F("Valeurs:"), 2);

    // Clean char_buffer

    // Loop la strcture des capteurs
    //sprint(F("["),2);
    for (byte i = 0; i < nbMaxCapteurs; i++) {
      if (mesCapteur[i].actif) { // si le capteur n'est pas actif on n'imprime pas

        // PRINT LES MESURES MESUREES
        sprint(mesCapteur[i].nomDuCapteur, 0);
        sprint(F(":"), 0);
        sprintln(mesMesures[i][mesCapteur[i].idDuCapteur].valeur, 0);
        //if (i < nbCapteurActif) sprint(F("\n"), 0);
      }
      else
      {
        sprint(mesCapteur[i].nomDuCapteur, 0);
        sprintln(F(":"), 0);
        //if (i < nbCapteurActif) sprint(F("\n"), 0);
      }
     }

m'affiche ceci
Quote
Valeurs des capteurs actifs
---------------------------------------
Nombre de capteurs: 11
Nombre de capteurs actifs: 5
Valeurs:
a:4.32
b:24.08
c:971.73
d:424.00
e:25.00
f:
g:
h:
j:
k:
l:

Si on oublie les lettres et les :

J'essayyyyeee  :)  d'empiler dans mon uint8_t mydata en essayant vos echemples (masi je dois manquer quelque chose

Code: [Select]

sprintln(F("\nEmpilatios des valeurs capteurs"), 2);
     sprintln(F("---------------------------------------"), 2);

     memset(mydata, 0xFF, tailleMax);
     uint8_t * ptr = mydata;
    
     for (byte i = 0; i < nbMaxCapteurs; i++) {
      
      if (mesCapteur[i].actif) { // si le capteur n'est pas actif on n'imprime pas
        // --------------------------------------------------------
        // EMPILE LES VALERUS MESUREE DANS mydata POUR LES ENVOYER A TTN
  
        //Je ne veux plus envoyer le nom du capteur
        //*ptr = mesCapteur[i].nomDuCapteur;
        //ptr += sizeof(char);

        *ptr = mesMesures[i][mesCapteur[i].idDuCapteur].valeur; // C EST UN FLOAT
        ptr += 15; // COMMENT CALCULER LE DEPLACEMENT DU POINTEUR EN FONCTION DE LA DERNIER VALEUR float
      

        if (i < nbCapteurActif + 1)
        {
          *ptr = 0x2C; // virgule
          ptr += sizeof(char);
          
        }
      }
      else
      {
        *ptr = 0x2C; // virgulepour les capteurs inactifs
        ptr += sizeof(char);
        
      }
    }
    
    *ptr = '00'; // Je ferme avec un \0
    ptr += sizeof(char);


    printData();

printData() m'affiche ceci
Quote
Empilatios des valeurs capteurs
---------------------------------------
mydata = { 04 FF FF FF FF FF FF FF FF FF FF FF FF FF FF 2C 18 FF FF FF FF FF FF FF FF FF FF FF FF FF FF 2C CB FF FF FF FF FF FF FF FF FF FF FF FF FF FF 2C A8 FF FF FF FF FF FF FF FF FF FF FF FF FF FF 2C }

Donc on voit que c'est totalement rappé...

Cette partie ne fonctionne vraiment pas
Code: [Select]

// [mesMesures[i][mesCapteur[i].idDuCapteur].valeur] est de type float
*ptr = mesMesures[i][mesCapteur[i].idDuCapteur].valeur;

(J'aimerais bien aussi supprimer ce qu'il y après les points (décimal))

Je me sens mal à l'aise car vous m'avez donner tellement d'exemple, mais je nage toujours....
Il ne suffit pas de tout savoir, la persévérance, c'est déjà presque tout!
You can not know everything, perseverance, it is almost everything!

J-M-L

Pourquoi ptr += 15; // deplace le capteur?

ça  explique le résultat 04 FF FF FF FF FF FF FF FF FF FF FF FF FF FF 2C 18 ...
Vous écrivez 15 octets plus loin

Voyez la mémoire comme une grande commode pleine de tiroirs. Il faut ranger dans les tiroirs successifs vos données mais un tiroir ne contient que 1 octet, donc si vous avez une donnée sur 4 octets il faut les mettre dans 4 tiroirs successifs
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

pierrot10

Quote
Pourquoi ptr += 15; // deplace le capteur?

ça  explique le résultat 04 FF FF FF FF FF FF FF FF FF FF FF FF FF FF 2C 18 ...
Vous écrivez 15 octets plus loin
Oui je suis tout à fait d'accord.
 mais au lieu de
Quote
04 FF FF FF FF...
on devrait voir

Quote
34 2e 33 32 FF FF FF FF FF FF FF FF FF FF FF 2C 18
car
Quote
34 2e 33 32
vaut 4.32 !!!

Alors pourquoi j'ai que 04???
Il ne suffit pas de tout savoir, la persévérance, c'est déjà presque tout!
You can not know everything, perseverance, it is almost everything!

Go Up