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 ?
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
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 -->??
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
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é.
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);
}
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());
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;
}
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