Projet Balise Météo SMS808 EVB3/ Arduino Mega

Bonjour,

Voici pour le contexte quelques éléments, je suis tout à fait novice dans le monde de l'Arduino et de la programmation, j'ai décidé de me lancer dans cette aventure pour répondre à un besoin d'une association dont je suis trésorier et qui réunie des pratiquant de vol libre (parapente). Le matériel présent sur nos site de vol vieillis est les couts de maintenance sont élevés.
J ai donc envisagé de mettre en place un matériel similaire monté avec du matériel courant et moins onéreux et in-finé faire l'entretien par des bénévoles du club (moi;)).
J ai déjà lu de nombreux post similaire:
https://forum.arduino.cc/?topic=375522#msg3630338

http://www.parapentiste.info/forum/developpements-hardware-software/developper-une-balise-meteo-connectee-t49909.0.html

Aujourd'hui le matériel dont je dispose est le suivant:

Aujourd'hui je rencontre un problème .....
Pour un programme "simple": l'Arduino reçoit un message (SMS), il réponds avec les valeurs instantanées, j arrive a tout faire fonctionné sur l'Arduino UNO bien que limite en capacité de temps en temps il envois le message bien longtemps aprés ..
Tout ce complique quand je passe sur l'Arduino Mega principalement pour la communication avec la SIM808.
Sur le UNO j'utilise la bibliothéque DFRobot_Sim808 et SoftSeiral sans soucis, Sur le MEGA j ai l'impression que cette bibliothéque ne fonctionne pas.
J ai déjà bien lu à plusieurs reprise que sur le MEGA pas besoin de Softsérial car il a 3 ports série d'origine j'utilise donc le Sérial1. Mais si je supprime cette bibliothèque l'affichage du moniteur série ne me renvois que des petits carrés.
Seulement dans mon code, inspiré de mes recherches sur le net pour arriver à communiquer j ai des commandes AT. ce qui n'était pas nécessaire avec le UNO ....
Pourriez vous m'aider, j aimerais simplement comprendre comment récupérer les infos qui viennent de la SIM808 par le port série N ° 1 pour les stocker et les réutiliser, dans un premier temps le numéro de téléphone afin de pouvoir répondre.

Voici le code actuel juste pour envoyer et recevoir un SMS:

#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>

//Mobile phone number,need to change
#define PHONE_NUMBER "0677777774"  
 
//The content of messages sent
#define MESSAGE  "Pret"

DFRobot_SIM808 sim808(&Serial1);
#define MESSAGE_LENGTH 160
int messageIndex = 0;
char message[MESSAGE_LENGTH];
char phone[16];
char datetime[24];


void setup() {
  //mySerial.begin(9600);
  Serial.begin(9600);
 Serial1.begin(9600);
 Serial.println("Initializing...");
  delay(1000);
 //******** Initialize sim808 module *************
  while(!sim808.init()) {
      delay(1000);
      Serial.print("Sim808 init error\r\n");
  }  
Serial1.println("AT"); //Handshaking with SIM900
updateSerial();
Serial1.println("AT+CMGF=1"); // Configuring TEXT mode
updateSerial();
Serial1.println("AT+CNMI=1,2,0,0,0"); // Decides how newly arrived SMS messages should be handled
  updateSerial();
  Serial.println("Sim808 init success");
  Serial.println("Start to send message ...");
  //******** define phone number and text **********
  sim808.sendSMS(PHONE_NUMBER,MESSAGE); 
  Serial.println(" message envoyé...");
}

void loop() {
if (Serial1.available() > 0) {
  DFRobot_SIM808 sim808(&Serial1);
messageIndex = (sim808.isSMSunread()&Serial1);
( sim808.readSMS(messageIndex, message, MESSAGE_LENGTH, phone, datetime)&Serial1);      
      //***********In order not to full SIM Memory, is better to delete it**********
      sim808.deleteSMS(messageIndex);
      Serial.print("From number: ");
      Serial.println(phone);  
      Serial.print("Datetime: ");
      Serial.println(datetime);        
      Serial.print("Recieved Message: ");
      Serial.println(message);    
 }
}
void updateSerial()
{
  delay(500);
  while (Serial.available())
  {
    Serial1.write(Serial.read());//Forward what Serial received to Software Serial Port
  }
  while(Serial1.available())
  { 
    Serial.write(Serial1.read());//Forward what Software Serial received to Serial Port
  }
}

Merci d'avance pour votre aide.

1 : tu devrais éviter de mettre ton numéro de portable en clair sur un forum si tu ne veux pas que des petits malins t'appellent à 1 heure du matin...
2 : ton message n'est pas dans la bonne section du forum. Ici c'est pour les projets terminés, tu es un peu en avance. Demande au modo (bouton 'report to moderator') de le déplacer.
3 : Précise comment tout est connecté, notamment pour l'utilisation du port série 1 (voir ici). Sur le Méga les pins sont 19(RX), 18(TX) et il faut penser à croiser les RX et TX du module et de la carte.

Merci pour le réponse.
1 Ce n'est pas mon numéro je ne suis pas fou. j ai laissé le 06 et le 4 a la fin et remplacé tout le reste par de 7.
2 Demande au modo faite.
3 C'est bien branché comme tu le décrit TX Sim808 sur RX19 Arduino

ça se voit que ce n'est pas son numero dites le moi si vous voyez un numero avec autant de 7

Attends de voir le numéro de Lesept...

je peux le donner ? (celui où il n'y a que des 7 après le 0 ou le +33)

Non, laisse les deviner... 8)

Mais revenons à nos moutons, comme disait Jeanne d'Arc.

Il est possible que ton problème vienne de ta fonction updateserial : essaye d'en commenter tous les appels.

Sinon, si tu as un problème avec le Hardware Serial du Mega, tu peux toujours rester au Software Serial, mais attention :

Not all pins on the Mega and Mega 2560 support change interrupts, so only the following can be used for RX: 10, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), A11 (65), A12 (66), A13 (67), A14 (68), A15 (69).

Il faut choisir les pins qui fonctionnent...

Bonjour,
Merci pour le conseil, la communication entre le SIM808 EVB3 et Arduino MEGA fonctionne très bien avec la bibliothéque DFRobot_SIM808 sur les pin 11 et 12 en Softserial.
J'ai juste du inverser RX et TX par rapport au montage sur l' Arduino uno. Sur le uno le montage été le suivant:
TX sur pin 8 et RX sur pin 9 ~. Sur le MEGA TX sur pin 12 et RX sur pin 11 ~.
Je peux maintenant continuer à travailler sur le code pour un envois automatique à des heures données. Calculer la vitesse min et max sur l'intervalle de temps....
Je reviendrais vers vous si je suis encore bloqué, Merci pour votre aide.
Si vous voulez je peux vous tenir informé de l'avancement du projet.

Bonjour,

Je reviens vers vous pour vous donné des nouvelles de ce projet.
J ai réalisé une 1er version qui fonctionne plutôt bien en précision de mesure et transmission des données vers ThingSpeak. Mais bien sur vous vous en douté il y a un quand même un petit truc qui coince...
L'autonomie de cette balise est limité, j arrive a la faire fonctionner 1semaine pile poil. Après je suis obligé de recharger l'accu (12V / 13000mah) et ceci malgré le panneau solaire et de belle condition d'ensoleillement.

J ai donc décidé de réfléchir autrement pour simplifier au maximum le montage, avec juste les capteur nécessaire et en me limitant a un arduino nano donc la consumation sera déjà moins élevé qu'un MEGA.
Le montage est donc le suivant :
Arduino Nano / petit modul SIM800L / module GY-271 (compas 3 axe) et un capteur effet hall pour la vitesse du vent. Viendra peut être suivant la capacité du Nano un GY-68 (Pression et température) .
Cette foi c'est l'ensemble de la balise qui pivotera pour s'orienter face au vent est donc donné la direction et la vitesse.

J aimerais pour vraiment pouvoir resté sur un montage le plus simple utiliser l'heure fournit par le SIM800L pour envoyer les donné vers ThingSpeak. En cherchant j'ai trouver un code qui permet d'envoyer des donnés. J ai réussit a faire afficher l'heure dans le moniteur série mais je n'arrive pas à l'utiliser avec une condition IF. Par exemple, SI il est 10h00 alors envoyer vitesse et direction.

void loop() 
{
  duration = pulseIn(pin, HIGH);
  Serial.print("vitesse :");
  Serial.println(duration);
  /* Get a new sensor event */ 
  sensors_event_t event; 
  mag.getEvent(&event);

 
  float heading = atan2(event.magnetic.y, event.magnetic.x);
  
  float declinationAngle = 0.22;
  heading += declinationAngle;
  
  // Correct for when signs are reversed.
  if(heading < 0)
    heading += 2*PI;
    
  // Check for wrap due to addition of declination.
  if(heading > 2*PI)
    heading -= 2*PI;
   
  // Convert radians to degrees for readability.
  float headingDegrees = heading * 180/M_PI; 
  
  Serial.print("Heading (degrees): "); Serial.println(headingDegrees);
  
 
//sscanf (sendATcommand("AT+CCLK?\r\n", "OK\r\n", TIMEOUT, 1),"+CCLK:%*%d/%d/%d,%d:%d:%d+08%*",day,&month,&year,&minute,&second,&hour); // get time stamp from network
 (sendATcommand("AT+CCLK?\r\n", "OK\r\n", TIMEOUT, 1));
  //NOW the variables have the real time. 
  Serial.print(DATE);
  Serial.print(':');
  Serial.print(minute);
  Serial.print(':');
  Serial.print(second);
  Serial.println () ;
  

if (( hour==8) && ( minute  ==20) && ( second  >=10)&&( second  <=19) ){
    HTTPRequest();}

    
}

/////////////////////////////////////////////////////////
int8_t sendATcommand(const char* ATcommand, const char* expected_answer1, unsigned int timeout, int print_response) {

  uint8_t x = 0,  answer = 0;
  char response[100];
  unsigned long previous;

  memset(response, '\0', 100);    // Initialize the string

  delay(100);

  while (serialSIM800.available())
  { //Cleans the input buffer
    serialSIM800.read();
  }



  Serial.println(ATcommand);    // Prints the AT command
  serialSIM800.write(ATcommand); // Sends the AT command


  x = 0;
  previous = millis();

  // this loop waits for the answer
  do
  {
    ////if (Serial.available() != 0) {
    if (serialSIM800.available() != 0)
  {
      ////response[x] = Serial.read();
      response[x] = serialSIM800.read();
      x++;
      // check if the desired answer is in the response of the module
      if (strstr(response, expected_answer1) != NULL)
      {
        answer = 1;
    if (print_response == 1)
    {
      Serial.println(response);
    }
      }
    }
    // Waits for the asnwer with time out
  }
  while ((answer == 0) && ((millis() - previous) < timeout));

  return answer;
}

Le problème est dans le Voidloop:
//sscanf (sendATcommand("AT+CCLK?\r\n", "OK\r\n", TIMEOUT, 1),"+CCLK:%%d/%d/%d,%d:%d:%d+08%",day,&month,&year,&minute,&second,&hour); // get time stamp from network
(sendATcommand("AT+CCLK?\r\n", "OK\r\n", TIMEOUT, 1));
//NOW the variables have the real time.
Serial.print(hour);
Serial.print(':');
Serial.print(minute);
Serial.print(':');
Serial.print(second);
Serial.println () ;

Dans le moniteur série, la réponse a la commande AT+CCLK? et la suivante:

21:47:00.732 -> +CCLK: "21/04/07,21:46:59+08"

Bonsoir

Autonomie : autre piste ... ou piste complémentaire : utiliser les possibilités de mise en veille du SIM800L, de fonctionnement réduit à basse consommation.

J'ai un module SIM800L géré par une carte Lolin D32 LIte qui tourne depuis deux mois avec un accu Li-on d'environ 5000mAh et un petit panneau solaire (6V 200mA) plaqué contre une fenêtre orientée Ouest avec des conditions d'ensoleillement médiocres.

Dans mon cas le SIM800L reste raccordé en permanence au réseau mais n'est pleinement reveillé (par l'ESP32) que pour envoyer les données vers AdafuitIO. Les phases de réveil durent une dizaine de secondes .(connection GPRS, connection au broker du site AdafruitIO, publication)

Pour augmenter l'autonomie il est possible d'éteindre complètement le SIM800L entre les envois, mais j'ai voulu garder sous le coude la possibilité d'envoyer un au SIM800L un SMS pour lui passer des consignes.
(SMS que l'ESP32 peut découvrir à son réveil)

Je remet la main sur le code pour indiquer les commandes AT utilisées :

Quand l'envoi vers AdafruitIO ou ThingSpeak est terminé je fais
-déconnection du client Mqtt

  • -déconnection du réseau GPRS*
  • -AT+CSCLK=2 (Sleep Mode 2)*
  • -deepsleep ESP32*

Au réveil de l'ESP32 j'envoie vers le SIM800 :
-une commande AT (l'activité sur l'UART sort temporairement le SIM800 du sleepmode 2)
-attente 50ms
-une commande AT+CSCLK=0 (pour désactiver le deepsleep et rester en réveil)
*-attente 100ms *
-travail de l'ESP32.....

je n'ai pas trouvé de mode de fonctionnement consommant moins de courant tout en conservant la connection au réseau 2G (un éclat de del toutes les 2s environ) (Revers de la médaille : parfois la carte SIM reçoit un appel non désiré , le SIM800L se réveille tout seul, et il faut attendre la session ESP32 suivante pour abaisser la consommation, c'est bien visible sur la courbe de suivi de la tension de l'accu)

Bonsoir, merci pour la réponse rapide, ce sont de bonne piste en effet pour réduire la consommation. Mais la n est pas mon soucis pour le moment, j aimerais pouvoir envoyer des données a des heures précises..
Merci encore

Le code n'est pas complet donc pas facile d'aider.
Comment sont déclarées les variables hour, minute, second ? Je ne vois rien qui les met à jour dans le code que tu fournis, donc pas forcément étonnant qu'il ne se passe rien.

Que dit ceci dans la console ?

Serial.println(response);

C'est ce que tu as indiqué ?

+CCLK: "21/04/07,21:46:59+08"

Dans ce cas il faut utiliser sscanf, par exemple

sscanf (response, "+CCLK: \"%2d/%2d/%2d,%2d:%2d:%2d+08\"", &day, &month, &year, &hour, &minute, &second);

et après tu pourras afficher comme tu le fais

 Serial.print(hour);
 Serial.print(':');
 Serial.print(minute);
 Serial.print(':');
 Serial.print(second);
 Serial.println () ;

A tester...

Bonjour,

En effet c'est bien ce que j'essaye de faire.
Mais la "response" dans sérial est après analyse un peux plus compliqué puisque elle est écrite sur 3 lignes voir 4:

*10:38:11.134 -> AT+CCLK? * =>Envois de la commande
*10:38:11.134 -> *
*10:38:11.228 -> AT+CCLK? *=>Réponse à la commande
10:38:11.228 -> +CCLK: "21/04/11,10:38:10+08"
*10:38:11.275 -> *
10:38:11.275 -> OK
*10:38:11.275 -> *

J ai donc essayé avec SSCANF comme proposé mais le résultat reste :
10:38:11.275 -> 0:0:0
Voici ma phrase pour récupérer les donné de l'heure:
sscanf (response, "AT+CCLK?\n+CCLK:"%2d/%2d/%2d,%2d:%2d:%2d+08"\n\nOK", &year, &month, &day, &hour, &minute, &second);

Est ce que le "\n" correspond bien a un retour a la ligne ?

Merci pour votre aide

C'est bon !!
J ai trouvé, d'abord j ai limité la réponse a deux lignes comme vous pouvez le voir ci dessous :
(sendATcommand("AT+CCLK?\r\n", "+08"\r\n", TIMEOUT, 1));

11:12:40.820 -> AT+CCLK?
11:12:40.820 ->
11:12:40.914 -> AT+CCLK?
11:12:40.914 -> +CCLK: "21/04/11,11:12:39+08"
11:12:40.960 ->
11:12:40.960 -> 11:12:39

Ensuite j ai ajusté le SSCANF:
sscanf (response, "AT+CCLK?\r\n+CCLK: "%2d/%2d/%2d,%2d:%2d:%2d+08"\r\n", &year, &month, &day, &hour, &minute, &second);

Merci de votre aide

Il y a peut être un \r avant le \n
Pour en être sûr, tu devrais afficher les caractères contenus dans ta réponse un peu un en hexadécimal, tu verrais les codes ASCII et tu pourrais vérifier facilement.

int i =0;
while (response[i]!=0) Serial.println(response[i++], HEX);

Édit : impec, tu as trouvé tout seul !

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.