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 :

[Arduino/Python] Problème de transmission


Sujet :

Arduino

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Électricien
    Inscrit en
    Février 2018
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Électricien

    Informations forums :
    Inscription : Février 2018
    Messages : 15
    Points : 7
    Points
    7
    Par défaut [Arduino/Python] Problème de transmission
    Bonjour à tous !

    Je me permet de venir demander votre aide car j'ai un problème de transmission entre un script Python lancé sur linux et un arduino Nano.

    Mon projet est de créé un système commandé par Domoticz ( qui est une application sur linux de domotique ) qui est dans mon bureau, pour piloter ma climatisation qui est dans mon salon via une led Infra rouge.

    Actuellement j'ai un système comme ceci :

    - Un serveur Linux sur un petit PC

    - L'application Domoticz

    - un RFXCom 433 MHz

    - des relais 433MHz sur mes radiateurs éléctriques

    - un Broadlink Infrarouge WiFi qui reproduit mes trames infrarouges lancé normalement via ma télécommande de clim

    Mon but est de supprimé le broadlink wifi.

    Tout ceci permet de gérer mon chauffage à distance via l'application smartphone, ou automatiquement grâce au calendrier.

    Pour supprimer de broadlink IR j'ai imaginé un petit système :

    - Une carte émettrice : connecté au PC avec Domoticz et qui envoi l'information via un transmetteur RF 433Mhz

    - Une carte Recepteur : alimenté par secteur dans le salon avec le recepteur RF 433MHz et une led Infra rouge pour reproduire la trame IR

    Donc on récapitule, le fonctionnement du système est :

    1 - Je lance une script Python via Domoticz avec une commande : lgChaud22fast ( climatiseur LG en mode Chauffage à 22° et ventilation rapide )

    2 - le Script Python recoit l'ordre et transmet la trame infra rouge correspondante

    3 - la carte émetteur recoit la trame et la divise en deux ( j'utilise la bibliothéque VirtualWire pour envoyer la trame sous forme de tableau et si le tableau est trop long l'arduino bug )

    4 - la carte récepteur recoit la trame en deux fois

    5 - la carte récepteur réintégre la trame divisé en deux dans un seul tableau

    6 - la carte récepteur envoie la trame Infra Rouge via la LED

    Pour mieux comprendre voilà un peu de code :
    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
     
    #!/usr/bin/python
    #coding=utf-8
    import sys
    import time 
    import serial 
    ser = serial.Serial(
        port='/dev/ttyACM0',
        baudrate=9600,
        parity=serial.PARITY_ODD,
        stopbits=serial.STOPBITS_TWO,
        bytesize=serial.SEVENBITS
    )
    trame = 'null'
    try:
        ordre = sys.argv[1]
    except IndexError:
        ordre = 'null'
     
    if ordre == 'lgChaud22fast':
        trame = ["444", "14876", "104", "11372", "184", "9016", "364", "1724", "232", "30844", "3208", "9880", "500", "1576", "500", "564", "476", "540", "496", "560", "472", "1596", "476", "556", "476", "556", "472", "568", "476", "560", "476", "560", "472", "556", "476", "556", "476", "556", "476", "1588", "448", "576", "496", "556", "476", "556", "476", "1588", "476", "1584", "476", "1604", "476", "556", "472", "1588", "476", "556", "476", "556", "476", "1588", "476", "1580", "496", "1588", "476", "1588", "476",";"] 
    elif ordre == 'lgChaud18fast':
        trame = '3208, 9848, 476, 1600, 504, 540, 504, 544, 496, 532, 496, 1604, 476, 540, 504, 552, 476, 532, 500, 556, 476, 556, 476, 532, 496, 540, 500, 544, 504, 1596, 476, 536, 504, 552, 476, 532, 500, 532, 500, 1588, 476, 1584, 476, 536, 504, 1588, 476, 536, 504, 532, 496, 1596, 476, 532, 500, 1584, 476, 1596, 476;'
    elif ordre == 'lgSwingOn':
        trame = '3232, 9832, 496, 1584, 500, 556, 476, 556, 476, 552, 476, 1612, 476, 540, 496, 560, 472, 556, 476, 556, 476, 556, 476, 556, 476, 1600, 452, 572, 500, 556, 476, 1588, 476, 1576, 500, 564, 476, 564, 476, 556, 476, 1584, 476, 556, 476, 1588, 476, 540, 496, 556, 476, 1588, 476, 564, 452, 572, 500, 1584, 476;'
    elif ordre == 'lgSwingOff':
        trame = '3204, 9848, 500, 1584, 500, 556, 476, 556, 472, 556, 480, 1584, 476, 540, 500, 556, 472, 560, 472, 556, 476, 556, 476, 556, 476, 1584, 476, 560, 472, 556, 452, 1612, 500, 1584, 476, 564, 476, 540, 500, 548, 500, 564, 472, 1604, 476, 540, 500, 556, 476, 1588, 476, 1576, 476, 1612, 500, 556, 476, 1600, 476;'
    elif ordre == 'lgFroid25fast':
        trame = '3208, 9848, 472, 1616, 504, 532, 500, 532, 500, 528, 504, 1568, 500, 536, 504, 536, 504, 536, 504, 524, 504, 532, 500, 532, 500, 540, 500, 532, 500, 532, 500, 528, 500, 536, 504, 1568, 504, 536, 504, 1584, 476, 532, 500, 532, 500, 1576, 504, 532, 504, 532, 500, 1612, 476, 1572, 504, 1564, 500, 540, 500;'
    elif ordre == 'lgFroid25auto':
        trame = '3208, 9860, 532, 1592, 480, 532, 504, 532, 500, 532, 500, 1576, 500, 544, 496, 564, 452, 568, 504, 528, 504, 528, 504, 528, 504, 536, 500, 532, 500, 532, 500, 556, 476, 536, 504, 1584, 476, 536, 504, 1592, 480, 536, 500, 532, 500, 1592, 480, 532, 500, 1584, 476, 1568, 504, 1572, 504, 1588, 476, 1600, 480;'
    elif ordre == 'lgFroid26auto':
        trame = '3288, 9876, 500, 1596, 504, 540, 500, 536, 504, 528, 504, 1584, 480, 528, 500, 532, 500, 532, 500, 528, 504, 532, 496, 532, 500, 536, 504, 532, 500, 532, 500, 528, 504, 528, 504, 1564, 496, 532, 500, 1576, 504, 1560, 500, 540, 500, 1576, 504, 532, 508, 1584, 476, 532, 500, 532, 500, 528, 500, 532, 500;'
    elif ordre == 'lgFroid26fast':
        trame = '3288, 9880, 476, 1600, 504, 536, 500, 532, 504, 528, 500, 1564, 500, 536, 504, 532, 472, 568, 504, 532, 500, 532, 500, 532, 500, 536, 504, 528, 504, 528, 500, 532, 500, 536, 504, 1584, 480, 532, 504, 1596, 476, 1568, 504, 536, 500, 1572, 500, 536, 504, 528, 504, 1584, 476, 1596, 476, 1584, 476, 1604, 476;'
    elif ordre == 'lgFan':
        trame = '3368, 9860, 528, 1596, 476, 536, 504, 528, 504, 528, 500, 1604, 476, 536, 504, 536, 500, 536, 496, 544, 504, 532, 500, 532, 500, 532, 500, 532, 504, 532, 500, 1596, 480, 532, 504, 528, 504, 528, 500, 1576, 496, 1568, 504, 532, 504, 532, 500, 532, 500, 528, 504, 540, 500, 1592, 476, 532, 500, 1596, 476;'
    elif ordre == 'lgFanOff':
        trame = '3368, 9860, 528, 1596, 476, 536, 504, 528, 504, 528, 500, 1604, 476, 536, 504, 536, 500, 536, 496, 544, 504, 532, 500, 532, 500, 532, 500, 532, 504, 532, 500, 1596, 480, 532, 504, 528, 504, 528, 500, 1576, 496, 1568, 504, 532, 504, 532, 500, 532, 500, 528, 504, 540, 500, 1592, 476, 532, 500, 1596, 476;'
     
     
     
     
    ser.isOpen()
    time.sleep(2)
    ser.write(trame.encode("ascii")+'\r\n')
    #n = len(trame)
    #print trame
    #for lettre in trame:
    #    if lettre != " ":
    #	ser.write(lettre.encode("ascii")+'\r\n')
    #	print lettre
    #    elif lettre == ";":
    #	break
    #ser.close()
    lu = ser.readline()
    print lu
    print "Code Sent...."
    et l'arduino Nano pour l'émetteur :
    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
     
    #include <VirtualWire.h>
     
    int tIR[69] = {0};
    int octetReception = 0; // variable de stockage des valeurs reçues sur le port Série (ASCII)
    char caractereRecu = 0; // variable pour stockage caractère recu
    int compt = 0; // variable comptage caractères reçus
    int nbIR = 0;
    String chaineReception = "";
     
     
    void setup() {
      // Initialisation de la bibliothèque VirtualWire
      // Vous pouvez changez les broches RX/TX/PTT avant vw_setup() si nécessaire
      Serial.begin(9600);
      vw_setup(2000);
      vw_set_tx_pin(11);
    }
    void sendRF()
    {
      int tRF1[35] = {0};
      int tRF2[36] = {0};
      tRF1[0] = 1;
      tRF2[0] = 2;
      int i2 = 1;
      int i = 0;
      int i3 = 1;
      for (i = 0; i < 34; i++)
      {
        tRF1[i2] = tIR[i];
        i2++;
      }
      i2 = 1;
      for (i = 34; i < 69; i++)
      {
        tRF2[i2] = tIR[i];
        i2++;
      }
     
      //   Lit les broches analogiques
      vw_send((byte *) &tRF1, sizeof(tRF1)); // On envoie le message
      vw_wait_tx(); // On attend la fin de l'envoi
      delay(100);
      vw_send((byte *) &tRF2, sizeof(tRF2)); // On envoie le message
      vw_wait_tx(); // On attend la fin de l'envoi
      delay(50);
      nbIR = 0;
     
    }
     
    void loop() {
      int c = 0;
     
      while (Serial.available() > 0) { // tant qu'un octet en réception
     
        octetReception = Serial.read(); // Lit le 1er octet reçu et le met dans la variable
        compt = compt + 1;
     
        if ((octetReception == 44) || (octetReception == 59))
        {
     
          char str[15] = {NULL};
          int v;
          for (v = 0; v <= compt; v++)
          {
            str[v] = chaineReception[v];
          }
          tIR[nbIR] = strtol(str, NULL, 10);
          if (octetReception == 59)
          {
            sendRF();
            chaineReception = ""; //RAZ le String de réception
            compt = 0; // RAZ compteur
            break;
          }
          else
          {
            nbIR++;
          }
          chaineReception = ""; //RAZ le String de réception
          compt = 0; // RAZ compteur
        }
        else { // si le caractère reçu n'est pas un saut de ligne
          caractereRecu = char(octetReception); // convertit l'octet reçu en caractère
          chaineReception = chaineReception + caractereRecu; 
        }
     
      } 
    }
    Donc en faite... tout fonctionne ! Sauf lorsque le script Python envoie la trame qui correspond à l'ordre en question

    Donc le script python balance la trame 476, 15972, 455 machin machin

    et l'arduino ( carte émetteur qui est connecté au PC avec linux ) recoit :

    TrameIR=0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 1, 47, 1, 47, 0, 0, 1, 47, 0, 0, 0, 4, 1, 47, 0, 0, 1, 47, 1, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

    le Nano recepteur recoit aussi cette trame la incomplète
    lorsque je travail sur l'IDE et le moniteur série de l'arduino et que j'envoi manuellement la trame correct, la clim se met en route ou s'arrête suivant les ordres transmit.

    J'ai essayé pas mal de chose, comme faire un tableau dans le script python et envoyer les données une par une, mais je n'y arrive pas.

    J'ai du mal à trouver des informations là dessus, car la trame à transmettre n'est pas un message courant, d'habitude on envoi un mot ou un entier etc...

    J'avou que mon code est loin d'être un code de pro et j'avou avoir pioché des morceaux dans des tuto à droite et à gauche.

    Je passe par un système comme celui ci car je ne veux pas avoir les trames IR programmé en dur dans l'arduino car si je veux faire une petite modif j'aurais la flemme de brancher l'arduino et le reprogrammer etc... Et puis aussi par plaisir de bidouiller j'aime faire fabriquer mes trucs

    De plus je pourrais réutiliser la carte émetteur pour d'autre application, je vais me faire plus tard un système d'irrigation, un petfeeder et un truc pour changer l'eau de mes poule (faut pas que sa bug LOL) le tout commandé par domoticz avec par exemple contrôle du réservoir de graines de mes poules :p

    car oui oui j'arrive à faire porter un émetteur RF low cost à l'autre bout de la maison dans mon jardin :p

    Si jamais mon système interresse quelqu'un je peux vous montrer le câblage et le code dans son ensemble. Avec grand plaisir.

    En tout cas merci à ceux qui ont eu le courage de me lire jusqu'au bout !

    Merci d'avance pour votre aide !

    Bonne soirée !

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    Je survole ton message et je vois ça dans le code Python :
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ser = serial.Serial(
        port='/dev/ttyACM0',
        baudrate=9600,
        parity=serial.PARITY_ODD,
        stopbits=serial.STOPBITS_TWO,
        bytesize=serial.SEVENBITS
    )

    Alors que dans le code Arduino, je vois :
    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    Serial.begin(9600);

    Pourquoi avoir mis autant de paramètres en Python et pas en Arduino ?

    Ca donne quoi si tu fais ça ?
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    ser = serial.Serial(port='/dev/ttyACM0')

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Électricien
    Inscrit en
    Février 2018
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Électricien

    Informations forums :
    Inscription : Février 2018
    Messages : 15
    Points : 7
    Points
    7
    Par défaut
    Bonsoir,
    Et bien merci... J'avais eu des problème pour communiquer avec l'arduino. Et j'avais trouvé ce bout de code qui semblait fonctionner... Et ensuite j'ai vue qu'il y avait ce problème de transmission des valeurs.

    Du coup, merci beaucoup, c'était pas grand chose mais j'étais loin d'imaginé que c'était ça...

    Par curiosité, qu'elle est le paramètre qui pouvait poser problème ?

    Merci encore !

    Si jamais, penses tu que ce projet pourrais intéresser quelqu'un ? Car je pourrais en faire un tutoriel avec toutes les étapes =)

  4. #4
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 647
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 647
    Points : 11 136
    Points
    11 136
    Par défaut
    bonsoir,

    je suis surpris par le protocole série utilisé ici, qui n'est pas celui que l'on utilise habituellement pour parler à un Arduino.
    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ser = serial.Serial(
        port='/dev/ttyACM0',
        baudrate=9600,
        parity=serial.PARITY_ODD,
        stopbits=serial.STOPBITS_TWO,
        bytesize=serial.SEVENBITS

    Généralement c'est plutôt :
    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
        ser.port = '/dev/ttyACM0'  # port série de l'Arduino
        ser.baudrate = 9600
        ser.bytesize = serial.EIGHTBITS
        ser.parity = serial.PARITY_NONE
        ser.stopbits = serial.STOPBITS_ONE
        ser.xonxoff = False
        ser.rtscts = True
        ser.dsrdtr = True

    Pour la vitesse tu peux choisir ce que tu veux à partir du moment où il y a concordance entre l'émetteur et le récepteur. Par contre, c'est 8 bits de données, aucune parité et 1 bit de stop. Il faut savoir également que le flag RTS et connecté sur la borne reset des Arduino, tu dois l'activer. Et je trouve curieux que tu doives envoyer ta trame en 2 parties.

    Pour ce qui est de la vitesse : ne choisis pas la valeur de 1200 bauds. Cela provoque un reset de la carte Arduino (§ USB, Serial and Reset with the Leonardo under Linux (RPi).

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Électricien
    Inscrit en
    Février 2018
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Électricien

    Informations forums :
    Inscription : Février 2018
    Messages : 15
    Points : 7
    Points
    7
    Par défaut
    D'accord merci, c'était une question de protocole.

    Alors pourquoi j'envoie la trame en deux fois, c'est parce que lorsque je l'envoie d'un seul bloque en RF l'arduino bug, elle freeze complètement. C'est peut être une limite de la bibliothèque virtualwire.
    Étant donné que les exemples que je trouve sont souvent de petit tableau ou une petite chaîne de caractères, j'ai eu l'idée de la scinder en deux.
    Après je crois qu'il existe d'autres librairie RF mais je n'ai pas cherché.

  6. #6
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 647
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 647
    Points : 11 136
    Points
    11 136
    Par défaut
    D'accord, je comprends mieux.

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Électricien
    Inscrit en
    Février 2018
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Électricien

    Informations forums :
    Inscription : Février 2018
    Messages : 15
    Points : 7
    Points
    7
    Par défaut
    Merci pour tout

  8. #8
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Pour comprendre ces paramètres et comprendre pourquoi ça faisait n'importe quoi, il faut comprendre un peu mieux le protocole UART : https://fr.wikipedia.org/wiki/UART Une fois que tu auras lu ceci, tu devrais assez facilement comprendre les paramètres du constructeur de Serial et pourquoi la réception ne fonctionnait pas correctement Ici, tu ne configurais pas les UART de la même manière donc l'émetteur émettait un nombre avec un certain format, alors que le récepteur le recevait dans un autre format.

    Citation Envoyé par Ecko- Voir le message
    Si jamais, penses tu que ce projet pourrais intéresser quelqu'un ? Car je pourrais en faire un tutoriel avec toutes les étapes =)
    Tu peux contacter la rédaction de Developpez.com pour publier des tutoriels ici ! Envoie par un exemple un message privé à https://www.developpez.net/forums/u1105/vincent-petit/

Discussions similaires

  1. Réponses: 4
    Dernier message: 09/06/2007, 01h33
  2. Problème de Transmission de variable par url
    Par toma03 dans le forum Langage
    Réponses: 2
    Dernier message: 30/05/2007, 21h47
  3. Réponses: 4
    Dernier message: 18/04/2007, 09h16
  4. Problème dans transmission de variables dans anim
    Par baleiney dans le forum Flash
    Réponses: 1
    Dernier message: 13/08/2006, 10h26
  5. Réponses: 31
    Dernier message: 30/08/2005, 13h10

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