IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Conversion pour réduire la taille d'une trame


Sujet :

C

  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 171
    Par défaut Conversion pour réduire la taille d'une trame
    Bonjour, pour un projet je recupere des trames de la forme suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    //Date, Heure, Latitude, Longitude, Nombre de satellites captes, Altitude, Temperature 1, Temperature 2
     
    => 70618,93101,Lat:50.103366,Long:14.391946,NbSat:12,Alt:250,T1:27.443226,T2:26.556774 <=
    => 70618,93112,Lat:50.103366,Long:14.391901,NbSat:12,Alt:254,T1:27.362640,T2:25.267401 <=
    => 70618,93123,Lat:50.103348,Long:14.391873,NbSat:12,Alt:256,T1:27.120874,T2:25.106226 <=
    Je souhaite reduire la taille de cette trame et j'ai les contraintes suivantes:

    The Longitude, latitude, and elevation were obtained from GGA sentence.
    The longitude and Latitude were firstly transformed to degrees (<0,360)
    degrees) and then represented by 3 bytes unsigned fixed-point number.
    number, 0 deg corresponds to 0x000000 and 360 deg to 0x1000000.
    The altitude was rounded to meters and transmitted by two bytes number.
    The range is 0 to 65536 meters.
    J'ai deja recupere les GGA sentences et je les ait converties en degres.

    Maintenant j'aimerais faire la conversion pour que la latitude et la longitude tiennent sur 3 bytes et que l'altitude tienne sur 2 bytes. Je vois bien que je vais devoir faire une table de 3 (enfin je pense) mais une fois que j'aurais, admettons une latitude convertie en 0x038765 (juste un exemple), je ne vois pas dans quel type de variable le stocker ni comment l'ecrire pour qu'il prenne reellement un taille de 3 bytes

    Enfin comme vous voyez c'est un peu confus pour moi a partir du moment ou je dois convertir en byte, auriez vous des pistes, solutions ?

    Merci

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Généralement, un type au byte près, ça veut dire des données binaires brutes.
    En gros, un tableau de unsigned char dans lequel tu écris au fur et à mesure (renseigne-toi sur le boutisme (endianness) des nombres, aussi).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    Tu souhaites transmettre un flux (réseau ? fichier ?). Ce flux est constitué d'octets.
    Pour construire la valeur sur 3 octets, tu as pleins de solutions. Tu peux par exemple utiliser un int sur 4 octets mais tu vas t'assurer que la valeur stockée ne dépasse pas la valeur max de 3 octets.
    Ensuite, tu vas écrire les 3 octets dans le flux en faisant un décalage de bit et un masque :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int entier = 342;
    unsigned char octet1 = entier & 0xFF;
    unsigned char octet2 = (entier >> 8) & 0xFF;
    unsigned char octet3 = (entier >> 16) & 0xFF;
    EDIT : trop lent
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  4. #4
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 171
    Par défaut
    Salut, merci pour vos reponses.

    Je veux transmettre un message via l'uart de mon microcontrolleur (stm32l152re) qui est connecte a un module Sigfox et ce dernier n'accepte "que" des messages de 12 octets.

    Parmi ces 12 octets le debut de ma trame doit etre:
    -3 octet pour la longitude
    -3 octet pour la latitude
    -2 octet pour l'altitude (elevation)

    Je recupere ces donnees via un module GPS (neo 6m).

    La longitude est exprimee en degree de -90 a 90.
    La latitude est exprimee en degree de -180 a 180.
    L'altitude est exprimee en metres de 0 a ?? (au moins 50 000) car le gps va etre envoye dans la stratosphere)

    Par exemple pour le cas de l'altitude, j'aimerais que -180 degres corresponde a la valeur 0x000000 et que +180 degres corresponde a 0xFFFFFF

    Je vois pas trop le rapport entre ce que je viens de decrire les "unsigned", je suis oblige de faire un decalage de flux et un masque?
    Je peux pas directement convertir mes valeurs?

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Tu veux représenter [-180, 180] sur [0,16777215], donc sur une valeur non signé.
    C'est une simple projection, il faut résoudre ANGLE = A * NOMBRE pour retrouver ton angle à partir du nombre envoyé sur le réseau, et bien entendu NOMBRE = ANGLE / A pour trouver le nombre correspondant à l'angle.
    Et vu que tu connais les valeurs pour -180 et 180, c'est une équation de niveau collège(?) à résoudre pour le coefficient.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 171
    Par défaut
    Salut, effectivement le probleme ce n'est pas l'equation mais plutot la mise en pratique au niveau des variables, j'ai ecris cela:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    char str_frame[7];
    void sigfox_send_frame(long latitude, long longitude, uint16_t altitude)
    {
    	double lat_precision = 360/0xFFFFFF;
    	double long_precision = 180/0xFFFFFF;
    	double alt_precision = 65536/0xFFFF;
     
    	unsigned long lat_unsigned = lat_precision*latitude;
    	unsigned long long_unsigned = long_precision*longitude;
    	unsigned int alt_unsigned = alt_precision*altitude;
    	sprintf(str_frame,"AT$SF=%lu%lu%u\r",lat_unsigned,long_unsigned,alt_unsigned);
    	UART_puts(UART3_ID, (uint8_t*)str, sizeof(str));
    }
    Rien qu'au debut mes variables "precision" me retourne 0. Je pourrais remplacer les 0xFFFFFF par des nombres reels (16 777 215) mais je veux que dans str_frame, le resultat soit du genre: "AT$SF=1010AF0101FA4532\r" et non pas des nombres entiers.

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Rien qu'au debut mes variables "precision" me retourne 0.
    Tu fais des divisions entières donc oui tes résultats valent 0..
    Je pourrais remplacer les 0xFFFFFF par des nombres reels (16 777 215)
    Ce qui n'a strictement aucun intérêt et ne changerait rien, sauf à lire des nombres décimaux si t'es plus à l'aise avec.

    Le but c'est de sérialiser/compresser des valeurs flottantes avec une virgule fixe (technique classique de sérialisation et compression).
    Si je décide de sérialiser avec 1 décimal, je prends ma valeur, la multiplie par 10, et je peux couvrir les valeurs [0, 180] avec une précision à 0.1 par un intervale [0, 1800].
    Je ne vois pas comment l'expliquer plus clairement à ce stade..

    je veux que dans str_frame, le resultat soit du genre: "AT$SF=1010AF0101FA4532\r"
    D'où sort ce résultat et que signifie-t-il ?

    et non pas des nombres entiers.
    L'énoncé stipule clairement que tu dois sérialiser sur des valeurs non signées. Qu'espères-tu avoir d'autre que des nombres entiers ?!

    Et d'où sort ce format texte de trame ? Pourquoi ne pas simplement manipuler du binaire ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  8. #8
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 171
    Par défaut
    D'où sort ce résultat qui n'a aucun sens ?
    C'est simplement un exemple (les valeurs ne representent rien de reel c'est juste pour un exemple) de la forme de la trame que je souhaite avoir au final:

    "AT$SF=1010AF0101FA4532\r"

    Il s'agit d'une commande AT qui envoie les donnees via Sigfox sur leur site internet pour pouvoir les traiter sur l'interface prevue a cet effet.

    Les 3 premiers bytes correspondent a la latitude, les 3 suivants a la longitude et les deux derniers a l'altitude.

    L'énoncé stipule clairement que tu dois sérialiser sur des valeurs non signées. Qu'espères-tu avoir d'autre que des nombres entiers ?!

    Et d'où sort ce format texte de trame ? Pourquoi ne pas simplement manipuler du binaire ?
    "J'espere" obtenir une trame composee de (pour l'instant) 8 bytes en hexadecimal comme l'exemple que j'ai ecris un peu plus haut.


    Tu fais des divisions entières donc oui tes résultats valent 0..
    Je devrais donc stocker ces variables de precision dans des float ?

    Le but c'est de sérialiser/compresser des valeurs flottantes avec une virgule fixe (technique classique de sérialisation et compression).
    Si je décide de sérialiser avec 1 décimal, je prends ma valeur, la multiplie par 10, et je peux couvrir les valeurs [0, 180] avec une précision à 0.1 par un intervale [0, 1800].
    Je ne vois pas comment l'expliquer plus clairement à ce stade..
    Je crois que ca repond a ma question precedente. Par contre pour la technique de serialisation je vois pas trop pourquoi tu multiplie par 10, pourquoi ne pas avoir une precision de 0.01 sur l’intervalle [0,180] ?

  9. #9
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Citation Envoyé par tengalice49 Voir le message
    Je crois que ca repond a ma question precedente. Par contre pour la technique de serialisation je vois pas trop pourquoi tu multiplie par 10, pourquoi ne pas avoir une precision de 0.01 sur l’intervalle [0,180] ?
    En informatique, les représentations dites "en virgule fixe" sont sur des entiers. Si tu veux une précision de 0.01 sur l'intervalle [0.00, 180.00], il te faut alors des entiers de 0 à 18000.
    Ensuite, le code qui reçoit les infos peut les re-convertir en double, simplement en divisant par 100.0.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    Reprenons depuis le début et commençons par la latitude (pour éviter de se disperser).
    En entrée, tu as la latitude sous forme entière, de -180 à 180. Pour l'encoder sur 3 octets, tu as plusieurs possibilités, en fonction du programme qui va recevoir les données.
    Par exemple, tu peux appliquer un décalage pour avoir une valeur toujours positive. Il suffit d'ajouter 180 à la latitude et tu obtiens un intervalle [0;360].
    La valeur maximum 360 s'écrit sur 2 octets.
    L'encodage sur 3 octets se fait comme suit (en supposant que les bits de poids forts sont lus en premier) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    long latitude = la_veritable_valeur;
    latitude += 180;
    unsigned char tab[3];
    tab[0] = 0;
    tab[1] = (latitude >> 8) & 0xFF;
    tab[2] = latitude & 0xFF;
    Ta latitude est maintenant sur 3 octets.
    Tu fait la même chose pour la longitude dans l'intervalle [-90;90] en ajoutant 90 pour avoir un intervalle [0;180]. La valeur maximum s'écrit sur un octet, donc les 2 premiers octets sont toujours à 0.

    Pour la latitude et la longitude, on s'aperçoit qu'il y a des octets inutiles.

    Enfin, pour l'altitude en mètres, tu as 2 octets donc la valeur maximum représentable sera 65536 mètres.

    Pour la trame Sigfox, tu parles de flux puis tu donnes un exemple avec une chaine de caractères. Quelle est la syntaxe exacte ? Soit tu écrits les octets directement dans le flux, soit tu convertis tes valeurs en caractères ASCII. Ce n'est pas du tout la même chose.


    EDIT : comme le dit Medinoc, il faut savoir si tu as des entiers ou des flottants en entrée. Quelles sont les plages de valeurs de tes données d'entrée ? Et en sortie ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  11. #11
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 171
    Par défaut
    Merci pour toutes vos reponses, je vais essayer d'etre un peu plus clair mais pour moi ca ne l'est pas totalement de base donc je fais de mon mieux

    Pour la trame Sigfox, tu parles de flux puis tu donnes un exemple avec une chaine de caractères. Quelle est la syntaxe exacte ? Soit tu écrits les octets directement dans le flux, soit tu convertis tes valeurs en caractères ASCII. Ce n'est pas du tout la même chose.
    Pour que Sigfox comprenne ce que je lui envoie, il doit recevoir un message du type AT$SF=frame[,bit]. Toutes les commandes AT sont dispo sur la datasheet a partir de la page 9: https://www.lpwan.cz/LPWAN_sigfox_node_datasheet_v1.pdf

    Moi j'ai connecte mon module Sigfox a l'uart de mon microcontrolleur et je lui envoie les commandes AT sous forme de chaine de caractere comme cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char str[11];
    void sigfox_send_test(void){
    	sprintf(str,"AT$SF=4444\r");
    	UART_puts(UART3_ID, (uint8_t*)str, sizeof(str));
    	HAL_Delay(10000);
    }
    L'exemple ci-dessus fonctionne et envoie la donnee "4444" sur le site de Sigfox.


    EDIT : comme le dit Medinoc, il faut savoir si tu as des entiers ou des flottants en entrée. Quelles sont les plages de valeurs de tes données d'entrée ? Et en sortie ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void sigfox_send_frame(double latitude, double longitude, uint16_t altitude)
    Je recupere la latitude et la longitude en double, et l'altitude en uint16_t.

    Les plages d'entrees sont:
    -180 a +180 degres pour la latitude
    -90 a +90 degres pour la longitude
    0 a 65536 metres pour l'altitude

    Par exemple pour le moment je suis a Prague et j'ai les valeurs suivantes:
    Lat:50.103233
    Long:14.391686
    Alt:269

    Le probleme c'est justement en sortie ! J'aimerais que la latitude et la longitude sortent en hexadecimal sur 3 octets chacuns et que l'altitude sorte sur 2 octets

  12. #12
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par dinobogan Voir le message
    Pour la latitude et la longitude, on s'aperçoit qu'il y a des octets inutiles.
    Sauf qu'il y a une partie de l'énoncé que tout le monde occulte qui est represented by 3 bytes unsigned fixed-point number. Et à juste titre, une latitude et longitude n'est pas entière.
    Donc non il n'y a pas d'octet inutile, juste une précision à définir et fixer, pour tenir sur 3 octets.

    Le probleme c'est justement en sortie ! J'aimerais que la latitude et la longitude sortent en hexadecimal sur 3 octets chacuns et que l'altitude sorte sur 2 octets
    printf("0x%06x", latitude); et paf tu as ta sortie en héxa sur 3 octets.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  13. #13
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 171
    Par défaut
    En ecrivant comme cela j'obtiens bien de valeur de precisions:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void sigfox_send_frame(double latitude, double longitude, uint16_t altitude)
    {
    	double lat_precision = 360.0/0xFFFFFF;
    	double long_precision = 180.0/0xFFFFFF;
    	uint16_t alt_precision = 65535.0/0xFFFF;
    
    	unsigned long lat_unsigned = lat_precision*latitude;
    	unsigned long long_unsigned = long_precision*longitude;
    	unsigned int alt_unsigned = alt_precision*altitude;
    	sprintf(str_frame,"AT$SF=%lu%lu%u\r",lat_unsigned,long_unsigned,alt_unsigned);
    	UART_puts(UART3_ID, (uint8_t*)str_frame, sizeof(str_frame));
    	HAL_Delay(10000);
    }
    Cependant les variables que j'ai ecrit en rouge sont des entiers donc au moment de les ajouter dans str_frame ce ne sont pas des valeurs hexadecimales.

    Nom : str_frame.jpg
Affichages : 609
Taille : 126,3 Ko

    Ici latitude et longitudes valent 0 je ne sais pas pourquoi et ensuite il y a l'altitude qui prends 3 bytes, un pour la centaine, un pour la dizaine et un pour l'unite c'est pas du tout ce que je veux...

    printf("0x%06x", latitude); et paf tu as ta sortie en héxa sur 3 octets.
    Tu peux m'expliquer un peu ? A quoi correspond "0x%06x" ?

  14. #14
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 845
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 845
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par tengalice49 Voir le message
    Cependant les variables que j'ai ecrit en rouge sont des entiers donc au moment de les ajouter dans str_frame ce ne sont pas des valeurs hexadecimales.
    Bonjour
    Cela ne veut rien dire une "valeur hexadécimale". Une valeur exprime une quantification (un caillou, deux coquillages, trois arbres) tandis que l'hexadécimal exprime la base permettant d'afficher cette valeur au moyen de symboles (autant de symboles différents que la base exprimée ; et un décalage d'une unité vers la gauche chaque fois qu'on atteint "base" symboles).
    Si par exemple je te demande de me dire combien tu as de doigts, ben rien ne t'interdit de me répondre "j'en ai 101". Parce que ce nombre, exprimé dans une certaine base (ici 3) correspond à la quantité exate de tes doigts. Et (en admettant que tu aies 10 doigts), ben on peut regrouper ces 10 doigts en 3 groupes (niveau 1) de 3 et il en reste 1. Et ces 3 groupes se regroupent eux-même en 1 groupe (niveau 2) et il en reste 0. D'où 10(10) = 101(3).

    Donc pour un ordinateur, un nombre c'est un nombre et il s'en fout de la base avec laquelle tu l'affiches parce que pour lui, c'est tout en base 2.

    Citation Envoyé par tengalice49 Voir le message
    Tu peux m'expliquer un peu ? A quoi correspond "0x%06x" ?
    "0x" c'est une chaine écrite en dur (exactement comme dans printf("Hello")) ; et "%06x" c'est "nombre entier affiché au format hexadécimal sur 6 positions avec complément à 0 si le nombre ne remplit pas ces 6 positions". C'est écrit dans toutes les doc de printf().
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  15. #15
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 171
    Par défaut
    Bonjour,

    Dites moi ce que vous en pensez si je fais comme cela:

    Je recupere ma valeur de latitude, puis je lui ajoute 180 pour avoir un intervalle de [0,360]:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    latitude = 50,3647747; //valeur exemple
    	latitude += 180;
    D'abord je regle la precision de la valeur que je souhaite (je veux que 0x000000 corresponde a un angle de 0 degre et que 0xFFFFFF corresponde a un angle de 360 degres):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    float lat_precision = 0xFFFFFF/360.0;
    Je mets ensuite dans une variable non signee la valeur que j'obtiens en faisant la conversion de l'intervalle [0,360] a [0,16777215]:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unsigned long valeur = latitude*lat_precision;
    Ensuite j'ecris cette valeur dans une chaine de caractere en la "transformant" en hexadecimal:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sprintf(str_frame,"AT$SF=%06x\r",valeur);

  16. #16
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Ca ressemble déjà plus à ce que tu devrais avoir.
    Sauf qu'en continuant à écrire des chaînes de caractères, tu n'enverras jamais 3 octets mais 6 (%06 va écrire 6 caratères, soit 6 octets..). Cette écriture est juste bonne à vérifier ta valeur mais ne devrait pas être envoyée.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  17. #17
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 171
    Par défaut
    Sauf qu'en continuant à écrire des chaînes de caractères, tu n'enverras jamais 3 octets mais 6 (%06 va écrire 6 caratères, soit 6 octets..). Cette écriture est juste bonne à vérifier ta valeur mais ne devrait pas être envoyée.
    C'est etonnant parce qu'avec le code suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    char str_frame[23];
    void sigfox_send_frame(double latitude, double longitude, uint16_t altitude)
    {
    	float lat_precision = 0xFFFFFF/360.0;	//precision for latitude
    	float long_precision = 0xFFFFFF/180.0;	//precision for longitude
    	float alt_precision = 0xFFFF/65535;		//precision for altitude
     
    	latitude += 180;						//[-180,180] -> [0,360]
    	longitude += 90;						// [-90,90]  -> [0,180]
     
    	unsigned long latitude_convert = latitude*lat_precision;	//converted values for latitude
    	unsigned long longitude_convert = longitude*long_precision;	//					   longitude
    	unsigned int altitude_convert = altitude*alt_precision;		//				   and altitude
     
    	sprintf(str_frame,"AT$SF=%06x%06x%04x\r",latitude_convert,longitude_convert,altitude_convert);	//frame to send
    	UART_puts(UART3_ID, (uint8_t*)str_frame, sizeof(str_frame));									//send frame to uart 3
    	HAL_Delay(10000);																				//with a 10-seconds delay
    }
    Tout fonctionne comme je le souhaite, je recupere des trames de ce format:
    Nom : sigfoxtrames.jpg
Affichages : 586
Taille : 123,9 Ko

    Si je prends la derniere trame recue: a3a1019477da0113

    J'ai bien mon altitude en rouge sur 3 octets, ma longitude en bleu sur 3 octets et mon altitude en noir sur 2 octets. De plus, Sigfox ne peut pas recevoir plus de 12 octets donc si ca avait ete 6 octets de latitude + 6 octets de longitude+ 4 octets d'altitude (au lieu de 3+3+2) je pense que ma trame n'aurait pas ete envoyee correctement, je me trompe?

  18. #18
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 845
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 845
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par tengalice49 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	char str_frame[23];
    	sprintf(str_frame,"AT$SF=%06x%06x%04x\r",latitude_convert,longitude_convert,altitude_convert);	//frame to send
    	UART_puts(UART3_ID, (uint8_t*)str_frame, sizeof(str_frame));	
    }
    De plus, Sigfox ne peut pas recevoir plus de 12 octets donc si ca avait ete 6 octets de latitude + 6 octets de longitude+ 4 octets d'altitude (au lieu de 3+3+2) je pense que ma trame n'aurait pas ete envoyee correctement, je me trompe?
    Ben c'est encore plus étonnant que ce que tu dis car "str_frame" commence par "AT$SF=" ce qui fait déjà 6 octets de perdus sur les 12 disponibles. Ne t'en reste donc plus que 6 pour y coder ta géographie.
    De plus, étant donné que str_frame est défini comme un tableau de 23 octets, alors sizeof(str_frame) vaut "23" (rappel sizeof != strlen). Donc quoi que contienne ce tableau, c'est tout son contenu que tu envoies à un truc ne pouvant (d'après ce que tu dis) pas recevoir plus de 12 octets.
    Et il se trouve qu'il reçoit tout. Donc (conclusion rapide) l'info "Sigfox ne peut pas recevoir plus de 12 octets" semble erronée...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  19. #19
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 171
    Par défaut
    Salut,

    Ben c'est encore plus étonnant que ce que tu dis car "str_frame" commence par "AT$SF=" ce qui fait déjà 6 octets de perdus sur les 12 disponibles. Ne t'en reste donc plus que 6 pour y coder ta géographie.
    Oui mais ca c'est ce que j'envoie sur l'UART.

    Sigfox lui ne prend en compte que ce qui est ecrit entre le "=" et le "\r", donc quand je dis que Sigfox ne peut pas recevoir des messages de plus de 12 octets je parle du message contenu dans la commande AT:

    "AT$SF=%06x%06x%04x\r"

    En rouge on est d'accord que j'ai ici 8 octets d'envoyes ?

  20. #20
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Tu lis un peu les réponses ?
    Citation Envoyé par tengalice49 Voir le message
    "AT$SF=%06x%06x%04x\r"

    En rouge on est d'accord que j'ai ici 8 octets d'envoyes ?
    Devine ?
    Citation Envoyé par Bousk Voir le message
    %06 va écrire 6 caratères, soit 6 octets..
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Utiliser l'api GDi+ pour réduire la taille d'une image
    Par deepshark dans le forum WinDev
    Réponses: 3
    Dernier message: 04/06/2010, 09h31
  2. Possibilités pour réduir la taille d'une BDD
    Par farenheiit dans le forum Administration
    Réponses: 6
    Dernier message: 04/06/2009, 16h50
  3. Réponses: 2
    Dernier message: 09/06/2006, 14h49
  4. Réduire la taille d'une Lite déroulante, mais ...
    Par Joe Le Mort dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 18/05/2006, 15h17
  5. [Oracle 8i] réduire la taille d'une base de test
    Par delphim dans le forum Oracle
    Réponses: 2
    Dernier message: 04/07/2005, 11h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo