Comment gérer 2 uarts à l'aide du logiciel série Arduino Uno

j'ai essayer ce code, mais il ne fonctionne pas , je reçois tous les sms mais je ne reçois pas la localisation, je veux recevoir un sms de localisation quand la voiture est déverrouillée mais j'arrive pas à intégrer le gps dans le code, [j'utilise ARDUINO UNO , le circuit contient : RFID (lecteur RC522),GPS neo 6m,GSM SIM800L,5 Détecteurs TTP223,mini serrure 12v,relais 5v, mini buzzer ,leds, résistances.]

#include <SPI.h>
#include <MFRC522.h>
#include <SoftwareSerial.h>
#include <TinyGPS++.h>

#define SS_PIN 10
#define RST_PIN 9

MFRC522 rfid(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;

SoftwareSerial sim(3, 2); // Déclaration de sim comme variable globale
SoftwareSerial gps(A3, A2);
TinyGPSPlus gpsModule;

const int detecteur1 = A5;
const int detecteur2 = A4;
const int detecteur3 = A0;
const int detecteur4 = A1;
const int detecteur5 = 5;
const int ledvert = 8;
const int ledrouge = 4;
const int buzzer = 7;
const int relayPin = 6 ;

int etatPrecedentdetecteur1 = LOW;
int etatPrecedentdetecteur2 = LOW;
int etatPrecedentdetecteur3 = LOW;
int etatPrecedentdetecteur4 = LOW;
int etatPrecedentdetecteur5 = LOW;

String lastKnownLocation = "";

void setup() {
  pinMode(detecteur1, INPUT);
  pinMode(detecteur2, INPUT);
  pinMode(detecteur3, INPUT);
  pinMode(detecteur4, INPUT);
  pinMode(detecteur5, INPUT);
  pinMode(ledvert, OUTPUT);
  pinMode(ledrouge, OUTPUT);
  pinMode(buzzer, OUTPUT);
  pinMode(relayPin, OUTPUT); 

  Serial.begin(9600);
  sim.begin(9600);
  gps.begin(9600);

  SPI.begin();
  rfid.PCD_Init();

  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF;
  }

  Serial.println(F("Utilisation de la clé suivante :"));
}

void loop() {
  int etatDetecteur1 = digitalRead(detecteur1);
  int etatDetecteur2 = digitalRead(detecteur2);
  int etatDetecteur3 = digitalRead(detecteur3);
  int etatDetecteur4 = digitalRead(detecteur4);
  int etatDetecteur5 = digitalRead(detecteur5);

  sim.listen();
  
  if (sim.isListening()) {
      Serial.println("sim800l is listening!");
  } else {
      Serial.println("sim800l is not listening!");
  }

  if (gps.isListening()) {
      Serial.println("gps is listening!");
  } else {
      Serial.println("gps is not listening!");
  }

  // Vérification des détecteurs
  if (etatDetecteur1 == HIGH || etatDetecteur2 == HIGH || etatDetecteur3 == HIGH || etatDetecteur4 == HIGH) {
    for (int i = 0; i < 3; i++) {
      digitalWrite(ledrouge, HIGH);      // Allume la LED rouge
      delay(300);
      digitalWrite(ledrouge, LOW);       // Éteint la LED rouge
      tone(buzzer, 1000);                // Émet un son avec le buzzer
      delay(300);                       // Pendant 300 ms
      noTone(buzzer);                   // Arrête le son
      delay(300);                       // Attend 300 ms
    }
    sendSMS("QUELQU'UN TOUCHE LES PORTES DE LA VOITURE!");
  } else {
    etatPrecedentdetecteur1 = LOW;
    etatPrecedentdetecteur2 = LOW;
    etatPrecedentdetecteur3 = LOW;
    etatPrecedentdetecteur4 = LOW;
  }

  // Réinitialisation du module SIM800L
  sim.println("ATZ");
  delay(1000);

  // Vérification du détecteur 5
  if (etatDetecteur5 == HIGH ) {
    for (int i = 0; i < 3; i++) {
      digitalWrite(ledrouge, HIGH);      // Allume la LED rouge
      delay(300);
      digitalWrite(ledrouge, LOW);       // Éteint la LED rouge
      tone(buzzer, 1000);                // Émet un son avec le buzzer
      delay(300);                       // Pendant 300 ms
      noTone(buzzer);                   // Arrête le son
      delay(300);                       // Attend 300 ms
    }
    sendSMS("QUELQU'UN TOUCHE LA CAMERA DE RECULE DE LA VOITURE!");
  } else {
    etatPrecedentdetecteur5 = LOW;
  }

  // Réinitialisation du module SIM800L
  sim.println("ATZ");
  delay(1000);

  // Vérification de la présence d'une carte RFID
  if (!rfid.PICC_IsNewCardPresent()) {
    return;
  }

  if (!rfid.PICC_ReadCardSerial()) {
    return;
  }

  Serial.print(F("Type PICC : "));
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  Serial.println(rfid.PICC_GetTypeName(piccType));

  if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI && piccType != MFRC522::PICC_TYPE_MIFARE_1K && piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
    Serial.println(F("Votre carte n'est pas de type MIFARE Classic."));
    return;
  }

  byte nuidPICC[4];
  for (byte i = 0; i < 4; i++) {
    nuidPICC[i] = rfid.uid.uidByte[i];
  }

  while (gps.available() > 0) {
    if (gpsModule.encode(gps.read())) {
      displayInfo();
    }
  }

  if (nuidPICC[0] == 0x13 && nuidPICC[1] == 0xD6 && nuidPICC[2] == 0x49 && nuidPICC[3] == 0x10) {
    digitalWrite(ledvert, HIGH);
    digitalWrite(buzzer, HIGH);
    delay(500);
    digitalWrite(ledvert, LOW);
    digitalWrite(buzzer, LOW);
    digitalWrite(relayPin, HIGH); // Active le relais pour ouvrir la serrure
    delay(2000);  // Délai pour éviter la répétition des messages
    digitalWrite(relayPin, LOW);
    sendSMS("LA VOITURE EST DEVERROUILLEE. Localisation: " + lastKnownLocation);
    delay(5000);
  } else {
    for (int i = 0; i < 5; i++) {
      digitalWrite(ledrouge, HIGH);
      delay(300);
      digitalWrite(ledrouge, LOW);
      tone(buzzer, 950);
      delay(300);
      noTone(buzzer);
      delay(300);
    }
    digitalWrite(relayPin, LOW); // Désactive le relais pour fermer la serrure
    delay(2000);
    sendSMS("QUELQU'UN ESSAIE DE DEVERROUILLER LA VOITURE!");
    delay(5000);
  }

  rfid.PICC_HaltA();
  rfid.PCD_StopCrypto1();
}

void sendSMS(String message) {
  sim.println("AT");
  delay(1000);
  if (sim.find("OK")) {
    Serial.println("AT OK");
  } else {
    Serial.println("AT Error");
    return;
  }

  sim.println("AT+CMGF=1");
  delay(1000);
  if (sim.find("OK")) {
    Serial.println("AT+CMGF=1 OK");
  } else {
    Serial.println("AT+CMGF=1 Error");
    return;
  }

  sim.print("AT+CMGS=\"+\"");
  sim.write(0x0D);
  delay(1000);
  sim.write(0x0A);
  delay(1000);
  sim.print(message);
  sim.write(0x1A);
  delay(1000);
}

void displayInfo() {
  if (gpsModule.location.isValid()) {
    lastKnownLocation = String(gpsModule.location.lat(), 6) + ", " + String(gpsModule.location.lng(), 6);
  } else {
    lastKnownLocation = "Localisation indisponible";
  }
}

Post mis dans la mauvaise section, on parle anglais dans les forums généraux, je viens de déplacer le post dans la section francophone.

Merci de prendre en compte les recommandations listées dans "Les bonnes pratiques du Forum Francophone".

1 Like

Il faudrait que tu lises comme tu l'a indiqué @pert les bonnes pratiques de la partie francaise.
Cela nous aiderez à t'aider :slight_smile:

➜ donc avant tout autre discussion et après avoir lu les bonnes pratiques, cliquer sur le petit crayon qui est sous votre premier post et rajouter les balises de code.

Merci de nous aider à conserver le forum lisible.


ensuite on vous parlera de

merci a tous,j'ai modifier mon message.

quel arduino utilisez vous ?
quel est le circuit ?

j'utilise ARDUINO UNO , le circuit contient : RFID (lecteur RC522),GPS neo 6m,GSM SIM800L,5 Détecteurs TTP223,mini serrure 12v,relais 5v, mini buzzer ,leds, résistances.

l'usage des 2 port SoftwareSerial est quasiment impossible

ici en plus vous ne faites qu'un

et donc le port SoftwareSerial n'écoute jamais le GPS.

vous ne pouvez pas vraiment écouter de temps en temps le GPS car il balance des trames en permanence donc si vous intérrompez l'écoute, vous perdrez des données.

➜ passez sur une MEGA (ou MEGA Mini) ou un ESP32 et utilisez plusieurs UART "physiques" (matérielles)

Je ne peux pas continuer à utiliser Arduino uno et modifier le code de sorte qu’il fonctionne ?

Pour recevoir les SMS vous devez être constamment à l'écoute du port série SMS
Pour recevoir une trame du GPS complète il faut écouter pendant un moment (et le GPS balance des trames toutes les secondes)

Vous ne pouvez pas avoir 2 port SoftwareSerial actifs à la fois.

➜ avez vous besoin du moniteur série ?

si vous pouvez vous en passer, vous pourriez affecter le port série matériel à un des deux modules et n'avoir qu'un seul SoftwareSerial pour l'autre

Bien sûr il faudrait un autre moyen de communiquer alors avec l'utilisateur.

Non j’en n’ai pas besoin de serial monitor, donc ce n’est pas possible de réaliser ce que je veux ?

Si, si vous n’utilisez pas la console série pour afficher des choses alors c’est possible

un des appareils peut être connecté sur les pins 0 et 1 (à débrancher pendant que vous faites l’upload dun code) et l’autre utilisé SoftwareSerial.

(Assurez vous aussi de partager les GND)

Mais donc plus possible de faire des trucs comme

Donc je supprime tous les instructions ((serial.print.ln)) et je branche le gps au pins 0/1 (tx/rx) ? Et je garde le même code ?

Oui (et le GND - et vous vous assurez que votre GPS travaille en 5V)

Mais Vous remplacez

Par

#define gps Serial

Pour que partout où vous utilisiez la variable gps ce soit maintenant Serial qui soit utilisé

jai essayer mais ca na pas marcher, je ne recois aucun sms

Postez le code

#include <SPI.h>
#include <MFRC522.h>
#include <SoftwareSerial.h>
#include <TinyGPS++.h>

#define SS_PIN 10
#define RST_PIN 9

MFRC522 rfid(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;

SoftwareSerial sim(3, 2); // Déclaration de sim comme variable globale
#define gps Serial
TinyGPSPlus gpsModule;

const int detecteur1 = A5;
const int detecteur2 = A4;
const int detecteur3 = A0;
const int detecteur4 = A1;
const int detecteur5 = 5;
const int ledvert = 8;
const int ledrouge = 4;
const int buzzer = 7;

int etatPrecedentdetecteur1 = LOW;
int etatPrecedentdetecteur2 = LOW;
int etatPrecedentdetecteur3 = LOW;
int etatPrecedentdetecteur4 = LOW;
int etatPrecedentdetecteur5 = LOW;

String lastKnownLocation = "";

void setup() {
  pinMode(detecteur1, INPUT);
  pinMode(detecteur2, INPUT);
  pinMode(detecteur3, INPUT);
  pinMode(detecteur4, INPUT);
  pinMode(detecteur5, INPUT);
  pinMode(ledvert, OUTPUT);
  pinMode(ledrouge, OUTPUT);
  pinMode(buzzer, OUTPUT); 

  Serial.begin(9600);
  sim.begin(9600);
  gps.begin(9600);

  SPI.begin();
  rfid.PCD_Init();

  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF;
  }
}

void loop() {
  int etatDetecteur1 = digitalRead(detecteur1);
  int etatDetecteur2 = digitalRead(detecteur2);
  int etatDetecteur3 = digitalRead(detecteur3);
  int etatDetecteur4 = digitalRead(detecteur4);
  int etatDetecteur5 = digitalRead(detecteur5);

  sim.listen();

  // Vérification des détecteurs
  if (etatDetecteur1 == HIGH || etatDetecteur2 == HIGH || etatDetecteur3 == HIGH || etatDetecteur4 == HIGH) {
    for (int i = 0; i < 3; i++) {
      digitalWrite(ledrouge, HIGH);      // Allume la LED rouge
      delay(300);
      digitalWrite(ledrouge, LOW);       // Éteint la LED rouge
      tone(buzzer, 1000);                // Émet un son avec le buzzer
      delay(300);                       // Pendant 300 ms
      noTone(buzzer);                   // Arrête le son
      delay(300);                       // Attend 300 ms
    }
    sendSMS("QUELQU'UN TOUCHE LES PORTES DE LA VOITURE!");
  } else {
    etatPrecedentdetecteur1 = LOW;
    etatPrecedentdetecteur2 = LOW;
    etatPrecedentdetecteur3 = LOW;
    etatPrecedentdetecteur4 = LOW;
  }

  // Réinitialisation du module SIM800L
  sim.println("ATZ");
  delay(1000);

  // Vérification du détecteur 5
  if (etatDetecteur5 == HIGH ) {
    for (int i = 0; i < 3; i++) {
      digitalWrite(ledrouge, HIGH);      // Allume la LED rouge
      delay(300);
      digitalWrite(ledrouge, LOW);       // Éteint la LED rouge
      tone(buzzer, 1000);                // Émet un son avec le buzzer
      delay(300);                       // Pendant 300 ms
      noTone(buzzer);                   // Arrête le son
      delay(300);                       // Attend 300 ms
    }
    sendSMS("QUELQU'UN TOUCHE LA CAMERA DE RECULE DE LA VOITURE!");
  } else {
    etatPrecedentdetecteur5 = LOW;
  }

  // Réinitialisation du module SIM800L
  sim.println("ATZ");
  delay(1000);

  // Vérification de la présence d'une carte RFID
  if (!rfid.PICC_IsNewCardPresent()) {
    return;
  }

  if (!rfid.PICC_ReadCardSerial()) {
    return;
  }

  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);

  if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI && piccType != MFRC522::PICC_TYPE_MIFARE_1K && piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
    return;
  }

  byte nuidPICC[4];
  for (byte i = 0; i < 4; i++) {
    nuidPICC[i] = rfid.uid.uidByte[i];
  }

  while (gps.available() > 0) {
    if (gpsModule.encode(gps.read())) {
      displayInfo();
    }
  }

  if (nuidPICC[0] == 0x13 && nuidPICC[1] == 0xD6 && nuidPICC[2] == 0x49 && nuidPICC[3] == 0x10) {
    digitalWrite(ledvert, HIGH);
    digitalWrite(buzzer, HIGH);
    delay(500);
    digitalWrite(ledvert, LOW);
    digitalWrite(buzzer, LOW);
    sendSMS("LA VOITURE EST DEVERROUILLEE. Localisation: " + lastKnownLocation);
    delay(5000);
  } else {
    for (int i = 0; i < 5; i++) {
      digitalWrite(ledrouge, HIGH);
      delay(300);
      digitalWrite(ledrouge, LOW);
      tone(buzzer, 950);
      delay(300);
      noTone(buzzer);
      delay(300);
    }
    sendSMS("QUELQU'UN ESSAIE DE DEVERROUILLER LA VOITURE!");
    delay(5000);
  }

  rfid.PICC_HaltA();
  rfid.PCD_StopCrypto1();
}

void sendSMS(String message) {
  sim.println("AT");
  delay(1000);
  if (sim.find("OK")) {
  } else {
    return;
  }

  sim.println("AT+CMGF=1");
  delay(1000);
  if (sim.find("OK")) {
  } else {
    return;
  }

  sim.print("AT+CMGS=\"+213799481879\"");
  sim.write(0x0D);
  delay(1000);
  sim.write(0x0A);
  delay(1000);
  sim.print(message);
  sim.write(0x1A);
  delay(1000);
}

void displayInfo() {
  if (gpsModule.location.isValid()) {
    lastKnownLocation = String(gpsModule.location.lat(), 6) + ", " + String(gpsModule.location.lng(), 6);
  } else {
    lastKnownLocation = "Localisation indisponible";
  }
} 

il faut virer


mais le souci n'est pas là. Je pense qu'un des souci est dans vos délais qui trainent un peu partout....

tous ces délais empêchent de recevoir correctement la trame GPS. le buffer ne contient que 64 caractères et la trame GPS arrive à 960 caractères par secondes....

vous devez écrire un code sans delay.

donc je supprime les deux instructions, et pour les delay je ne pense pas que le code fonctionne sans eux car j'evite la répétitions d'envois de messages

oui il faut traiter cela différemment.

le version "simpliste" consisterait à écrire une fonction delay() perso qui vérifie s'il y a des communications du GPS pour ne pas les perdre pendant l'attente

une "bonne" version serait de restructurer le code sous forme de machine à états par exemple pour n'avoir aucun délai