//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 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
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
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
// 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
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
![]()
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é.
Vous faites
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)
// 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
@J-M-L
Oui, excuse moi, j'avais mal corrigé
struct capteur
{
uint8_t idDuCapteur;
boolean actif;
const char * nomDuCapteur;
};
@fdufnews
Merci de te joindre ![]()
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..
//#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..
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
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
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
C'est la manière de les interpréter qui change.
Je crois que ca, je n'ai encore pas compris
![]()
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
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
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
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
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
![]()
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
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
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
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
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
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
// [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....
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
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
04 FF FF FF FF...
on devrait voir
34 2e 33 32 FF FF FF FF FF FF FF FF FF FF FF 2C 18
car
34 2e 33 32
vaut 4.32 !!!
Alors pourquoi j'ai que 04???
ptr est un pointeur typé et quand vous dites *ptr = ... vous n’écrivez que le nombre d’octest Dépendant de ce type car ça dépend du type de stockage pour la variable destination - et ici *ptr est de type 1 seul octet de mémoire (uint8_t)
Donc *ptr = 0xAABB; par exemple ne récupérerait que le BB à l’endroit du pointeur le compilateur comprend que vous ne voulez que l’octet de poids faible car il n’y a qu’une case dans la destination alors que
* ([color=red](uint16_t *)[/color] ptr) = 0xAABB;
va bien mettre BB au niveau du pointeur et AA dans l’octet suivant (little endian, on range en mémoire d’abord le poids faible)
C’est pour cela que dans mon exemple ci dessus quand j’écris 16 bits, je cast le pointeur en 16 bits (transformé temporairement pour cette ligne)
* ([color=red](uint16_t *)[/color] ptr) = [nobbc]allMesures[s][m].mesure;[/nobbc]
Parce que mesure est sur 2 octets dans mon exemple
Bien sûr il faut avancer ensuite le pointeur du bon nombre de case d’où ptr += sizeof(uint16_t);
De la même manière quand je veux mettre chrono dans le buffer je dis au compilateur par un cast (changement de type) que ptr pointe vers une zone 32 bits et ensuite j’avance de 4 cases le pointeur
Bonjour J-M-L.
J'aimerais savoir si vous pouviez encore me filer un coup de pouce. Je n'arrive pas à résoudre mon problème malgré tous les exemples.
En soit, ces exemples mon beaucoup aidé car ils font toujours partie de mon code.
Ceci je bloque toujours sur le même point.
J'ai surfé sur le net et sur le site de TTN et ils fournissent un exemple pour envoyer plusieurs variables.
Avec ceci j'ai réussi à faire ce que je veux SAUF que je n'arrive toujours pas à empiler des int dans un byte!!!!
GRRR. ![]()
Voic donc mon cas.
J'ai ces variables
byte payloadAltitude[] = {0x34};
byte payloadHumidity[] = {0x35};
byte payloadMoisture[] = {0x36};
byte payloadLuminosity[] = {0x37};
byte payloadUv[] = {0x38};
byte payloadLatitude[] = {0x39};
byte payloadLongitude[] = {0x31, 0x30};
byte payloadDate[] = {0x31, 0x31};
Puis ensuite je calcule la taille
int sizeofPayloadBattery = sizeof(payloadBattery);
int sizeofPayloadTemperature = sizeof(payloadTemperature);
int sizeofPayloadPression = sizeof(payloadPression);
int sizeofPayloadAltitude = sizeof(payloadAltitude);
int sizeofPayloadHumidity = sizeof(payloadHumidity);
int sizeofPayloadMoisture = sizeof(payloadMoisture);
int sizeofPayloadLuminosity = sizeof(payloadLuminosity);
int sizeofPayloadUv = sizeof(payloadUv);
int sizeofPayloadLatitude = sizeof(payloadLatitude);
int sizeofPayloadLongitude = sizeof(payloadLongitude);
int sizeofPayloadDate = sizeof(payloadDate)
int playloadSize = sizeofPayloadBattery + sizeofPayloadTemperature + sizeofPayloadPression + sizeofPayloadAltitude + sizeofPayloadHumidity + sizeofPayloadMoisture + sizeofPayloadLuminosity + sizeofPayloadUv + sizeofPayloadLatitude +sizeofPayloadLongitude + sizeofPayloadDate;
sprint(F("Payload size: "),1); sprintln(playloadSize,2);
byte payload[playloadSize];
et j'empile
memcpy(payload, payloadBattery, sizeofPayloadBattery);
memcpy(payload + sizeofPayloadBattery, payloadTemperature, sizeofPayloadTemperature);
memcpy(payload + sizeofPayloadBattery + sizeofPayloadTemperature, payloadPression, sizeofPayloadPression);
memcpy(payload + sizeofPayloadBattery + sizeofPayloadTemperature + sizeofPayloadPression, payloadAltitude, sizeofPayloadAltitude);
memcpy(payload + sizeofPayloadBattery + sizeofPayloadTemperature + sizeofPayloadPression + sizeofPayloadAltitude, payloadHumidity, sizeofPayloadHumidity);
memcpy(payload + sizeofPayloadBattery + sizeofPayloadTemperature + sizeofPayloadPression + sizeofPayloadAltitude + sizeofPayloadHumidity, payloadMoisture, sizeofPayloadMoisture);
memcpy(payload + sizeofPayloadBattery + sizeofPayloadTemperature + sizeofPayloadPression + sizeofPayloadAltitude + sizeofPayloadHumidity + sizeofPayloadMoisture, payloadLuminosity, sizeofPayloadLuminosity);
memcpy(payload + sizeofPayloadBattery + sizeofPayloadTemperature + sizeofPayloadPression + sizeofPayloadAltitude + sizeofPayloadHumidity + sizeofPayloadMoisture + sizeofPayloadLuminosity, payloadUv, sizeofPayloadUv);
memcpy(payload + sizeofPayloadBattery + sizeofPayloadTemperature + sizeofPayloadPression + sizeofPayloadAltitude + sizeofPayloadHumidity + sizeofPayloadMoisture + sizeofPayloadLuminosity + sizeofPayloadUv, payloadLatitude, sizeofPayloadLatitude);
memcpy(payload + sizeofPayloadBattery + sizeofPayloadTemperature + sizeofPayloadPression + sizeofPayloadAltitude + sizeofPayloadHumidity + sizeofPayloadMoisture + sizeofPayloadLuminosity + sizeofPayloadUv + sizeofPayloadLatitude, payloadLongitude, sizeofPayloadLongitude);
memcpy(payload + sizeofPayloadBattery + sizeofPayloadTemperature + sizeofPayloadPression + sizeofPayloadAltitude + sizeofPayloadHumidity + sizeofPayloadMoisture + sizeofPayloadLuminosity + sizeofPayloadUv + sizeofPayloadLatitude + sizeofPayloadLongitude, payloadDate, sizeofPayloadDate);
//if((sizeofPayloadBattery + sizeofPayloadTemperature + sizeofPayloadPression + sizeofPayloadAltitude + sizeofPayloadHumidity + sizeofPayloadMoisture + sizeofPayloadLuminosity + sizeofPayloadUv + sizeofPayloadLatitude + sizeofPayloadLongitude + sizeofPayloadDate) > 51) Serial.println(F("playload is over (10)"));
// PRINT
Serial.print("mydata = { ");
for (byte i = 0; i < playloadSize; i++) {
//Serial.print("0x");
if (payload[i] <= 0xF) Serial.print("-");
Serial.print(payload[i], HEX);
Serial.print(" ");
}
Serial.println("}");
Ca marche!!!!!
Sauf que mon problème est encore ici
byte payloadBattery[] = {0x34};
byte payloadTemperature[] = {0x35};
byte payloadPression[] = {0x36};
byte payloadAltitude[] = {0x37};
Et je précise.
sij'ai
int ibatt = 345
int itemp = -3
int ipres = 1
int ialti = 123456 // je fait expres de mettre un gros chiffre
Je n'arrive pas à les passer dans
byte payloadBattery[] = {0x33 0x34 0x35};
byte payloadTemperature[] = {0x2d 0x33};
byte payloadPression[] = {0x31};
byte payloadAlttiude[] = {0x31 0x32 0x33 0x34 0x35 0x36 0x20};
J'ai essayé plein de truc comme paremple
byte payloadBattery[2];
playloadBattery[0] = ibatt / 256;
playloadBattery[1] = ibatt % 256;
byte payloadTemperature[2];
playloadTemperature[0] = itemp / 256;
playloadTemperature[1] = itemp % 256;
byte payloadPression[2];
playloadPression[0] = ipres / 256;
playloadPression[1] = ipres % 256;
byte payloadAltitude[2];
playloadAltitude[0] = ialti / 256;
playloadAltitude[1] = ialti % 256;
Ci-dessus, affichera des valerus fausses sous // PRINT
J'ai encore essayé
byte tBattery[2];
tBattery[0] = ibatt / 256;
tBattery[1] = ibatt % 256;
byte tTemperature[2];
tTemperature[0] = itemp / 256;
tTemperature[1] = itemp % 256;
byte tPression[2];
tPression[0] = ipress / 256;
tPression[1] = ipres % 256;
byte tAltitude[2];
tAltitude[0] = ialti / 256;
tAltitude[1] = ialti % 256;
byte payloadBattery[] = tBattery;
byte payloadTemperature[] = tTemperature;
byte payloadPression[] = tPression;
byte payloadAlttiude[] = tAltitude;
Ceci m'affichera une erreur dans mon terminal. Je ne sais plus ce que j'ai essayé...
Comment travailler ibatt (et les nombre négatif ou grand nombre)
ibatt = 345
pour arriver à ce même résultat
byte payloadTemperature[] ={0x33, 0x34, 0x35};
Il est encore important que je puisse sauver dans notre comme
1 (1 digit)
345 (3 digit)
-4 (négative)
123456 (6 digit pour les longitude et latitude)
Des que j'arrive à comprendre et à la faire, je suis débloqué :o :o
Milles mercis
vous comprenez que quand vous écrivezbyte payloadBattery[] = {0x34};vous déclarez un tableau de 1 byte de long (car vous ne passez qu'une valeur) ? donc la variable payloadBattery est de type pointeur en mémoire sur un tableau de byte.
donc votre exemple avec
byte payloadAltitude[] = {0x34};
byte payloadHumidity[] = {0x35};
byte payloadMoisture[] = {0x36};
// ... etc
est tout à fait fonctionnel car la fonction memcpy() a besoin d'un pointeur en mémoire pour travailler.
A ce sujet, pour simplifier la lecture et l'écriture au lieu de faire
memcpy(payload, payloadBattery, sizeofPayloadBattery);
memcpy(payload + sizeofPayloadBattery, payloadTemperature, sizeofPayloadTemperature);
memcpy(payload + sizeofPayloadBattery + sizeofPayloadTemperature, payloadPression, sizeofPayloadPression);
qui devient vite pénible à lire, il est plus simple de déclarer un pointeur et de le bouger.
byte * ptr = payload; // on initialise ptr au début du payload
memcpy(ptr, payloadBattery, sizeofPayloadBattery);
ptr+= sizeofPayloadBattery; // on décale le pointeur
memcpy(ptr, payloadTemperature, sizeofPayloadTemperature);
ptr+= sizeofPayloadTemperature; // on décale le pointeur
memcpy(ptr, payloadPression, sizeofPayloadPression);
ptr+= sizeofPayloadPression; // on décale le pointeur
// etc
Pour votre question maintenant concernantint ibatt = 345;
il faut comprendre ici que ibatt est une variable de type entier. Comme ce n'est pas un tableau, lorsque dans du code vous faites référence à ibatt, vous manipulez le contenu de la mémoire et pas le pointeur sur la mémoire associée. En C le pointeur (l'adresse de la case mémoire du début du stockage) se représente par &ibatt. à cet endroit en mémoire va se trouver le codage sur plusieurs octets de votre nombre. Le nombre d'octets de codage dépend du type de la variable. Un int sur arduino standard c'est 2 octets, un float ou un long c'est 4 par exemple. Le nombre d'octets affectés au stockage d'un entier va influencer les valeurs représentables: sur un Arduino typique (genre UNO), un int est sur 2 octets donc 16 bits. un int est signé donc il y a un bit qui va être utilisé pour dire si le nombre est positif ou négatif et il reste 15 bits pour représenter la valeur, ce qui permet par convention (puisqu'on est en base 2) d'avoir une valeur minimum à -215 = -32,768 et maximale à +215-1 = 32,767.
Si vos valeurs sont toutes positives vous pouvez utiliser un unsigned int qui va alors vous donner les 16 bits pour représenter vos nombres entre 0 et 216-1=65535. On voit bien que la représentation sous forme de 1 et de 0 de votre nombre n'est qu'affaire de convention (qui suit une norme internationale), cette convention vous la définissez avec le type de la variable et le compilateur se charge du reste.
Pour ibatt qui est un int donc sur 2 octets, vous aurez à partir de l'adresse mémoire &ibatt la représentation de 345(décimal) qui est en héxadécimal 0x159(hex).
Le compilateur sur Arduino étant little endian et la mémoire étant organisée en octets (une adresse pointe vers 8 bits de mémoire) il va mettre dans la mémoire d'abord l'octet de poids faible puis celui de poids fort et donc on aura à partir de l'adresse mémoire &ibatt 0x59 puis dans l'octet qui suit en mémoire la valeur 0x01.
Mais vous me dites vouloir avoir dans le payload 0x33 0x34 0x35 ce qui correspond à la représentation en ASCII de votre nombre en base 10 (le caractère '3' est effectivement codé en 0x33, le caractère '4' est 0x34 et le caractère '5' est 0x35).
Cette approche comme on vous l'a déjà mentionné n'est pas super car l'entier 15228 par exemple va nécessiter 5 octets pour être représenté alors que l'entier 3 ne va en nécessité qu'un seul. Pour calculer la taille de votre payload a priori, c'est pénible... et côté décodage ça va être un peu galère aussi, il faudra marquer la fin de la chaîne de caractères puisque sa longueur n'est pas fixe. et donc rajouter un octet (généralement on met '\0' dans ce caractère). Il est bcp plus efficace d'envoyer la représentation binaire, les fameux 2 octets à partir de l'adresse mémoire &ibatt 0x59 puis 0x01.
en continuant l'approche mentionnée ci dessus cela se ferait par
int ibatt = 345;
byte * ptr = payload; // on initialise ptr au début du payload
memcpy(ptr, (byte *) (& ibatt), sizeof(ibatt));
ptr+= sizeof(ibatt); // on décale le pointeur du bon nombre d'octets
Cependant si vous tenez à représenterez en mémoire la chaîne de caractères ASCII, il faut d'abord la convertir.
Pour cela il y a des fonctions dans les librairies standard (stdlib.h ou string.h par exemple) et celle qui permet de convertir un entier (type int) en chaîne ASCII est itoa()
Pour convertir un entier stocké dans
valeur
, et mettre la chaîne correspondante à la représentation ASCII dans une certaine
base
à l'adresse pointée par
adresseMémoire
, l'appel de fonction est le suivant
itoa([color=red]valeur[/color], [color=blue]adresseMémoire[/color], [color=purple]base[/color] );
ça rajoute tout seul aussi un caractère nul de fin de chaîne '\0' à la fin de l'encodage.
Donc puisque vous voulez représenter en base 10 et stocker ça dans le payload (en supposant qu'il y ait toute la place nécessaire dans le payload)
int ibatt = 345;
byte * ptr = payload; // on initialise ptr au début du payload
itoa ( ibatt, (char *) ptr, 10 ); // on écrit à partir de ptr la représentation ASCII en base 10 de la valeur de ibatt
ptr+= strlen(ptr) + 1; // on décale le pointeur du bon nombre d'octets, besoin du +1 pour conserver le '\0'
La fonction standard [url=http://www.cplusplus.com/reference/cstring/strlen/]strlen()[/url] donne le nombre de caractères utilisés. cette fonction ne compte pas le caractère nul de fin et donc je fais +1 pour déplacer le pointeur vers la prochaine case vide du payload.
Si on met tout cela dans un exemple de code:
uint8_t payload[10]; // uint8_t c'est comme byte mais plus standard
const byte nbBytesDansPayload = sizeof(payload);
void afficherPayload()
{
for (byte i = 0; i < nbBytesDansPayload; i++) {
Serial.print(F("payload["));
Serial.print(i);
Serial.print(F("]=0x"));
Serial.print(payload[i], HEX);
Serial.print(F("\tsoit le caractère ASCII '"));
Serial.print((char) payload[i]);
Serial.println(F("'"));
}
}
void setup() {
int ibatt = 345; // 0x159 en hexa
Serial.begin(115200);
// on met tout le buffer à '#'histoire de voir quelque chose lors de l'impression
memset(payload, '#', nbBytesDansPayload);
// on copie la représentation binaire (2 octets sur UNO)
uint8_t * ptr = payload; // on initialise ptr au début du payload
memcpy(ptr, (uint8_t *) (& ibatt), sizeof(ibatt));
ptr += sizeof(ibatt); // on décale le pointeur du bon nombre d'octets
// on copie la représentation base 10 en ASCII
itoa(ibatt, (char *) ptr, 10); // on écrit à partir de ptr la représentation ASCII en base 10 de la valeur de ibatt
ptr += strlen((char *) ptr) + 1; // on décale le pointeur du bon nombre d'octets, besoin du +1 pour conserver le '\0'
afficherPayload();
}
void loop() {}
si vous exécutez, vous verrez dans la console
[nobbc]
payload[0]=0x59 soit le caractère ASCII 'Y'
payload[1]=0x1 soit le caractère ASCII ''
payload[2]=0x33 soit le caractère ASCII '3'
payload[3]=0x34 soit le caractère ASCII '4'
payload[4]=0x35 soit le caractère ASCII '5'
payload[5]=0x0 soit le caractère ASCII ''
payload[6]=0x23 soit le caractère ASCII '#'
payload[7]=0x23 soit le caractère ASCII '#'
payload[8]=0x23 soit le caractère ASCII '#'
payload[9]=0x23 soit le caractère ASCII '#'
[/nobbc]
on retrouve bien en cases 0 et 1 la représentation de 0x159 (avec le 0x59 d'abord) puis la représentation ASCII correcte de 345 en base 10, suivi du zéro de fin de chaîne et ensuite rien n'a été touché, on trouve tous les '#' que j'avais mis au départ.
Pour des nombre négatifs ou des grands nombres c'est la même chose, si vous voulez de l'ASCII il faut prendre la fonction de conversion ASCII adaptée... mais ma recommendation c'est de ne pas envoyer l'ASCII et d'envoyer la représentation mémoire et faire ensuite le traitement côté serveur....
ça aide ?
Bonjour J-M-L
Je vous réponds juste pour vous dire que j'ai reçu votre super mega réponse. Vous être extraordinaire.
Je ne pourrai pas me pencher la dessus ce week-end, car je suis avec ma fille, mais je lirai ligne par ligne votre réponse lundi. Milles mercis et tout bon week-end à vous
Bonjour J-M-L,
Je crois que j'y suis arrivéééééeeeee!!!!!!!!!!!!!!!!!
Je crois, je crois, je crois.
Je me suis basé sur votre dernière réponse sans avoir de résultat concluant, mais très proche.
Avant de continuer:
A ce sujet, pour simplifier la lecture et l'écriture au lieu de faire
Oui en effet, je l'ai corrigé de la sorte. C'est en effet bien bien mieux ![]()
Ce code fonctionne exactement comme je le veux, sauf que je n'arrive toujours pas à ce que
payloadBattery prenne la valeur de ibatt, comme ci-dessous
byte payloadBattery[] = {0x33, 0x34, 0x35}; //345
byte payloadTemperature[] = {0x2D, 0x31, 0x30}; // -10
byte payloadPression[] = {0x31}; //1
byte payloadAltitude[] = {0x34, 0x32, 0x34}; // 424
byte payloadHumidity[] = {0x35}; // 5
byte payloadMoisture[] = {0x36}; // 6
byte payloadLuminosity[] = {0x37}; // 7
byte payloadUv[] = {0x38}; // 8
byte payloadLatitude[] = {0x39}; // 9
byte payloadLongitude[] = {0x31, 0x30}; // 10
byte payloadDate[] = {0x31, 0x31}; // 11
int sizeofPayloadBattery = sizeof(payloadBattery);
int sizeofPayloadTemperature = sizeof(payloadTemperature);
int sizeofPayloadPression = sizeof(payloadPression);
int sizeofPayloadAltitude = sizeof(payloadAltitude);
int sizeofPayloadHumidity = sizeof(payloadHumidity);
int sizeofPayloadMoisture = sizeof(payloadMoisture);
int sizeofPayloadLuminosity = sizeof(payloadLuminosity);
int sizeofPayloadUv = sizeof(payloadUv);
int sizeofPayloadLatitude = sizeof(payloadLatitude);
int sizeofPayloadLongitude = sizeof(payloadLongitude);
int sizeofPayloadDate = sizeof(payloadDate);
//int playloadSize = sizeofPayloadBattery + sizeofPayloadTemperature + sizeofPayloadPression + sizeofPayloadAltitude + sizeofPayloadHumidity + sizeofPayloadMoisture + sizeofPayloadLuminosity + sizeofPayloadUv + sizeofPayloadLatitude +sizeofPayloadLongitude + sizeofPayloadDate;
int playloadSize = 64;
sprint(F("Payload size: "),1); sprintln(playloadSize,2);
uint8_t payload[playloadSize];
// on met tout le buffer à '#'histoire de voir quelque chose lors de l'impression
memset(payload, '#', playloadSize);
uint8_t * ptr = payload;
//Arranegment proposée par J-M-L
memcpy(ptr, payloadBattery, sizeofPayloadBattery);
ptr+= sizeofPayloadBattery+1; // On deplace le pointeur. J'ajoute volontaire un espace suppl. pour ieux lire le réultat
memcpy(ptr, payloadTemperature, sizeofPayloadTemperature);
ptr+= sizeofPayloadTemperature+1; // On deplace le pointeur
memcpy(ptr, payloadPression, sizeofPayloadPression);
ptr+= sizeofPayloadPression+1; // On deplace le pointeur
memcpy(ptr, payloadAltitude, sizeofPayloadAltitude);
ptr+= sizeofPayloadAltitude+1; // On deplace le pointeur
memcpy(ptr, payloadHumidity, sizeofPayloadHumidity);
ptr+= sizeofPayloadHumidity+1; // On deplace le pointeur
memcpy(ptr, payloadMoisture, sizeofPayloadMoisture);
ptr+= sizeofPayloadMoisture+1; // On deplace le pointeur
memcpy(ptr, payloadLuminosity, sizeofPayloadLuminosity);
ptr+= sizeofPayloadLuminosity+1; // On deplace le pointeur
memcpy(ptr, payloadUv, sizeofPayloadUv);
ptr+= sizeofPayloadUv+1; // On deplace le pointeur
memcpy(ptr, payloadLatitude, sizeofPayloadLatitude);
ptr+= sizeofPayloadLatitude+1; // On deplace le pointeur
memcpy(ptr, payloadLongitude, sizeofPayloadLongitude);
ptr+= sizeofPayloadLongitude+1; // On deplace le pointeur
memcpy(ptr, payloadDate, sizeofPayloadDate);
Ce qui donne
33 34 35 23 2D 31 30 23 31 23 34 32 34 23 35 23 36 23 37 23 38 39 23 31 30 23 31 31 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23
ou
345#-10#1#424#5#6#7#89#10#11####################################
C'est exactement le résultat que je veux avoir!!!( Avec des # des, c'est egal..)
Après avoir rendu cette partie plus lisible, je me suis penché sur vos propositions, sans pour autant réussir.
Finalement, je me suis basé sur votre tout dernier code
Cette partie m'affichait des caracteres ilisible
// on copie la représentation binaire (2 octets sur UNO)
uint8_t * ptr = payload; // on initialise ptr au début du payload
memcpy(ptr, (uint8_t *) (& ibatt), sizeof(ibatt));
ptr += sizeof(ibatt); // on décale le pointeur du bon nombre d'octets
Finalement, je l'ai supprimé pour gardé que ceci et là il semble que ca s'affiche bien
Si
ibatt=345
itemp=-10
ipres=1
ialti=424
ihumi=-34654// Je mets volontairement un chiffre à 6 difigt
imois=6
ilumi=7
iuv=8
ilati=4686789 // 5 deimal
lati=412436 //5decimal
idate=170925
itime=1747
Ceci
int payloadSize = 64;
uint8_t payload[payloadSize];
memset(payload,'#',payloadSize);
uint8_t * ptr = payload;
ibatt = 345;
itemp = -10;
ipres = 1;
ialti = 424;
ihumi = -34654; // Je mets volontairement un chiffre à 6 difigt
imois = 6;
ilumi = 7;
iuv = 8;
ilati = 4686789; // 5 deimal
ilong = 412436; //5decimal
idate = 170925;
itime = 1731;
// on copie la représentation binaire (2 octets sur UNO)
// memcpy(ptr, (uint8_t *) (& ibatt), sizeof(ibatt));
// ptr += sizeof(ibatt); // on décale le pointeur du bon nombre d'octets
// on copie la représentation base 10 en ASCII
itoa(ibatt, (char *) ptr, 10); // on écrit à partir de ptr la représentation ASCII en base 10 de la valeur de ibatt
ptr += strlen((char *) ptr) + 1; // on décale le pointeur du bon nombre d'octets, besoin du +1 pour conserver le '\0'
// memcpy(ptr, (uint8_t *) (& itemp), sizeof(itemp));
// ptr += sizeof(itemp);
itoa(itemp, (char *) ptr, 10);
ptr += strlen((char *) ptr) + 1;
// memcpy(ptr, (uint8_t *) (& ipres), sizeof(ipres));
// ptr += sizeof(ipres);
itoa(ipres, (char *) ptr, 10);
ptr += strlen((char *) ptr) + 1;
// memcpy(ptr, (uint8_t *) (& ialti), sizeof(ialti));
// ptr += sizeof(ialti);
itoa(ialti, (char *) ptr, 10);
ptr += strlen((char *) ptr) + 1;
itoa(ihumi, (char *) ptr, 10);
ptr += strlen((char *) ptr) + 1;
itoa(imois, (char *) ptr, 10);
ptr += strlen((char *) ptr) + 1;
itoa(ilumi, (char *) ptr, 10);
ptr += strlen((char *) ptr) + 1;
itoa(iuv, (char *) ptr, 10);
ptr += strlen((char *) ptr) + 1;
itoa(ilati, (char *) ptr, 10);
ptr += strlen((char *) ptr) + 1;
itoa(ilong, (char *) ptr, 10);
ptr += strlen((char *) ptr) + 1;
itoa(idate, (char *) ptr, 10);
ptr += strlen((char *) ptr) + 1;
itoa(itime, (char *) ptr, 10);
ptr += strlen((char *) ptr) + 1;
for (byte i = 0; i < 64; i++) {
Serial.print(F("payload3["));
Serial.print(i);
Serial.print(F("]=0x"));
Serial.print(payload[i], HEX);
Serial.print(F("\tsoit le caractere ASCII '"));
Serial.print((char) payload[i]);
Serial.println(F("'"));
}
m'affiche bien
payload3[0]=0x33 soit le caractere ASCII '3'
payload3[1]=0x34 soit le caractere ASCII '4'
payload3[2]=0x35 soit le caractere ASCII '5'
payload3[3]=0x0 soit le caractere ASCII ''
payload3[4]=0x2D soit le caractere ASCII '-'
payload3[5]=0x31 soit le caractere ASCII '1'
payload3[6]=0x30 soit le caractere ASCII '0'
payload3[7]=0x0 soit le caractere ASCII ''
payload3[8]=0x31 soit le caractere ASCII '1'
payload3[9]=0x0 soit le caractere ASCII ''
payload3[10]=0x34 soit le caractere ASCII '4'
payload3[11]=0x32 soit le caractere ASCII '2'
payload3[12]=0x34 soit le caractere ASCII '4'
payload3[13]=0x0 soit le caractere ASCII ''
payload3[14]=0x2D soit le caractere ASCII '-'
payload3[15]=0x33 soit le caractere ASCII '3'
payload3[16]=0x34 soit le caractere ASCII '4'
payload3[17]=0x36 soit le caractere ASCII '6'
payload3[18]=0x35 soit le caractere ASCII '5'
payload3[19]=0x34 soit le caractere ASCII '4
payload3[20]=0x0 soit le caractere ASCII ''
payload3[21]=0x36 soit le caractere ASCII '6'
payload3[22]=0x0 soit le caractere ASCII ''
payload3[23]=0x37 soit le caractere ASCII '7'
payload3[24]=0x0 soit le caractere ASCII ''
payload3[25]=0x38 soit le caractere ASCII '8'
payload3[26]=0x0 soit le caractere ASCII ''
payload3[27]=0x34 soit le caractere ASCII '4'
payload3[28]=0x36 soit le caractere ASCII '6'
payload3[29]=0x38 soit le caractere ASCII '8'
payload3[30]=0x36 soit le caractere ASCII '6'
payload3[31]=0x37 soit le caractere ASCII '7'
payload3[32]=0x38 soit le caractere ASCII '8'
payload3[33]=0x39 soit le caractere ASCII '9'
payload3[34]=0x0 soit le caractere ASCII ''
payload3[35]=0x34 soit le caractere ASCII '4'
payload3[36]=0x31 soit le caractere ASCII '1'
payload3[37]=0x32 soit le caractere ASCII '2'
payload3[38]=0x34 soit le caractere ASCII '4'
payload3[39]=0x33 soit le caractere ASCII '3'
payload3[40]=0x36 soit le caractere ASCII '6'
payload3[41]=0x0 soit le caractere ASCII ''
payload3[42]=0x31 soit le caractere ASCII '1'
payload3[43]=0x37 soit le caractere ASCII '7'
payload3[44]=0x30 soit le caractere ASCII '0'
payload3[45]=0x39 soit le caractere ASCII '9'
payload3[46]=0x32 soit le caractere ASCII '2'
payload3[47]=0x35 soit le caractere ASCII '5'
payload3[48]=0x0 soit le caractere ASCII ''
payload3[49]=0x31 soit le caractere ASCII '1'
payload3[50]=0x37 soit le caractere ASCII '7'
payload3[51]=0x33 soit le caractere ASCII '3'
payload3[52]=0x31 soit le caractere ASCII '1'
payload3[51]=0x0 soit le caractere ASCII ''
payload3[54]=0x23 soit le caractere ASCII '#'
payload3[55]=0x23 soit le caractere ASCII '#'
payload3[56]=0x23 soit le caractere ASCII '#'
payload3[57]=0x23 soit le caractere ASCII '#'
payload3[58]=0x23 soit le caractere ASCII '#'
payload3[59]=0x23 soit le caractere ASCII '#'
payload3[60]=0x23 soit le caractere ASCII '#'
payload3[61]=0x23 soit le caractere ASCII '#'
payload3[62]=0x23 soit le caractere ASCII '#'
payload3[63]=0x23 soit le caractere ASCII '#'
Et je vois même qu'il me reste un peu de place ![]()
C'est génial. Il me reste plus qu'a voir si mes données seront bien envoyées. J'essayerai aussi arrivé à la maison.
En attendant, je vais simplifer l'affichage d ela sorte
payload3 {33 34 35 0 2D 31 30 0 31 0 34 32 34 0 2D 33 34 36 35 34 0 36 0 37 0 38 0 34 36 38 36 37 38 39 0 34 31 32 34 33 36 0 31 37 30 39 32 35 0 31 37 33 31 0 23 23 23 23 23 23 23 23 23 23 }
et que je remplace les 0 par 2C (la virgule)
Je me réjouis d'essayé tut ceci.
Qu'en pensez-vous?
je vous tiens au courant et tout cas, milles milles milles mercis pour tout ce que vous avez fait, pour tout vos exemples, votre temps. C'est vraiment super sympa et je vous en suis très reconnaissant.
Vous êtes quel côté géographique?
Bonjour J-M-L
Je voulais encore vraiment vous remercier pour toute l'énergie et la patience que vous avez pris pour moi.
Ca fonctionne!!!!!!
J'ai envoyé des données que je retrouve sur le serveur. Je suis super content et sans vous j'aurais jamais réussi.
Aussi, l'air de rien, j'ai beaucoup, beaucoup appris surtout e ce qui concerne le pointer. Je ne sais pas ou vous etes localisé, mais c'est avec grand plaisir que je vous offrirais un bon verre.
Cette discussion, elle est vraiment été énorme et je vais prendre un moment pour mettre tout mon code. Je vais avant faire un peu de nettoyage mais je le mets plus tard
Super boulot - vous avez tout compris !
(bon si c'était moi vous savez bien que je n'enverrai pas de l'ASCII puisque le serveur sera bcp plus puissant pour décoder vos octets directement mais pas grave)
Bonne continuation
Voilà, j'espère qu'il n'y aura rien à redire ![]()
(J'espère ne rien oublier)
//---------------------------------------------------------
// Sensor activation
//---------------------------------------------------------
#define SENSOR_BATTERY // Battery Voltage
//#define SENSOR_GPS // latitude, longitude, datetime
#define SENSOR_BMP180 // Barometer (temperature/pression/alt)
#define SENSOR_DTH22 // Humidity (Temrature)
//#define SENSOR_MOISTURE
#define SENSOR_TSL2561 // Luminoisty
//#define SENSOR_UV
//#define SENSOR_MEMORY // Free memory
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...
#ifdef SENSOR_BATTERY
bool battery_active = true;
#else
bool battery_active = false;
#endif
struct capteur
{
uint8_t idDuCapteur;
boolean actif;
const char * nomDuCapteur;
};
capteur mesCapteur[] = {
{capteur_battery_id, battery_active, "ba"},
{capteur_temperature_id, temperature_active, "te"},
{capteur_pression_id, pression_active, "pr"},
{capteur_alt_id, alt_active, "al"},
{capteur_humidity_id, humidity_active, "hu"},
{capteur_moisture_id, moisture_active, "mo"},
{capteur_luminosity_id, luminosity_active, "lu"},
{capteur_uv_id, uv_active, "uv"},
{capteur_latitude_id, latitude_active, "la"},
{capteur_longitude_id, longitude_active, "lo"},
{capteur_datetime_id, datetime_active, "da"},
};
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;
int valeur; // 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];
Je ne peux pas mettre tout mon code dans un post, je le split
(Suite)
J'ai maintenant une fonction do_send(). Elle est appelée tous les 120sec. A caque fois qu'elle est applée, les fonctions "capteurs" sont applés..
void do_send(osjob_t* j)
{
uint8_t payload[payloadSize];
memset(payload,'#',payloadSize);
// Ici la partie du code qui prépare LoRa a l'envoi
/*
* Je fais appelle à mes fonctions qui me retorune tous des float.
* J'ai décidé ne pas garder les décimal, sauf pour la batterie et poue les latitude et longitude
* Je dois encore étudier la date. Ce que j'ai fais c'est du brouillon.
* Pour la batterie je garde 2 décimal
* pour lat et lon, je garde 4 décimal
* pour les autres, je garde rien
* Si le moduel est inactif, je garde la valeur de -99. Cette valeur ne sera jamais envoyée. Elle ne s'affiche que si il ya un problème...
*/
/*
* Getting battery value
*/
float fbatt;
int ibatt;
if(battery_active)
{
fbatt = get_battery(battery);
fbatt = fbatt*100;
ibatt = fbatt;
}
else
{
ibatt = -99;
}
mesMesures[c_battery][capteur_battery_id].valeur = ibatt;
/*
* Get temperature, pression, altitude value
*/
float ftemp, fpres, falti;
int itemp, ipres, ialti;
if(temperature_active)
{
ftemp = get_temperature(temperature);
itemp = ftemp;
}
else
{
itemp = -99;
}
mesMesures[c_temperature][capteur_temperature_id].valeur = itemp;
if(pression_active)
{
fpres = get_pression(pression);
ipres = fpres;
}
else
{
ipres = -99;
}
mesMesures[c_pression][capteur_pression_id].valeur = ipres;
if(alt_active)
{
ialti = ALTITUDE;
}
else
{
ialti = -99;
}
mesMesures[c_alt][capteur_alt_id].valeur = ialti;
/*
* Get humidity value
*/
float fhumi;
int ihumi;
if(humidity_active)
{
fhumi = get_humidity(humidity);
ihumi = fhumi;
}
else
{
ihumi = -99;
}
mesMesures[c_humidity][capteur_humidity_id].valeur = ihumi;
/*
* Get moisture value
*/
float fmois;
int imois;
if(moisture_active)
{
fmois = get_moisture(moisture);
imois = fmois;
}else{
imois = -99;
}
mesMesures[c_moisture][capteur_moisture_id].valeur = imois;
/*
* Get luminosity value
*/
int ilumi;
float flumi;
if(luminosity_active)
{
flumi = get_luminosity(luminosity);
ilumi = flumi;
}
else
{
ilumi = -99;
}
mesMesures[c_luminosity][capteur_luminosity_id].valeur = ilumi;
/*
* Get UV value
*/
float fuv;
int iuv;
if(uv_active)
{
fuv = get_uv(uv);
iuv = fuv;
}else{
iuv = -99;
}
mesMesures[c_uv][capteur_uv_id].valeur = iuv;
/*
* Getting GPS value
*/
float flati, flong, fdate;
int ilati, ilong, idate, itime;
if(latitude_active)
{
flati = get_latitude(latitude);
flati = flati*10000;
ilati = flati;
}
else
{
ilati = -99;
}
mesMesures[c_latitude][capteur_latitude_id].valeur = ilati;
if(longitude_active)
{
flong = get_longitude(longitude);
flong = flong*10000;
ilong = flong;
}
else
{
ilong = -99;
}
mesMesures[c_longitude][capteur_longitude_id].valeur = ilong;
if(datetime_active)
{
fdate = get_time(datetime); // 170927.2356
idate = fdate; // 170927
uint16_t item, item2;
fdate = fdate*10000; // 1709272356.00
item = fdate; // 1709272356
item2 = idate*10000; // 1709270000
itime = item-item2; // 2356
}else{
idate = -99;
itime = -99;
}
mesMesures[c_datetime][capteur_datetime_id].valeur = idate;