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

Arduino Discussion :

Utiliser le code ASCII pour extraire deux valeurs.


Sujet :

Arduino

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    bricoleur
    Inscrit en
    Octobre 2014
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : bricoleur
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2014
    Messages : 406
    Par défaut Utiliser le code ASCII pour extraire deux valeurs.
    Bonjour à tous

    J'aurais besoin de créer un caractère dont le code ASCII décimal irait de 11 à 99. La création se ferait par l'ajout de 2 chiffres: le premier pour la dizaine et le second pour l'unité.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    char carte, relais, codeAscii;
    int code;
    //example:
     
    carte='1'; relais='8';
    code = (int(carte)-48)*10 + int(relais)-48;
    codeAscii= char(code);
    puis pour extraire les données ainsi codées:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     int laCarte = int(codeAscii)/10;
     int leRelais = codeAscii - laCarte*10;
    Cela ne semble pas fonctionner.
    Si quelqu'un(e) a une idée. Merci

  2. #2
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 785
    Par défaut
    Hello,

    Un petit exemple codé en C (et ça fonctionne sous arduino, sauf le #include <stdio.h> évidemment):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <stdio.h>
     
    int main(void) {
    	char carte='1', relais='8';
     	int code= (carte-'0')*10 + relais-'0';
    	printf("carte=%c, relais=%c, code=%d\n", carte, relais, code);
     
    	code=25;
    	carte=code/10+'0';
    	relais=code%10+'0';
    	printf("code=%d, carte=%c, relais=%c\n", code, carte, relais);
     
    	return(0);
    }

  3. #3
    Membre éclairé
    Homme Profil pro
    bricoleur
    Inscrit en
    Octobre 2014
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : bricoleur
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2014
    Messages : 406
    Par défaut
    Merci EdgardJacob
    C'est tout à fait cela en plus, simple.
    C'était la restitution des données qui ne fonctionnait pas dans mon code.
    J'avais tort de ne pas rajouté le code Ascii de zéro.
    Cordialement
    Michel

  4. #4
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 909
    Par défaut
    Pourquoi utiliser des chars de code ascii? Prenez directement des entiers…

  5. #5
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 785
    Par défaut
    Citation Envoyé par Jay M Voir le message
    Pourquoi utiliser des chars de code ascii? Prenez directement des entiers…
    L'ascii se code sur au plus 8 bits, pourquoi utiliser un entier ? Question (je débute en code arduino): plus rapide ?

  6. #6
    Membre éclairé
    Homme Profil pro
    bricoleur
    Inscrit en
    Octobre 2014
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : bricoleur
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2014
    Messages : 406
    Par défaut
    La raison première est que dans un programme existant, une case d'un tableau de caractères correspond à une adresse de '0' à '9'.
    Ayant besoin d'augmenter le nombre d'adresses sans changer la structure du tableau, j'ai pensé utiliser les deux chiffres du code ASCII pour passer de 10 adresses à 100 avec un seul caractère. Astucieux, non?

  7. #7
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 634
    Par défaut
    Bonjour,

    Pourquoi ne pas écrire simplement : char c = '0' + i; avec i allant de 0 à 99 (l'ajout de cast serait plus propre mais ça marche).

    C'est, je crois, ce qu'évoquait Jay M (hors les casts "oubliés" ).

    Le décalage opéré par '0' évite seulement d'avoir un caractère nul qui peut, selon les traitements envisagés, présenter quelques problèmes.

    La récupération de i se fait de la même manière : byte i = c - '0';.

    Salutations

  8. #8
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 909
    Par défaut
    à mon avis on est dans le cas d'un problème XY

    Des indices de tableau et des maths, ça se fait avec un type entier

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    byte carte, relais, code; // byte si on sait qu'on reste sous 255
     
    carte=1; 
    relais=8;
    code = carte*10 relais;
     
     byte laCarte = code / 10;
     byte leRelais = code % 10;
    si les éléments pertinents du tableau ne commencent pas à l'adresse 0 dans le tableau mais sont décalés de la valeur ascii de '0' (48), on fait le décalage dans l'accès au tableau en ajoutant systématiquement ces 48.

    cela dit, c'est aussi une drôle d'idée si les 48 premières entrées ne sont pas utilisées, on perd de la mémoire pour rien... ça sent le code mal fichu...

  9. #9
    Membre éclairé
    Homme Profil pro
    bricoleur
    Inscrit en
    Octobre 2014
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : bricoleur
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2014
    Messages : 406
    Par défaut
    Oui, n'étant pas un grand spécialiste, ce code est certainement mal fichu. Il aurait fallu que je reprenne l'analyse complète. Je le ferai certainement quand je serai grand!
    Pour le moment, mon but est de faire fonctionner mon montage électronique et pour l'instant c'est une réussite.

    Pour revenir sur mon besoin exact, le code transmis soit par un clavier, soit par un client réseau, pour enregistrer le programme dans le SPIFFS de l'ESP32 est:
    //**** pour un relais distants: PM D cr tt hh mm 'B' à la place de 'D' pur un relais local (sur la carte de base)
    P est le n° du programme de '0' à '9', M est le n° de la manoeuvre de '0' à '9', 'D' pour un équipement distant, cr de 11 a 98 cr=ascii carte '1' à '9' + relais '1' à '8',
    'h' 'h' 'm' 'm' heure minute de déclenchement.

    Exemple1: {25D61328} mémoire 2, manoeuvre 5, relais distant, carte 5 relais 4, à 13:28 (54 étant le code ASCII de '6')
    Exemple2: {26B30630} mémoire 2, manoeuvre 6, relais local, relais 3, à 6:30

    Bien sûr, lors du contrôle horaire, l'ESP32 extrait et interprète le code pour l'envoyer vers le bon destinataire.

  10. #10
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 909
    Par défaut
    Oui si ça fonctionne c’est déjà ça

    Vous dites «*cr de 11 a 98 cr=ascii carte '1' à '9' + relais '1' à '8',»

    Pourquoi l’ASCII est la question?

  11. #11
    Membre éclairé
    Homme Profil pro
    bricoleur
    Inscrit en
    Octobre 2014
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : bricoleur
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2014
    Messages : 406
    Par défaut
    Pourquoi l’ASCII est la question?
    Par exemple, pour la carte N° 5 et le relais N°4, je considère le code ASCII 54 ce qui me donne le caractère 6, ce qui me permet avec un seul caractère de transmettre 2 adresses.

    L'utilité de cela pour mon application est de ne pas changer la structure du code envoyé et donc de n'avoir à modifier que le décodage du message pour les relais distants.

  12. #12
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 909
    Par défaut
    OK, c'est peut-être juste un mauvaise compréhension de ma part concernant la notion de ASCII

    en pratique, vous n'avez qu'un seul octet dispo dans le protocole que vous remplissez avec 54 pour dire "carte N° 5 et le relais N°4"

    mais 54 est le code ASCII du caractère '6'. le décodage de votre protocole verra donc "carte N° 5 et le relais N°4" ou ce que '6' voulait dire dans l'ancien code ?

  13. #13
    Membre éclairé
    Homme Profil pro
    bricoleur
    Inscrit en
    Octobre 2014
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : bricoleur
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2014
    Messages : 406
    Par défaut
    mais 54 est le code ASCII du caractère '6'. le décodage de votre protocole verra donc "carte N° 5 et le relais N°4" ou ce que '6' voulait dire dans l'ancien code ?
    La programmation horaire des évènements est stockée en mémoire selon un format x y p p h h m m soit 8 caractères.
    Le x définit le type de commande: B pour un relais sur la base, E pour la lecture de capteurs, etc.
    Le y définit l'adresse d'un équipement 1 à 9
    p p sont 2 paramètres, h h l'heure, m m les minutes.

    Cela était le fonctionnement de base.
    Mais j'ai voulu ajouter des équipements muni de 8 relais qu'il me fallait adresser.
    Alors comme le code ASCII est composé de 2 chiffres, j'ai pensé prendre le premier pour adresser la carte, le second pour adresser le relais.

    Donc la commande envoyée vers le serveur spécifie bien carte N°5 et relais N° 4 (par exemple) que le programme transforme en 6 pour le stocker en mémoire selon le protocole. Lorsque l'heure de déclenchement arrive, le programme lit le caractère 6 de la mémoire mais fait l'opération de décodage et en déduit les deux caractères 5 et 4.

    Avec l'aide apportée par edgarjacobs, j'ai pu faire fonctionner parfaitement mon système.

    En conclusion: avec un caractère, je peux adresser jusqu'à 81 relais!

    Merci encore à vous tous pour l'aide précieuse que vous apportez au bricoleur comme moi.
    Michel

  14. #14
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 909
    Par défaut
    Ok compris

    Vous n’avez plus à gérer en même temps l’ancien format

  15. #15
    Membre éclairé
    Homme Profil pro
    bricoleur
    Inscrit en
    Octobre 2014
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : bricoleur
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2014
    Messages : 406
    Par défaut
    si, les deux formats cohabitent. C'est le caractère x type de commande ('B' pour les relais de la base, 'D' pour les relais distants) qui oriente le programme vers tel ou tel décodage.

  16. #16
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 909
    Par défaut
    Citation Envoyé par mormic Voir le message
    Le y définit l'adresse d'un équipement 1 à 9
    était-ce en ASCII '1' à '9' ou la valeur binaire 0x01 à 0x09? sinon il y a risque de chevauchement des 2 modèles?

  17. #17
    Membre éclairé
    Homme Profil pro
    bricoleur
    Inscrit en
    Octobre 2014
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : bricoleur
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2014
    Messages : 406
    Par défaut
    si c'est un relais de la base, le caractère x étant 'B', le caractère y sera directement en Ascii de 1 à 9.
    si c'est un relais distant, le caractère x étant 'D', le caractère y sera aussi en Ascii, mais au lieu d'être lu comme tel, il sera décodé selon le principe d'edgarjacobs; exemple pour un code Ascii de 25:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	code=25;
    	carte=code/10+'0';    //codeAscii de 2
    	relais=code%10+'0';   //codeAscii de 5
    Donc aucun risque de chevauchement.

  18. #18
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 634
    Par défaut Modèle Vue Contrôleur, what else ?
    Bonjour,

    Que cela fonctionne est très bien mais il y a une erreur de conception qui amène des gymnastiques qui limiteront maintenance et évolution. La communication (en ASCII) ne doit pas structurer les données (voir MVC).

    Peu importe le format d'échange (ici la Vue est essentiellement le Moniteur et la liaison série), l'organisation des données (Modèle) n'y est pas liée. Par exemple, mais il y en a d'autres certainement meilleurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef enum action_t {
       actNone, actOn, actOff, actOnTemp, actOffTemp
       };
     
    typedef struct Prog_t {
       action_t action;
       uint8_t iCarte, iRelais, h, mn, actParam;
       }
    On considère ici que la carte 0 désigne la carte de base. Les actions types sont dans une énumération qui permet d'utiliser un symbole signifiant. dans le programme (ma liste est bidon, juste pour illustration). Au total cela consomme 6 octets. En utilisant des champs binaires (ou explicitement v >> 4 et v & 0x0F) associant iCarte et iRelais, on pourrait gagner encore un octet.

    La traduction (C) entre caractères (V) et enregistrement (M) a lieu à réception et non, comme dans le schéma d'origine, à chaque utilisation d'un enregistrements. Outre les gains de places et performances, cela permet de signifier, dès la réception, les erreurs détectées (par exemple 2 ordres consécutifs de collage du même relais).

    Comme on le voit, cela amène à gérer séparément les échanges avec l'utilisateur et les traitements et stockage. Ce n'est pas juste pour faire joli, c'est plus fiable et plus évolutif. Il est possible de faire varier le dialogue Homme-machine en ne changeant que la traduction de ceux-ci sans altérer rien d'autre.

    C'est déjà remarquable d'avoir un programme qui fonctionne. C'est une base pour l'améliorer, pas nécessairement avec plus de fonctionnalités, mais en repensant certains choix.

    Ce qui m'a toujours fasciné est que le travail de réflexion préalable, parfois long et ardu, aboutisse souvent à un programme bien plus simple, efficace et lisible qu'une écriture directe qui doit être caviardée avec des astuces peu lisibles pour corriger le tir.

    Salutations

  19. #19
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 909
    Par défaut
    d'accord compris.

  20. #20
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 909
    Par défaut
    La communication (en ASCII) ne doit pas structurer les données (voir MVC).
    Tout protocole de communication structure les données. C’est le rôle du contrôleur des 2 côtés de sérialiser et désérialiser les données du modèle…

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

Discussions similaires

  1. [AC-2013] code VBA pour extraire tous les dates entre deux dates.
    Par Rafikaccess dans le forum Access
    Réponses: 2
    Dernier message: 20/10/2023, 13h06
  2. Utilisation de ctypes pour extraire une valeur/un tableau
    Par XeO3n dans le forum Interfaçage autre langage
    Réponses: 1
    Dernier message: 04/07/2012, 00h33
  3. Utilisation du code Ascii pour quitter une feuille.
    Par ALUSIP Dranreb dans le forum VB.NET
    Réponses: 1
    Dernier message: 07/04/2011, 17h11
  4. Code ascii pour les accents ?!
    Par ender08450 dans le forum C++
    Réponses: 4
    Dernier message: 29/12/2006, 01h32
  5. code java pour récupérer la valeur d'un neoud XML
    Par MASSAKA dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 14/10/2005, 15h17

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