probleme compilation programme dht22/arduino uno/sim900/relais

Bonjour ,

Suite à la compilation de mes deux programmes , je dois avoir un conflit sur la liaison série ( les deux programmes utilisent la bibliotheque softwareserial sur les même pin 7 et 8 )
les deux programmes fonctionnent séparement.

voici mes composant :

-dht22
-module sim900
-relais
-carte arduino uno

voici mon programme :

#include <SoftwareSerial.h>
SoftwareSerial gprsSerial(7,8);
 
#include <DHT.h> 
 
#define DHTPIN A0
 
DHT dht(DHTPIN, DHT22);

 SoftwareSerial SIM900(7, 8); // Pins 7, 8 are used as used as software serial pins

String incomingData; // for storing incoming serial data
String message = ""; // A String for storing the message
int relay_pin = 2; // Initialized a pin for relay module

void setup()
{
  gprsSerial.begin(115200);               // the GPRS baud rate   
  Serial.begin(19200);    // the GPRS baud rate 
  dht.begin();
 
  delay(1000);

 
Serial.begin(9600); // baudrate for serial monitor
SIM900.begin(9600); // baudrate for GSM shield

pinMode(relay_pin, OUTPUT); // Setting erlay pin as output pin
digitalWrite(relay_pin, HIGH); // Making relay pin initailly low

// set SMS mode to text mode
SIM900.print("AT+CMGF=1\r"); 
delay(100);

// set gsm module to tp show the output on serial out
SIM900.print("AT+CNMI=2,2,0,0,0\r"); 
delay(100);
}
void loop()
{
      float h = dht.readHumidity();
      float t = dht.readTemperature(); 
      delay(100);   
         
      Serial.print("Temperature = ");
      Serial.print(t);
      Serial.println(" °C");
      Serial.print("Humidity = ");
      Serial.print(h);
      Serial.println(" %");    
      
   
  if (gprsSerial.available())
    Serial.write(gprsSerial.read());
 
  gprsSerial.println("AT");
  delay(1000);
 
  gprsSerial.println("AT+CPIN?");
  delay(1000);
 
  gprsSerial.println("AT+CREG?");
  delay(1000);
 
  gprsSerial.println("AT+CGATT?");
  delay(1000);
 
  gprsSerial.println("AT+CIPSHUT");
  delay(1000);
 
  gprsSerial.println("AT+CIPSTATUS");
  delay(2000);
 
  gprsSerial.println("AT+CIPMUX=0");
  delay(2000);
 
  ShowSerialData();
 
  gprsSerial.println("AT+CSTT=\"orange\"");//start task and setting the APN,
  delay(1000);
 
  ShowSerialData();
 
  gprsSerial.println("AT+CIICR");//bring up wireless connection
  delay(3000);
 
  ShowSerialData();
 
  gprsSerial.println("AT+CIFSR");//get local IP adress
  delay(2000);
 
  ShowSerialData();
 
  gprsSerial.println("AT+CIPSPRT=0");
  delay(3000);
 
  ShowSerialData();
  
  gprsSerial.println("AT+CIPSTART=\"TCP\",\"api.thingspeak.com\",\"80\"");//start up the connection
  delay(6000);
 
  ShowSerialData();
 
  gprsSerial.println("AT+CIPSEND");//begin send data to remote server
  delay(4000);
  ShowSerialData();
  
  String str="GET https://api.thingspeak.com/update?api_key=xxxxxxxx&field1=" + String(t) +"&field2="+String(h);
  Serial.println(str);
  gprsSerial.println(str);//begin send data to remote server
  
  delay(4000);
  ShowSerialData();
 
  gprsSerial.println((char)26);//sending
  delay(5000);//waitting for reply, important! the time is base on the condition of internet 
  gprsSerial.println();
 
  ShowSerialData();
 
  gprsSerial.println("AT+CIPSHUT");//close the connection
  delay(100);
  ShowSerialData();


//Function for receiving sms
receive_message();

// if received command is to turn on relay
if(incomingData.indexOf("M_on")>=0)
{
digitalWrite(relay_pin, LOW);
message = "Moteur is turned ON";
// Send a sms back to confirm that the moteur is turned on
send_message(message);
}

// if received command is to turn off relay
if(incomingData.indexOf("M_off")>=0)
{
digitalWrite(relay_pin, HIGH);
message = "Moteur is turned OFF";
// Send a sms back to confirm that the moteur is turned off
send_message(message);
} 
}
void ShowSerialData()
{
  while(gprsSerial.available()!=0)
  Serial.write(gprsSerial.read());
  delay(5000); 
  
}
void receive_message()
{
if (SIM900.available() > 0)
{
incomingData = SIM900.readString(); // Get the data from the serial port.
Serial.print(incomingData); 
delay(10); 
}
}
void send_message(String message)
{
SIM900.println("AT+CMGF=1"); //Set the GSM Module in Text Mode
delay(100); 
SIM900.println("AT+CMGS=\"+xxxxxxxxxx\""); // Replace it with your mobile number
delay(100);
SIM900.println(message); // The SMS text you want to send
delay(100);
SIM900.println((char)26); // ASCII code of CTRL+Z
delay(100);
SIM900.println();
delay(1000); 
}

Est-il possible d'utiliser deux softwareserial ?
Peut-on utiliser les même cables (rx/tx/gnd) entre l'arduino et le module sim900 ?

Merci pour votre aide

Oui, instancier 2 objets SofwareSerial sur les même broches, ça ne risque pas de marcher !!

Mais que veux-tu faire ? Quel est ton schéma de branchement ?

Regardez la donc de software serial ils parlent d’utilisations multiples

En pratique si vous avez besoin de 3 ports séries, il faut envisager une autre carte. Une MEGA (ou mini MEGA si la place est restreinte) vous en propose 4

tout d'abord merci à vous pour vos réponses,

  • biggil : je souhaite envoyer les infos du capteur DHT22 sur thingspeak dans un premier temps puis avec un sms controler mon relais avec retour sms

Bonsoir

Pas besoin de deux ports série Soft pour un unique module SIM900 !!

les deux programmes fonctionnent séparement.

voici mes composant :
-dht22
-module sim900
-relais
-carte arduino uno

il me semble que les deux programmes à fusionner sont à 'harmoniser' , un seul port série série suffit pour le module SIM900 appelé gprs dans un des programmes... et SIM900 dans l'autre ....si j'ai bien compris

*J M L : j'ai trouver ça sur la doc arduino ( https://www.arduino.cc/en/Tutorial/LibraryExamples/TwoPortReceive) qu'n pense tu ? sur la uno il y a le port série numérique (sérial) 0 et 1 je pourrais surement utiliser ceux la ?
une autre question sur le module sim900 et il y a deux pin DBG TXD et DBG RXD à quoi correspondent-t-elles?(voir schéma -->??

Bonsoir

Les modules SIM900 possèdent un port série auxiliaire permettant par exemple d'y flasher un nouveau firmware.
En fonctionnement normal ne rien y raccorder


Source : notice du module SIM900 : [https://simcom.ee/documents/SIM900/SIM900_Hardware%20Design_V2.05.pdf](https://simcom.ee/documents/SIM900/SIM900_Hardware Design_V2.05.pdf)

voici mon schéma de cablage:
https://www.cjoint.com/c/JLir1Bd7W30

bonsoir alfch ,
merci pour ta participation et explication sur les pins du sim900, si j'harmonise mon code je dois donc passer en liaison série sur les pin 0 et 1 ? j'utilise donc la bibliotheque série et je retire les software serial ?

Pas du tout : mettre le module SIM900 sur un port série software, le port série matériel étant lui réservé au seul usage de la liaison USB

L'indispensable port série software , appelles-le gprsSerial(7,8) , SIM900(7,8) , mySerial(7,8), pierrev7(7,8)....ou comme tu préfères ..... Mais le l'introduit pas sous plusieurs noms dans le même programme comme c'est actuellement le cas dans le programme fusionné.

  • la copie d'écran du schéma est peu lisible

concernant les bauds rate tout le monde discute en 9600 bds?

concernant les bauds rate tout le monde discute en 9600 bds?

C'est de plus en plus rare.

En général : n'utiliser 9600 bauds que lorsque le périphérique impose cette valeur, sinon 115200 bauds est une valeur courante. la liaison Serial côté PC peut tout à fait être définie à 115200 bauds

Malheureusement SoftSerial 115200 bauds est une valeur un peu élevée pour SoftSerial sur Arduino Uno
il est prudent de prendre un peu en dessous en fonction de ce qu'accepte le SIM900

je viens de tester mon programme ,
sur mon moniteur je vois toutes les étapes et également la reception de mon sms cependant le retour sms est aléatoire et l'activation du relais également .

surement un pb de tempo ?

#include <SoftwareSerial.h>
SoftwareSerial gprsSerial(7,8);
 
#include <DHT.h> 
 
#define DHTPIN A0
 
DHT dht(DHTPIN, DHT22);

 String incomingData; // for storing incoming serial data
String message = ""; // A String for storing the message
int relay_pin = 2; // Initialized a pin for relay module

void setup()
{
  gprsSerial.begin(19200);               // the GPRS baud rate   
  Serial.begin(115200);    // the GPRS baud rate 
  dht.begin();
 
  delay(1000);

  pinMode(relay_pin, OUTPUT); // Setting erlay pin as output pin
digitalWrite(relay_pin, HIGH); // Making relay pin initailly low

// set SMS mode to text mode
gprsSerial.print("AT+CMGF=1\r"); 
delay(100);

// set gsm module to tp show the output on serial out
gprsSerial.print("AT+CNMI=2,2,0,0,0\r"); 
delay(100);
}
 
void loop()

{
      float h = dht.readHumidity();
      float t = dht.readTemperature(); 
      delay(100);   
         
      Serial.print("Temperature = ");
      Serial.print(t);
      Serial.println(" °C");
      Serial.print("Humidity = ");
      Serial.print(h);
      Serial.println(" %");    
      
   
  if (gprsSerial.available())
    Serial.write(gprsSerial.read());
 
  gprsSerial.println("AT");
  delay(1000);
 
  gprsSerial.println("AT+CPIN?");
  delay(1000);
 
  gprsSerial.println("AT+CREG?");
  delay(1000);
 
  gprsSerial.println("AT+CGATT?");
  delay(1000);
 
  gprsSerial.println("AT+CIPSHUT");
  delay(1000);
 
  gprsSerial.println("AT+CIPSTATUS");
  delay(2000);
 
  gprsSerial.println("AT+CIPMUX=0");
  delay(2000);
 
  ShowSerialData();
 
  gprsSerial.println("AT+CSTT=\"orange\"");//start task and setting the APN,
  delay(1000);
 
  ShowSerialData();
 
  gprsSerial.println("AT+CIICR");//bring up wireless connection
  delay(3000);
 
  ShowSerialData();
 
  gprsSerial.println("AT+CIFSR");//get local IP adress
  delay(2000);
 
  ShowSerialData();
 
  gprsSerial.println("AT+CIPSPRT=0");
  delay(3000);
 
  ShowSerialData();
  
  gprsSerial.println("AT+CIPSTART=\"TCP\",\"api.thingspeak.com\",\"80\"");//start up the connection
  delay(6000);
 
  ShowSerialData();
 
  gprsSerial.println("AT+CIPSEND");//begin send data to remote server
  delay(4000);
  ShowSerialData();
  
  String str="GET https://api.thingspeak.com/update?api_key=XXXXXXXXXXX&field1=" + String(t) +"&field2="+String(h);
  Serial.println(str);
  gprsSerial.println(str);//begin send data to remote server
  
  delay(4000);
  ShowSerialData();
 
  gprsSerial.println((char)26);//sending
  delay(5000);//waitting for reply, important! the time is base on the condition of internet 
  gprsSerial.println();
 
  ShowSerialData();
 
  gprsSerial.println("AT+CIPSHUT");//close the connection
  delay(100);
  ShowSerialData();
} 
void ShowSerialData()
{
  while(gprsSerial.available()!=0)
  Serial.write(gprsSerial.read());
  delay(5000); 
  



//Function for receiving sms
receive_message();

// if received command is to turn on relay
if(incomingData.indexOf("M_on")>=0)
{
digitalWrite(relay_pin, LOW);
message = "Moteur is turned ON";
// Send a sms back to confirm that the moteur is turned on
send_message(message);
}

// if received command is to turn off relay
if(incomingData.indexOf("M_off")>=0)
{
digitalWrite(relay_pin, HIGH);
message = "Moteur is turned OFF";
// Send a sms back to confirm that the moteur is turned off
send_message(message);
} 
}

void receive_message()
{
if (gprsSerial.available() > 0)
{
incomingData = gprsSerial.readString(); // Get the data from the serial port.
Serial.print(incomingData); 
delay(10); 
}
}

void send_message(String message)
{
gprsSerial.println("AT+CMGF=1"); //Set the GSM Module in Text Mode
delay(100); 
gprsSerial.println("AT+CMGS=\"+336XXXXXXXXX\""); // Replace it with your mobile number
delay(100);
gprsSerial.println(message); // The SMS text you want to send
delay(100);
gprsSerial.println((char)26); // ASCII code of CTRL+Z
delay(100);
gprsSerial.println();
delay(1000); 
}

si quelqu'un pouvait m'aider pour structurer mon programme , merci :confused:

N’utilisez pas

 incomingData = gprsSerial.readString();

Ces fonctions ne sont pas vos amies - elles incluent un blocage des flux pendant 1s par défaut après la réception du dernier caractère mais comme vous ne maîtrisez pas quand les données arrivent vraiment ou ce qui reste dans le buffer, ça peut faire n’importe quoi et recevoir seulement une partie du message.

en plus comme en début de loop vous enlevez 1 caractère s'il y en a un dans le buffer à ce moment là, ça tient ensuite du miracle si ça fonctionne...

  if (gprsSerial.available())
    Serial.write(gprsSerial.read());

Regardez mon tuto pour gérer un flux asynchrone (genre Serial ou keypad ) et appliquez la fonction qui lit une ligne à votre cas.

Merci beaucoup je vais regarder ça :slight_smile:

je viens d'essayer après une lecture attentive de votre tuto
si j'ai bien compris je transforme ma fonction receive en :

//Function for receiving sms

if (! ecouter()) {
    if (!strcmp(message, "on")) {
     digitalWrite(relay_pin, LOW);
message = "Moteur is turned ON";
// Send a sms back to confirm that the moteur is turned on
send_message(message);
}
  }

if (! ecouter()) {
    if (!strcmp(message, "off")) {
     digitalWrite(relay_pin, HIGH);
message = "Moteur is turned OFF";
// Send a sms back to confirm that the moteur is turned off
send_message(message);
}
  }

et je rajoute en déclaration :

const byte tailleMessageMax = 50;

char message[tailleMessageMax + 1]; // +1 car on doit avoir un caractère de fin de chaîne en C, le '\0'

const char marqueurDeFin = '#';

boolean ecouter()
{
  static byte indexMessage = 0; // static pour se souvenir de cette variable entre 2 appels consécutifs. initialisée qu'une seule fois.
  boolean messageEnCours = true;

  while (Serial.available() && messageEnCours) {
    int c = Serial.read();
    if (c != -1) {
      switch (c) {
        case marqueurDeFin:
          message[indexMessage] = '\0'; // on termine la c-string
          indexMessage = 0; // on se remet au début pour la prochaine fois
          messageEnCours = false;
          break;
        default:
          if (indexMessage <= tailleMessageMax - 1) message[indexMessage++] = (char) c; // on stocke le caractère et on passe à la case suivante
          break;
      }
    }
  }
  return messageEnCours;
}

Milles merci, je galere

Le marqueur de fin sera il un # dans votre cas ?

si je comprend bien les sms envoyés seront on# et off# si j'utilise # en marqueur de fin ?

oui mais vous pouvez aussi utiliser '\n' comme marqueur de fin de message (passage à la ligne) et dans ce cas votre fonction ecouter() vous retourne à chaque fois une ligne entière