Ça se gère - mais ne pouvez vous pas faire sans ? Une mega doit pouvoir revenir des sms et gérer l’exécution de commandes sans problème
oui ! mais je prefere separer les commandes "volets" et "maison" pour ne pas avoir a tout refaire si je modifie
OK
effectuer une communication I2C n'est pas très compliqué. il faut définir cependant un protocole de communication
ça complexifie pas mal votre montage car vous devez gérer l'asynchronisme (que se passe-t-il si vous recevez une commande SMS alors que l'arduino esclave est occupé à faire un mouvement?)
les commandes sms ,c est moi qui ,les envoi donc j essaierais de ne pas envoyer 2 commandes a se suivrent.deja mon portail a 2 facons de s ouvrir ,une normale et une beaucoup plus grande pour passer un camping car (90°et 135 °) et il ne faut pas demarrer les 2 moteurs en meme temps!jamais eus de probleme
OK
il y a des tutos pour la configuration et communication, par exemple celui là en français (premier hit google)
il y en a plein d'autres notamment en anglais
Bonjour gicquel
Ici, je proposais un exemple de dialogue i2C entre un master et un slave avec échange de structures. Je peut t'en faire une version minimum adaptée à tes besoins.
Cordialement
jpbbricole
ok! d accord.je suis sur le site que vous m avez donné et j essaie de comprendre
oh! je crois que je n est pas repondu a la meme poersonne !bonjour jpbbricoile
Pour répondre à la bonne personne le plus simple est de cliquer sur Reply dans le bas du message auquel on répond comme ça le nom de la personne apparaît et un lien de créé vers le message en question .
bonjour comment extraire "param" ou tout au moins sa valeur a partir de # 15 pour l envoyer par IIC.passer "m1" par IIC est pas possible je crois;il y a une lettre et un chiffre.comment faire?j ai vu le site aranaCorp , j ai compris pas mal de chose.
Ce ne sont que des octets - le microprocesseur ne lit pas le message - donc ça s’envoie sans aucun souci par I2C
Il suffit de faire un
Wire.write (param, strlen(param)+1); // +1 si on veut envoyer le caractère nul de fin de chaîne
ok ! j essaie ca merci
[code]
const bool verifierAppelant = false; // à mettre à true si vous ne souhaitez que des commandes en provenance du numeroAutorise
const char* numeroAutorise = "+33610000002"; // votre numéro
// ----------------------------
// LES INTERFACES
// ----------------------------
#include <Wire.h>
const byte gsmTXpin = 14; // pin D7 vers Tx3 du SIM900
const byte gsmRXpin = 15; // pin D8 vers Rx3 du SIM900
const byte pinActivationSIM900 = 9;
// ----------------------------
// LE GSM
// ----------------------------
#define gsmSerial Serial3 // Serial3: 15 (RX) and 14 (TX croisé
const char * ctrlZcString = "\x1A";
const char * OKLongcString = "OK\r\n";
const uint32_t uneSeconde = 1000ul;
const byte tailleMaxMessage = 100;
char ligneMessageGSM[tailleMaxMessage + 1]; // +1 pour le '\0' à la fin de la c-string
char smsAEnvoyer[tailleMaxMessage + 1]; // +1 pour le '\0' à la fin de la c-string
const byte tailleMaxNumeroTel = 30;
char numeroAppelant[tailleMaxNumeroTel + 1];
#define gsmPrintATCommand(...) gsmSerial.print(__VA_ARGS__)
#define gsmPrintlnATCommand(...) gsmSerial.println(__VA_ARGS__)
#define gsmWriteATCommand(...) gsmSerial.write(__VA_ARGS__)
void erreurFatale(const char* erreur = nullptr)
{
Serial.print(F("Erreur. "));
if (erreur != nullptr) Serial.print(erreur);
Serial.println();
Serial.flush();
while (true) yield();
}
// ------------ LES COMMANDES ------------------
void activervolet(const char* param) {
Wire.beginTransmission(4);
Wire.write (param, strlen(param) + 1);
Wire.endTransmission();
}
bool executer(const char* commande, const char* param) {
bool commmandeOK = false;
Serial.print("La commande est ["); Serial.print(commande); Serial.println("]");
Serial.print("Le paramètre est ["); Serial.print(param); Serial.println("]");
if (strcmp(commande, "vol") == 0) {
Serial.println("J'ai reconnu la commande des VOLETS");
activervolet(param);
strncpy(smsAEnvoyer, "COMMANDES VOLETS OK", tailleMaxMessage);
commmandeOK = true;
}
return commmandeOK;
}
bool analyserMessage(char * message) {
bool commmandeOK = false;
char * ptrDeuxPoint = strchr(message, ':'); // on cherhce les 2 points
if (ptrDeuxPoint != nullptr) {
Serial.print("Décodage de ["); Serial.print(message); Serial.println("]");
*ptrDeuxPoint = '\0'; // on sépare en deux cString en terminant la commande
commmandeOK = executer(message, ptrDeuxPoint + 1);
} else {
Serial.print("Erreur dans la Commande ["); Serial.print(message); Serial.println("]");
}
return commmandeOK;
}
// ------------
void activerGSM() {
pinMode(pinActivationSIM900, OUTPUT);
digitalWrite(pinActivationSIM900, HIGH); // mise en route automatique SIM900.
delay(1500);
digitalWrite(pinActivationSIM900, LOW);
delay(2000);
gsmSerial.begin(9600);
}
boolean attendreChaine(const char * marqueurDeFin, unsigned long duree, boolean bavard)
{
int taille = strlen(marqueurDeFin);
char bufferLocal[taille];
int index = 0;
boolean marqueurDeFinRecu = false;
unsigned long maintenant;
memset(bufferLocal, '\0', taille);
maintenant = millis();
while (millis() - maintenant <= duree) {
if (gsmSerial.available() > 0) {
if (index == taille) index = 0;
bufferLocal[index] = (uint8_t) gsmSerial.read();
if (bavard) Serial.print((char) bufferLocal[index]);
marqueurDeFinRecu = true;
for (int i = 0; i < taille; i++) {
if (bufferLocal[(index + 1 + i) % taille] != marqueurDeFin[i]) {
marqueurDeFinRecu = false;
break;
}
}
index++;
}
if (marqueurDeFinRecu) break;
}
return marqueurDeFinRecu;
}
boolean lireUneLigneGSM() {
static byte indiceMessage = 0;
boolean messageEnCours = true;
while (gsmSerial.available() && messageEnCours) {
int c = gsmSerial.read();
if (c != -1) {
switch (c) {
case '\n':
ligneMessageGSM[indiceMessage] = '\0'; // caractère NULL de fin pour une chaîne de caractères correcte
indiceMessage = 0; // préparez-vous pour la prochaine fois
messageEnCours = false;
break;
case '\r': // ne vous souciez pas de celui-ci
break;
default:
if (indiceMessage <= tailleMaxMessage - 1) ligneMessageGSM[indiceMessage++] = (char) c; // sinon ignorez-le..
break;
}
}
}
return !messageEnCours;
}
boolean gsmPrintlnBloquant(const char * command, const char * marqueurDeFin, unsigned long duree, boolean bavard = true) {
if (bavard) Serial.println(command);
gsmSerial.println(command);
return attendreChaine(marqueurDeFin, duree, bavard);
}
boolean gsmPrintBloquant(const char * command, const char * marqueurDeFin, unsigned long duree, boolean bavard = true) {
if (bavard) Serial.print(command);
gsmSerial.print(command);
return attendreChaine(marqueurDeFin, duree, bavard);
}
void afficherReponse(uint32_t idlePeriod = 3000) {
unsigned long lastByteTime = millis();
while (millis() - lastByteTime <= idlePeriod) {
int c = gsmSerial.read();
if (c != -1) {
lastByteTime = millis();
Serial.write(c);
}
yield();
}
}
boolean envoiSMS(const char * noDeTel, const char * messageAEnvoyer) {
Serial.print(F("SMS A ENVOYER : ")); Serial.println(smsAEnvoyer);
Serial.print(F("APPELANT = [")); Serial.print(noDeTel); Serial.println(F("]"));
gsmSerial.print("AT+CMGS=\"");
gsmSerial.print(noDeTel);
gsmSerial.println("\"");
delay(200);
gsmSerial.print(messageAEnvoyer);
gsmSerial.write(26);
afficherReponse();
return true;
}
// ----------------
bool gestionMessage() {
bool commandeConnue = false; smsAEnvoyer[0] = '\0';
if (verifierAppelant && (strcmp(numeroAppelant, numeroAutorise) != 0)) {
Serial.println(F("Appelant non autorisé. Commande ignorée"));
} else {
if (analyserMessage(ligneMessageGSM)) {
Serial.println("La commande a bien été traitée");
commandeConnue = true;
} else {
Serial.println("Erreur dans la commande");
}
}
return commandeConnue;
}
// ----------------------------
// LE CODE PRINCIPAL
// ----------------------------
void setup() {
Serial.begin(9600);
activerGSM();
// on vérifie que le GSM répond bien à un AT
if (!gsmPrintlnBloquant("AT", OKLongcString, uneSeconde * 5)) erreurFatale("Erreur GPRS Modem");
// on passe les SMS en mode texte
if (!gsmPrintlnBloquant("AT+CMGF=1", OKLongcString, uneSeconde * 5)) erreurFatale("AT+CMGF");
// on passe en mode routage des SMS vers le terminal
if (!gsmPrintlnBloquant("AT+CNMI=1,2,0,0,0", OKLongcString, uneSeconde * 5)) erreurFatale("AT+CNMI"); // (normalement c'est 1,2,0,0,0)
Serial.println("Initialisation terminée. Système Prêt.");
}
void loop() {
if (lireUneLigneGSM()) {
if (!strncmp(ligneMessageGSM, "+CMT:", 5)) { //la ligne commence-t-elle par +CMT:
Serial.print(F("RECEPTION SMS = [")); Serial.print(ligneMessageGSM); Serial.println(F("]"));
const char *ptr = strchr(ligneMessageGSM + 7, '\"');
if (ptr) {
byte l = min(ptr - (ligneMessageGSM + 7), tailleMaxNumeroTel);
strncpy(numeroAppelant, ligneMessageGSM + 7, l);
numeroAppelant[l] = '\0';
Serial.print(F("Numero Appelant [")); Serial.print(numeroAppelant); Serial.println(F("]"));
} else numeroAppelant[0] = '\0';
while (!lireUneLigneGSM()); // on attend le texte du SMS
if (gestionMessage()) { // retourne vrai si la commande est connue
envoiSMS("+33610000002", smsAEnvoyer);
} else {
Serial.print(F("Commande Inconnue [")); Serial.print(ligneMessageGSM); Serial.println(F("]"));
}
} else {
Serial.print(F("LIGNE IGNOREE = [")); Serial.print(ligneMessageGSM); Serial.println(F("]"));
}
}
[/code]
AT
AT
OK
AT+CMGF=1
AT+CMGF=1
OK
AT+CNMI=1,2,0,0,0
AT+CNMI=1,2,0,0,0
OK
Initialisation terminée. Système Prêt.
LIGNE IGNOREE = []
RECEPTION SMS = [+CMT: "+33614661912","","22/01/15,11:49:15+04"]
Numero Appelant [+33614661912]
Décodage de [Vol:m1]
La commande est [Vol]
Le paramètre est [m1]
Erreur dans la commande
Commande Inconnue [Vol]
pourquoi me met il "commande inconnue"?
ou prend il la valeur de "param"?
parce que vous avez mis une majuscule et le test se fait avec "vol" en minuscule
if (strcmp(commande, "vol") == 0) {
il existe une fonction stricmp() qui comparerait sans tenir compte des majuscules mais elle n'est pas implémentée dans notre compilateur. On pourrait tout mettre en majuscule lors de la réception du SMS sinon.
le code analyse the SMS reçu, cherche le premier ':' et coupe à cet endroit puis appelle la fonction
bool executer(const char* commande, const char* param)
avec ce qui a avant le ':' comme commande
et ce qui est après le ':' comme param
ah! oui c est vrai,le smartphone met automatiquement la premiere lettre en majuscule.
pour param ,est il memorisé quelque part,dans une case
Dans param le temps de l’appel de la fonction. Une fois le traitement effectué vous ne pouvez plus trop compter dessus car le buffer est global et sert à l’écoute des infos émises par votre GPRS
peut on le stocker quelquepart le temps de s en servir?des qu il est recu ,il doit passer a la fonction qui transfere "m1" vers l uno ,apres il peut disparaitre
vous gérez sa durée de vie:
Une fois le message reçu Le code principal appelle gestionMessage()
, qui appelle analyserMessage()
(qui découpe en 2 à partir du ':' ) et appelle executer()
pour faire ce qui est nécessaire par exemple activervolet()
si c'est la commande reconnue.
soit vous mettez la communication I2C tout au bout (dans activervolet()
), soit puisque le texte à envoyer est connu, vous pourriez par exemple modifier la fonction executer()
pour envoyer param
en I2C si commmandeOK
et vrai.
void communicationI2C(const char* param) {
// ici votre connexion I2C pour envoyer param
}
bool executer(const char* commande, const char* param) {
bool commmandeOK = false;
Serial.print("La commande est ["); Serial.print(commande); Serial.println("]");
Serial.print("Le paramètre est ["); Serial.print(param); Serial.println("]");
if (strcmp(commande, "vol") == 0) {
Serial.println("J'ai reconnu la commande des VOLETS");
activervolet(param);
strncpy(smsAEnvoyer, "COMMANDES VOLETS OK", tailleMaxMessage);
commmandeOK = true;
}
if (commmandeOK) communicationI2C(param); // <==== APPEL A RAJOUTER
return commmandeOK;
}
mais comme on retourne l'info de bonne exécution à chaque appel de fonction , vous pouvez même remonter cela dans analyserMessage()
. Mais à mon avis le bon endroit c'est dans executer()
ca ca marche tres bien,mais je recois le parametre "m1" sur 2 lignes:"m" puis en dessous "1"