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 :

NANO - Utilisation de SoftwareSerial


Sujet :

Arduino

  1. #1
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    914
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 914
    Par défaut NANO - Utilisation de SoftwareSerial
    Bonjour à tous,

    j'aurai besoin de votre aide svp car je n'arrive pas faire fonctionner
    2 capteurs distincts
    - Sensair_S8 ( capteur CO2)
    - ZH03B ( capteur poussières)

    ces capteurs utilisent une liaison série SoftwareSerial soit :
    - SoftwareSerial ZHSerial(8, 9); // RX, TX
    - SoftwareSerial sSerial (10, 11);

    ( le port Hardware est lui utilisé pour l'écran NEXTION )

    Le problème étant que ces capteurs fonctionnent de façon indépendante
    mais dès que je les active, seul le capteur ZH03B je perds les données sur l'autre capteur
    même remarque si je fais l'inverse
    j'en déduis qu'il a un problème sur la liaison mais sans pouvoir en déterminer la cause

    je mets en copie le code
    et vous remercie par avance si vous pouviez m'expliquer comment fonctionne
    les liaisons séries sur le Nano


    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
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
     
    #include "SoftwareSerial.h"
    #include "Wire.h"
    #include <ds3231.h>
    #include <Adafruit_Sensor.h>
    #include "Adafruit_BME680.h"
    #include <SD_ZH03B.h>
     
    //*********************************************
    Adafruit_BME680 bme; // I2C
    SoftwareSerial ZHSerial(8, 9); // RX, TX
    SD_ZH03B ZH03B( ZHSerial );
    //********************************************
    SoftwareSerial sSerial (10, 11);//RX=10 TX=11 utiliser un port hardware si disponible
    const byte CO2Command[] = {0xFE, 0X04, 0X00, 0X03, 0X00, 0X01, 0XD5, 0XC5};
    byte Response[] = {0, 0, 0, 0, 0, 0, 0};
    unsigned long CO2;
    //********************************************
    struct ts t; 
     
    unsigned long dataTimer = 0;
    unsigned long dataTimer3 = 0;
    unsigned long dataTimer4 = 0;
     
    int hours;
    int minutes;
    int temp, hum;
    int pm25;
    int previousMinutes = 1;
     
    String timeString;
    String receivedData = "Z";
     
    // Nous stockons les valeurs des capteurs des 24 dernières heures dans des tableaux - stockez une valeur toutes les 15 minutes, donc pour 24 heures nous avons besoin de 96 octets.
    // Nous devons utiliser des octets et ne pouvons pas augmenter le stockage à, disons, 5 minutes, car l'Arduino Pro Mini a une mémoire dynamique limitée.
    uint8_t tempData[96] = {};
    uint8_t humData[96] = {};
    //uint8_t tvocData[96] = {};
    uint8_t co2Data[96] = {};
    uint8_t pm25Data[96] = {};
    //uint8_t o3Data[96] = {};
    int8_t r = 99;
     
    int8_t last24Hours[12] = {};
    int yAxisValues[4] = {};
    int maxV = 0;
     
    char printbuf1[80];
     
    void setup() {
        Serial.begin(9600);
        Wire.begin();
     
    	/*
        while (!Serial);
        Serial.println(F("BME680 test"));
        */ 
    	if (!bme.begin()) {
    	  Serial.println("Could not find a valid BME680 sensor, check wiring!");
    		while (1);
    	}
     
        DS3231_init(DS3231_CONTROL_INTCN);
     
        // Set up oversampling and filter initialization
    	bme.setTemperatureOversampling(BME680_OS_8X);
    	bme.setHumidityOversampling(BME680_OS_2X);
    	//bme.setPressureOversampling(BME680_OS_4X);
    	//bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
    	//bme.setGasHeater(320, 150); // 320*C for 150 ms
    	   /*
    		t.hour=11; 
    		t.min=47;
    		t.sec=0;
    		t.mday=28;
    		t.mon=9;
    		t.year=2022;
     
    		DS3231_set(t); 
    	   */
     
    	// Set up Sensair ***** 
    	sSerial.begin(9600);
        delay(100);
     
    	// Set up ZH03B  *****  
        ZHSerial.begin(9600);
        delay(100);
        ZH03B.setMode( SD_ZH03B::IU_MODE );
        delay(200);
     
    }
     
    void loop() {
     
      //************************************************************************************************ 	
      if (! bme.performReading()) {
        Serial.println("Failed to perform reading :(");
      return;
      }
      temp = bme.temperature;
      hum = bme.humidity;
     
     
      //************************************************************************************************
      //  CO2 sensor pour 3 seconds 
      dataTimer3 = millis();
      while (millis() - dataTimer3 <= 2000) {
      sSerial.write(CO2Command, 8);
      sSerial.readBytes(Response, 7); 
      while (sSerial.available()) sSerial.read();//vidage du buffer
         if (Response[0] == 254) {
          CO2 =(Response[3] * 256 + Response[4])/10;
         }
      //delay(1000);
      }
     
     
      //************************************************************************************************ 
      // Read Particulate Matter sensor for 5 seconds
      dataTimer3 = millis();
      while (millis() - dataTimer3 <= 5000) {
    	//while (ZHSerial.available()) ZHSerial.read();//vidage du buffer  
    	ZH03B.setMode( SD_ZH03B::QA_MODE );
        delay(100);  
        ZH03B.readData();
        pm25 = ZH03B.getPM2_5();
      }
     
     
      //************************************************************************************************
      DS3231_get(&t);
      hours = t.hour ;
      minutes = t.min;
     
     
     
      dataTimer4 = millis();
      while (millis() - dataTimer4 <= 200) {
     
    	Serial.print("tempV.val=");
        Serial.print(temp);
        Serial.write(0xff);
        Serial.write(0xff);
        Serial.write(0xff);
     
        Serial.print("humV.val=");
        Serial.print(hum);
        Serial.write(0xff);
        Serial.write(0xff);
        Serial.write(0xff);
     
    	Serial.print("pm25V.val=");
        Serial.print(pm25);
        Serial.write(0xff);
        Serial.write(0xff);
        Serial.write(0xff);
     
       Serial.print("co2V.val=");
        Serial.print(CO2);
        Serial.write(0xff);
        Serial.write(0xff);
        Serial.write(0xff); 
     
      }
     
    }


    pascal

  2. #2
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    13 120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 13 120
    Billets dans le blog
    47
    Par défaut
    Salut,

    Avec les ports série software, le micro ne peut lire qu'un seul port à la fois, et il faut lui indiquer quel port "écouter" avec NomDuPort.listen(). Voir la démo Two Port Receive.

    A tester, mais je pense que le souci vient de là

  3. #3
    Expert confirmé

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

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 882
    Par défaut
    C’est très certainement le bug. Si les capteurs ne répondent que quand on les interroge alors ça ira avec listen(), mais s’ils parlent en permanence ce sera un souci.

    De manière générale il faut éviter SoftwareSerial quand on peut… une MEGA ou MEGA Mini si la place est un souci serait plus adaptée

  4. #4
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    914
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 914
    Par défaut
    Merci pour vos réponses

    Effectivement çà marche mieux avec NomDuPort.listen()

    De manière générale il faut éviter SoftwareSerial quand on peu… une MEGA ou MEGA Mini si la place est un souci serait plus adaptée
    peux-tu développer stp Jay M ?
    tu penses à un Mega 2560 Pro Mini comme celui-ci ?
    https://www.amazon.fr/ARCELI-Arduino...%2C122&sr=8-15

    mais je ne comprends pas en quoi çà changerait le recours à SoftwareSerial par exemple dans le code proposé

    En tout cas
    merci mille fois

    pascal

  5. #5
    Expert confirmé

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

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 882
    Par défaut
    Software serial dépend fortement des interruptions et plus le débit est élevé ou plus le volume de data est grand et plus vous mettez du stress sur votre arduino qui passe son temps dans les interruptions aux dépends du reste du code. Ça conduit généralement à des pertes de données reçues et des instabilités.

    Ma recommandation serait au max une seule instance à 9600 bauds, pour un volume de donnée et fréquence raisonnable (par exemple une phrase NMEA d’un GPS toutes les secondes ou gestions de commandes AT simples d’un module GPRS).

    Si vous voulez plus il faut passer à des ports séries (UART) gères directement au niveau matériel. La Uno et Nano n’ont qu’un seul de ces ports mais la Mega en a 4. Vous pouvez ainsi conserver Serial pour le chargement du code et le debug et utiliser Serial1, Serial2, et Serial3 pour discuter avec des modules série. Comme c’est géré à bas niveau en matériel c’est plus efficace, vous avez un buffer dédié par port série (64 octets chacun).

    ==> si vous passez sur ce genre ude carte, vous laissez tomber SoftwareSerial et prenez Serial1 et Serial2 par exemple et votre code a de grandes chances de fonctionner directement (je ne l’ai pas lu en détail.)

  6. #6
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    914
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 914
    Par défaut
    Grand merci Jay M
    pour ces précisions

    Et un merci supplémentaire à tous pour avoir pris de votre temps
    pour me dépanner
    çà fonctionne mais comme je dois encore ajouter un capteur peut-être devrais-je changer de support
    à voir donc...

    Bonne journée

    pascal

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 10
    Dernier message: 20/03/2022, 14h32
  2. utiliser les tag [MFC] [Win32] [.NET] [C++/CLI]
    Par hiko-seijuro dans le forum Visual C++
    Réponses: 8
    Dernier message: 08/06/2005, 15h57
  3. utilisation du meta type ANY
    Par Anonymous dans le forum CORBA
    Réponses: 1
    Dernier message: 15/04/2002, 12h36
  4. [BCB5] Utilisation des Ressources (.res)
    Par Vince78 dans le forum C++Builder
    Réponses: 2
    Dernier message: 04/04/2002, 16h01
  5. Réponses: 2
    Dernier message: 20/03/2002, 23h01

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