Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

Module GSM2-Click
Jérémy
Administrateur du site
Administrateur du site
Messages : 2124
Âge : 39
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#1 Message par Jérémy » jeu. 2 juin 2016 20:10 lien vers la Data-Sheet : Cliquez ici

Bonjour à tous,

Je me lance dans un nouveau projet, celui de fabriquer une prise électrique commandée par SMS.

Celui-ci rejoindra la prise électrique Blue-tooth dans sa partie Hard , avec quand même quelques modifications coté soft et fonctionnement.

La commande sera reçue grâce à un module GSM dont voici le manuel : GMS2-Click
Le "driver" de ce module est le M95 de QuecTEL : Data-sheet
Les commandes "AT" pour LE QuecTEL m95 : Data-Sheet
Le câble de liaison est le "TTL-232R-3V3-WE" : Datasheet
Pour les tests j'utiliserai ma plaque easyPIC V7 avec un PIC18F46k22 : voici la Data-sheet

Une bonne initiation à ce module à été faite sur le BLOG de Paulfjujo .

1er Objectif allumer et communiquer avec le module .
2éme l'initialisation .
3éme test de commande envoyées et reçues !

Donc en suivant les premiers conseils, je vais commencer par alimenter mon module avec un ACCU Li-Po plus régulateur de 3.3V / 3A.
Aucune communication avec le PIC pour le moment . je branche l'alim et le Cable USB-TTL-232 pour envoyer des commandes et recevoir sur mon PC, afin de me familiariser avec la bête et le logiciel RealTERM .

Dois-je relier d'autre broches ? a Vcc ou GND par exemple ou seulement ces 4 pour commencer suivise ?
Dois-je obligatoirement mettre une SIM pour faire un simple dialogue PC-Module




Toute aide est le bienvenue car d’après ce que j'ai pus lire , ca à l'air plutôt ardu !
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Module GSM2-Click
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 1064
Âge : 68
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#2 Message par paulfjujo » jeu. 2 juin 2016 21:08 lien vers la Data-Sheet : Cliquez ici

Jérémy a écrit :
Dois-je relier d'autre broches ?


oui, la PowerKey pour faire l'init "POWER ON" et le RTS à zero
En fait la 1ere version de programme , ne fait QUE l'init hardware du module

Code : Tout sélectionner





  
//  Set PWRKEY pin to zero
  
Delay_ms(1000);
  
PWRKEY 1;             //
  
Delay_ms(5000);         // hold it at least for two seconds
  
PWRKEY 0;             // Turn ON module
  
Delay_ms(1000);
  
// Set RTS pin to zero (we will use only RX & TX)
  
RTS =0;

 





ensuite le PIC ne fait rien .. puisque c'est l'UART GSM qui est connecté au terminal
au lieu d'etre connecté au PIC..

il est peut etre possible de traiter Power Key avec un interrupteur ...
sans aucun PIC ..

Module GSM2-Click
Jérémy
Administrateur du site
Administrateur du site
Messages : 2124
Âge : 39
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#3 Message par Jérémy » jeu. 2 juin 2016 22:07 lien vers la Data-Sheet : Cliquez ici

Merci Paul pour ces indications.

J'étais mal parti déjà :lol: je n'avais aucun signe de vie avec le logiciel terminal .

J'ai donc branché le Module sur ma plaque pour le connecté au PIC afin de faire l'initialisation de l'alim comme tu me l'as préconisé !

Comme tout étair branché, je me suis dis pourquoi ne pas essayé le code example de MikroE .
J'ai donc inserer ma carte SIM , j'ai rentré mon numero de portable , la ou je pensais qu'il devait être mit !

Et j'ai testé ...... Comment dire.......


► Afficher le texte


J'arrive donc à piloter mon PORT B et D avec les mots clefs "SET" et "CLEAR" suivis du Numéro de la broche pour allumer ou éteindre une led branchée dessus .

J'en reviens pas !!!
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Module GSM2-Click
sylvain54
Avatar de l’utilisateur
Amateur
Amateur
Messages : 178
Âge : 46
Enregistré en : août 2015
Localisation : Dans l'est de la France

#4 Message par sylvain54 » ven. 3 juin 2016 08:42 lien vers la Data-Sheet : Cliquez ici

Trop simple, passe à autre chose exit

En tout cas chapeau, je ne sais pas comment vous faites pour trouver tout le temps nécessaire à faire tout ça. je rame comme un damné pour me dégager du temps libre pour mes bidouilles :cry:

Module GSM2-Click
Jérémy
Administrateur du site
Administrateur du site
Messages : 2124
Âge : 39
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#5 Message par Jérémy » ven. 3 juin 2016 09:50 lien vers la Data-Sheet : Cliquez ici

je ne sais pas comment vous faites pour trouver tout le temps nécessaire à faire tout ça

la passion l’emporte sur la raison ...... et je ne dort pas trop ....

Trop simple, passe à autre chose

Presque !!!

j'ai tout de même pas mal de question afin de bien comprendre le code, je vais traduire les commentaires en FR pour réfléchir dessus en même temps . J'ai compris pas mal de chose déjà, mais il reste quelques subtilités que je n'ai pas saisies.

Ensuite il me faut peaufiner le code , notamment pour la mise en veille car la consommation doit être réduite au max , et réveille seulement sur la réception d'un texto.
Je dois aussi rechercher , si une solution existe pour connaitre si on capte le réseau ou non . Comme allumé une led verte si on capte ou rouge si on a pas le réseau.

En tout cas Hier j'ai été complétement bluffé, de recevoir un texto m'indiquant le status de ma plaque.... et l'état de mes sorties et entrée de mon PIC .... Cela ouvre des millions de possibilité.... Commandé ses volets par SMS ; la classe !!! :-D
Mais il reste du travail
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Module GSM2-Click
sylvain54
Avatar de l’utilisateur
Amateur
Amateur
Messages : 178
Âge : 46
Enregistré en : août 2015
Localisation : Dans l'est de la France

#6 Message par sylvain54 » ven. 3 juin 2016 15:41 lien vers la Data-Sheet : Cliquez ici

la passion l’emporte sur la raison ...... et je ne dort pas trop ...


Le problème ce que je me passionne pour pas mal de chose, j'adore apprendre ...

Effectivement, ce type de carte ouvre pas mal de possibilité :wink:
Et c'est super sympa de nous faire partager.
Bonne suite.

++

Module GSM2-Click
Jérémy
Administrateur du site
Administrateur du site
Messages : 2124
Âge : 39
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#7 Message par Jérémy » sam. 4 juin 2016 14:50 lien vers la Data-Sheet : Cliquez ici

Bonjour à tous,

Alors je ne sais pas trop par où commencer ...

Déjà voici mon code traduit en français. Il s'agit du code exemples que j'ai pus trouver et qui fonctionne parfaitement !

Code : Tout sélectionner

/*
 Test du module  GSM2 click
 * Copyright: (c) MikroElektronika, 2011.

 * Description:
   Ce programme utilise le module GSM Quectel M95 pour envoyer et recevoir des SMS
   Je controle ma carte easy PIC et envoie son état par SMS .
   Je recois dans le SMS, l'état d'une broche Analogique, l'état du niveau sur le PORTB et l'état de mon PORTD

 *configuration:
     MCU:             PIC18F46K22
                      http://ww1.microchip.com/downloads/en/DeviceDoc/41412F.pdf
     Carte:           EasyPIC7
                      http://www.mikroe.com/easypic/
     Oscillateur:     HS-PLL 32.0000 MHz, 8.0000 MHz Crystal
     modules ext.:    gsm2 clickick
                      http://www.mikroe.com/click/gsm2/
                      Quectel M95
                      https://www.soselectronic.hu/a_info/resource/c/quectel/M95_ATC_V1.0.pdf
     SW:              mikroC PRO for PIC
                      http://www.mikroe.com/mikroc/pic/
 * NOTES:
     - Les SMS à envoyer au module doivent contenir les mot clef suivant :
       "Statut?" indiquant que l'on souhaite recevoir l'état de notre carte
       Si on désire modifier une broche du PORTD, on envoie le mot clef:
       Pour mettre à 1 : "Set" suivi de "RDx"  ( x = Numero de la broche ) ex " Set RD0 RD1 RD2 RD3"
       Pour mettre à 0 : "Clear" suivi de RDx  ( x = Numero de la broche ) ex " Clear RD4 RD5 RD6 RD7"
    
    -  "Set RD0 RD4 RD6 Clear RD2 RD5 Status?" fonctionne aussi .
    -  ATTENTION à la Casse
 */

// Réglages des commande "AT" de bases
const char atc0[] = "AT";                        // Toutes les commandes "AT" commance par "AT"
const char atc1[] = "ATE";
const char atc2[] = "AT+CMGF=1";                 // TXT messages
      char atc3[] = "AT+CMGS=\"";                // envoi de  SMS au numero choisi
const char atc4[] = "AT+CMGR=1";                 // Commande pour lire les messages de l'emplacement 1 de la sauvegarde
      char atc5[] = "AT+CMGD=1";                 // Efface tout les messages de la sauvegarde
const char atc6[] = "AT+CMGL=\"ALL\"";           // Vérifie l'état du SMS recu
//

// Tables des Réponses attendues
const GSM_OK                       = 0;
const GSM_Ready_To_Receive_Message = 1;
const GSM_ERROR                    = 2;
const GSM_UNREAD                   = 3;

sbit PWRKEY at RE1_bit;
sbit PWRKEY_Direction at TRISE1_bit;

char Digital_INPUT            at PORTB;   // Valeur du Port B
char Digital_INPUT_Direction  at TRISB;
char Digital_OUTPUT           at LATD;    // Valeur du Port D
char Digital_OUTPUT_Direction at TRISD;

char SMS_Message[300];  // Message composant le SMS
char ADC1_data[6];      // donnée ADC en string pour stockage
char phone_number[20];  // Numéro de téléphone en string format : {"+33680******"}
char status_req = 0;    // flag : demande de status

// Variables de controle du statut
char gsm_state = 0;
char response_rcvd = 0;
short responseID = -1, response = -1, rsp;
char set_stat = 0, clr_stat = 0;
char PORT_flag = 0;
char Digital_O = 0;
char gsm_number = 0;
char Unread_flag;

//------------------------------------------------------------------------------
// Envoi de commande ou donnée (const)
void M95_Send(const char *s){
   while(*s) {
    UART1_Write(*s++);
   }
   UART_Wr_Ptr(0x0D);   // On termine par un CR
}

// Envoi de commande ou donnée (RAM)
void M95_Send_Ram(char *s1){
   while(*s1) {
    UART_Wr_Ptr(*s1++);
   }
   UART_Wr_Ptr(0x0D);   // On termine par un CR
}


// Get GSM response, if there is any
short Get_response() {
    if (response_rcvd) {   // Si il y a une reponse ( flag levé)
      response_rcvd = 0;   // RAZ du flag
      return responseID;   // On renvoie l'identification de la réponse
    }
    else
      return 
-1;           // Sinon on renvoie -1
}

//------------------------------------------------------------------------------
// Attente de la réponse du GSM (boucle infinie)
void Wait_response(char rspns) {
char test = 1;
  
  while 
(test){
  test = Get_response();
  if ((test == rspns) || (test == GSM_ERROR))
    test = 0;
  else
    test 
= 1;
  }
}

//------------------------------------------------------------------------------
// Fonction qui compose le message du "statut"
unsigned ComposeMessage(char* Message);

//------------------------------------------------------------------------------
// Envoi du SMS "status"
void Send_Msg(char* Msg){
  char atc[33];
  
  atc
[0] = 0;                        // Initialisation du début de tableau
  strcat(atc, atc3);                 // rajoute la commande d'envoi de message(atc3) dans le tableau atc[]
  strcat(atc, phone_number);         // Rajout le numéro de téléphone   à la suite
  strcat(atc, "\"");                 // et on fini avec une commande AT
  // Ex: atc[]= "AT+CMGS=06******xx\""
  M95_Send_Ram(atc);                 // Envoi la commande pour envoyer le message
  
  Wait_response
(GSM_Ready_To_Receive_Message); // On attend que le GSM soit pret

  M95_Send_Ram(Msg);                 // Envoi du contenu du Msg
  UART_Wr_Ptr(0x1A);                 // Envoi CTRL + Z comme caractere de fin
  UART_Wr_Ptr(0x0D);                 // Envoi un  "CR"
  Wait_response(GSM_OK);             // Attente de "OK" comme confirmation que le message a été envoyé
}

// Envoi le SMS de "Statut" au numéro défini avec la commande act3
void Send_Status(){
 ComposeMessage(SMS_Message);  // Compose le message formaté
 Send_Msg(SMS_Message);        // Envoi le message
}

// Pause de 3s
void Wait(){
   Delay_ms(3000);
}

// Main
void main(){
  ANSELA = 0;             // Tous les PORT en Digital
  ANSELB = 0;
  ANSELC = 0;
  ANSELD = 0;
  ANSELE = 0;

  SLRCON = 0;             // Set output slew rate on all ports at standard rate
  
  ANSELA 
|= 0x01;         // Met la broche A0 en entrée analogique
  TRISA0_bit = 1;         // Met la broche A0 en entrée
  
  Digital_INPUT_Direction 
= 0xFF;  // PORTB en Entrée
  Digital_OUTPUT_Direction = 0;    // PORTD en sortie
  Digital_OUTPUT = 0;              // Mise à zéro des sorties

//------------------------------------------------------------------------------
// Réglages de l'interruption
  RC1IE_bit = 1;          // Enable Rx1 intterupts
  PEIE_bit = 1;           // Enable peripheral interrupts
  GIE_bit  = 1;           // Enable global interrupts

//------------------------------------------------------------------------------
//  Activation de l'alim avec la pin PWRKEY
  PWRKEY_Direction  = 0;  // PWRKEY en sortie
  PWRKEY = 0;             // Mise à zéro
  Delay_ms(2500);         // Maintenir à 0 pendant plus de 2S
  PWRKEY = 1;             // Allume le module

//------------------------------------------------------------------------------
  UART1_Init(9600);      // Initialisation de l'UART
  ADC_Init();            // Initialisation du lecteur analogique
  Delay_ms(200);

//------------------------------------------------------------------------------
// Test du baud rate
  while(1) {
    M95_Send(atc0);                 //On envoi la commande "AT" jusqu'a que le baud rate soit verifier ?
    Delay_ms(100);
    if (Get_response() == GSM_OK)   // Si le M95repond "OK" au test baud rate le programme peut continuer
      break;                        // On sort de la bocule de test baud rate
  }
  
  Wait
(); Wait();         // Attendre pour que le réseau GSM se configure

  M95_Send(atc2);        // Reglage des messages de type "texte"
  Wait_response(GSM_OK); // Attende de la réponse

  M95_Send(atc1);        // Désactivation de la commande "Echo"
  Wait_response(GSM_OK); // Attende de la réponse

//-------------------   Effacement de message   --------------------------------
while(1){
   M95_Send_Ram(atc5);           // Envoi la commande pour effacer le message en place 1 si il existe
   if (get_response() == GSM_OK) // Si la réponse est "OK" message effacé, on sort de la boucle
     break;
   Delay_ms(500);
 }

 while(1){
   atc5[8] = '2';                // On remplace le chiffre "1"(8iéme valeur du tableau) dans la commande atc5[] par 2,   ca donne char atc5[] = "AT+CMGD=2";
   M95_Send_Ram(atc5);           // On efface donc le 2ieme message
   if (get_response() == GSM_OK) // Si la réponse est "OK" message effacé, on sort de la boucle
     break;
   Delay_ms(500);
 }

 while(1){
   atc5[8] = '3';                // On remplace le chiffre "1"(8iéme valeur du tableau) dans la commande atc5[] par 3,   ca donne char atc5[] = "AT+CMGD=3";
   M95_Send_Ram(atc5);           // On efface donc le 3 ieme message)
   if (get_response() == GSM_OK) // Si la réponse est "OK" message effacé, on sort de la boucle
     break;
   Delay_ms(500);
 }

 atc5[8] = '1';                  // On remet la valeur à 1 pour revenir au 1 message
 
//------------------------------------------------------------------------------
 // Allume le PORTD pour signifier l'initialisation c'est bien passéee et finie
 Digital_OUTPUT = 0xFF;
 Delay_ms(500);
 Digital_OUTPUT = 0;



//##############################################################################
//####################### BOUCLE PRINCIPALE     ################################
//##############################################################################
  while(1) {
    M95_Send(atc6);                  // On demande si un message à été recu
    Delay_ms(100);                   // Pause

    while(1) {
      M95_Send(atc0);                // Ici on attend que le module soit pret
      Delay_ms(50);
      if (Get_response() == GSM_OK)  // Si la réponse est "OK" le module est donc pret
        break;                       // On sort de la boucle d'attente
    }

    if (Unread_flag){         // Si il y a un message non lu , suite à reception de "UNREAD" dans le buffer
    
          if 
(PORT_flag){     // Si le flag du port est levé
            PORT_flag = 0;    // On raz le flag
            Digital_Output = Digital_O; // On allume les leds du port en fonction de la valeur recue
          }

          while(1) {
            M95_Send(atc0);               // Ici on attend que le module soit pret
            Delay_ms(50);
            if (Get_response() == GSM_OK) // Si la réponse est "OK" le module est donc pret
              break;                      // On sort de la bocule d'attente
          }

          if (status_req){       // Si le drapeau de la demande de statut est lévé
            status_req = 0;      // On RAz le drapeau
            Send_Status();       // Envoyer le SMS du "Statut"
          }

          Unread_flag = 0;      // RAZ du flag non lu avant effacement des messages


          while(1){              // Boucle qui permet d'éffacer les messages qui ont été lus
            M95_Send_Ram(atc5);  // Envoi de la commande pour effacer tout les messages
            Delay_ms(50);
            if (get_response() == GSM_OK) // Si tout les messages ont été éffacés recetpion de "OK"
              break;                      // Alors on sort de la boucle
              
            Delay_ms
(50);
            
            if 
(Unread_flag){  // Si entre temps on recoit un message on sort d'ici pour le lire
              Unread_flag = 0; // RAZ du flag "non lu"
              break;           // On sort de la boucle
            }
          }
     }
    Wait();
  }
}


/*****************    Composition du message de retour   **********************/

unsigned ComposeMessage(char* Message){
  unsigned adc_value1, adc_value2;
  char temp_txt[15];
  char PORTB_temp, i, PORTD_temp;

  RC1IE_bit = 0;                // Désactive l'interruption RX1

  Message[0] = '\0';

  // SMS header
  strcat(Message, "INFO:");         // Ecrit du texte
  strcat(Message, "\r\n");          // Passe à la ligne(CR + LF)

  temp_txt[0] = 0;                 // Place un null en début de ligne
  strcat(temp_txt, "PORTB ");      // Ecrit du texte
  PORTB_temp = Digital_INPUT;      // Recopie la valeur du PORTB dans une temporaire
  for (= 0; i < 8; i ++){        // Envoie l'état du PORTB en binaire
    temp_txt[13 - i] = (PORTB_temp % 2) + 48;
    PORTB_temp = PORTB_temp / 2;
  }
  temp_txt[14] = 0;                // Fin de chaine
  strcat(Message, temp_txt);       // Rajout du txt temporaire à la suite du message
  strcat(Message, "\r\n");         // Passe à la ligne(CR + LF)

  temp_txt[0] = 0;                 // Place un null en début de ligne
  strcat(temp_txt, "PORTD ");      // Ecrit du texte
  PORTD_temp = Digital_O;          // Recopie la valeur du PORTD dans une temporaire
  for (= 0; i < 8; i ++){        // Envoie l'état du PORTD en binaire
    temp_txt[13 - i] = (PORTD_temp % 2) + 48;
    PORTD_temp = PORTD_temp / 2;
  }
  temp_txt[14] = 0;                // Fin de chaine
  strcat(Message, temp_txt);       // Rajout du txt temporaire à la suite du message
  strcat(Message, "\r\n");         // Passe à la ligne(CR + LF)

  adc_value1 = ADC_Get_Sample(0);  // Lecture de la valeur analogique sur RA0
  WordToStr(adc_value1, ADC1_data);// Conversion en chaine de caractere
  strcat(Message, "AN0 - ");       // Ecrit du texte
  strcat(Message, ADC1_data);      // Rajoute la valeur lue à la suite du message
  strcat(Message, "\r\n");         // Passe à la ligne(CR + LF)

  // SMS footer
  strcat(Message, "Fin.");        // Ecrit du texte
  strcat(Message, "\r\n");        // Passe à la ligne(CR + LF)

  RC1IE_bit = 1;                 // On reactive les interrutpions sur RX1

  return strlen(Message);        // retourne la longueur du message
}


//##############################################################################
// Lecture des données dans le buffer UART par INT
void interrupt(){
char tmp;
char i;
  if (RCIF_bit == 1) {                           // Si INT UART détecté
    tmp = UART_Rd_Ptr();                         // On récupere et stock la donnée

// Ici on analyse les réponse possibles jusqu'a trouver la bonne réponse
    switch (gsm_state) {
      case  0: {
                response = -1;                   // Clear response
                if (tmp == 'O')                  // si Nous avons un 'O', C'est peut-être le mot "OK"
                  gsm_state = 1;                 // On signale qu'on attend peut etre un 'K'
                if (tmp == '>')                  // si Nous avons un '>', C'est peut-être le mot "> "
                  gsm_state = 10;                // On signale qu'on attend peut etre un  ' '
                if (tmp == 'E')                  // si Nous avons un 'E', C'est peut-être le mot "ERROR "
                  gsm_state = 30;                // On signale qu'on attend peut etre un 'R'
                if (tmp == 'S')                  // si Nous avons un 'S', C'est peut-être le mot  "Status?" ou "Set"
                  gsm_state = 40;                // On signale qu'on attend peut etre un 't' pour le mot "Statut" sinon se sera "Set"
                if (tmp == 'R')                  // si Nous avons un 'R', C'est peut-être le mot "RDx" or
                  gsm_state = 50;                // On signale qu'on attend peut etre un 'D'
                if (tmp == 'C')                  // si Nous avons un 'C', C'est peut-être le mot "Clear"
                  gsm_state = 110;               // On signale qu'on attend peut etre un 'l'
                if (tmp == 'U')                  // si Nous avons un 'U', C'est peut-être le mot "UNREAD"
                  gsm_state = 120;               // On signale qu'on attend peut etre un 'N'
                break;
               }
      case  1: {
                if (tmp == 'K') {                // Nous avons un 'K' ->
                  response = GSM_OK;             // Donc on a "OK"
                  gsm_state = 20;                // on va faire un CR+LF
                }
                else
                  gsm_state 
= 0;                 // si après le 'O' on a pas le 'K' On retourne au départ
                break;
               }
      case 10: {
                if (tmp == ' ') {
                  response_rcvd = 1;             // Nous avons "> " response
                  response = GSM_Ready_To_Receive_Message; // Set reception flag
                  responseID = response;         // Set response ID
                }
                gsm_state = 0;                   // Reset state machine
                break;
                }

      case 20: {
                if (tmp == 13)                   // We have 13, it could be CR+LF
                  gsm_state = 21;                // Expecting LF
                else
                  gsm_state 
= 0;                 // Reset state machine
                break;
               }
      case 21: {
                if (tmp == 10) {                 // We have LF, response is complete
                  response_rcvd = 1;             // Set reception flag
                  responseID = response;         // Set response ID
                }
                gsm_state = 0;                   // Reset state machine
                break;
               }

      case 30: {
                if (tmp == 'R')                  // We have 'R', it could be "ERROR"
                  gsm_state = 31;                // Expecting 'R'
                else
                  gsm_state 
= 0;                 // Reset state machine
                break;
               }
      case 31: {
                if (tmp == 'R')                  // We have 'R', it could be "ERROR"
                  gsm_state = 32;                // Expecting 'O'
                else
                  gsm_state 
= 0;                 // Reset state machine
                break;
               }
      case 32: {
                if (tmp == 'O')                  // We have 'O', it could be "ERROR"
                  gsm_state = 33;                // Expecting 'R'
                else
                  gsm_state 
= 0;                 // Reset state machine
                break;
               }
      case 33: {
                if (tmp == 'R'){                 // We have 'R'
                  response_rcvd = 1;             // We have "ERROR" response
                  response = GSM_ERROR;          // Set reception flag
                  responseID = response;         // Set response ID
                }
                gsm_state = 0;                   // Reset state machine
                break;
                }
      case 40: {
                if (tmp == 't')                  // We have 't', it could be "Status?"
                  gsm_state = 41;                // Expecting 'a'
                else
                  if 
(tmp == 'e')                // We have 'e'. it could be "Set"
                    gsm_state = 100;
                  else
                    gsm_state 
= 0;               // Reset state machine
               }; break;
      case 41: {
                if (tmp == 'a')                  // We have 'a', it could be "Status?"
                  gsm_state = 42;                // Expecting 't'
                else
                  gsm_state 
= 0;                 // Reset state machine
                break;
               }
      case 42: {
                if (tmp == 't')                  // We have 't', it could be "Status?"
                  gsm_state = 43;                // Expecting 'u'
                else
                  gsm_state 
= 0;                 // Reset state machine
                break;
               }

       case 43: {
                if (tmp == 'u')                  // We have 'u', it could be "Status?"
                  gsm_state = 44;                // Expecting 's'
                else
                  gsm_state 
= 0;                 // Reset state machine
                break;
               }

       case 44: {
                if (tmp == 's')                  // We have 's', it could be "Status?"
                  gsm_state = 45;                // Expecting '?'
                else
                  gsm_state 
= 0;                 // Reset state machine
                break;
               }

       case 45: {
                if (tmp == '?'){                 // We have '?'
                  status_req = 1;                // Status has been requested!
                }
                gsm_state = 0;                   // Reset state machine
                break;
                }

       case 50: {
                if (tmp == 'D')                  // We have 'D', it could be "RDx"
                  gsm_state = 51;                // Expecting number
                else
                  gsm_state 
= 0;                 // Reset state machine
                break;
               }
       case 51: {
                if (tmp >= '0' && tmp <= '7'){   // We have pin number, it could be "RDx"
                  if (set_stat)
                    Digital_O |= 1 << (tmp - '0');
                  if (clr_Stat)
                    Digital_O &= (0xFF ^(<< (tmp - '0')));
                }
                  PORT_flag = 1;
                  gsm_state = 0;                 // Reset state machine
               }; break;

       case 100: {
                   if (tmp == 't'){              // We have 't', we received set command
                     set_stat = 1;               // Set following bits
                     clr_stat = 0;               // Do not clear following bits
                   }
                   gsm_state = 0;
                 }; break;
       case 110: {
                   if (tmp == 'l'){              // We have 'l', it could be Clear
                     gsm_state = 111;
                   }
                   else
                     gsm_state 
= 0;
                 }; break;
       case 111: {
                   if (tmp == 'e'){              // We have 'e', it could be Clear
                     gsm_state = 112;
                   }
                   else
                     gsm_state 
= 0;
                 }; break;
       case 112: {
                   if (tmp == 'a'){              // We have 'a', it could be Clear
                     gsm_state = 113;
                   }
                   else
                     gsm_state 
= 0;
                 }; break;
       case 113: {
                   if (tmp == 'r'){              // We have 'r', we have received Clear
                     clr_stat = 1;               // Clear following bits
                     set_stat = 0;               // Do not set following bits
                   }
                   gsm_state = 0;
                 }; break;
       case 120: {
                  if (tmp == 'N')
                    gsm_state = 121;
                  else
                    gsm_state 
= 0;
                 }; break;
       case 121: {
                  if (tmp == 'R')
                    gsm_state = 122;
                  else
                    gsm_state 
= 0;
                 }; break;
       case 122: {
                  if (tmp == 'E')
                    gsm_state = 123;
                  else
                    gsm_state 
= 0;
                 }; break;
       case 123: {
                  if (tmp == 'A')
                    gsm_state = 124;
                  else
                    gsm_state 
= 0;
                 }; break;
       case 124: {
                  if (tmp == 'D'){
                    response_rcvd = 1;             // Nous avon un message non lu
                    response = GSM_UNREAD;         // Set reception flag
                    responseID = response;         // Set response ID
                    Unread_flag = 1;               // drapeau de unread levé
                  }
                  gsm_state = 0;
                 }; break;
      default: {                                 // Si un charactere non reconnu
                gsm_state = 0;                   // On reset
               }
    }
    
    
// analyse le numéro de téléphone sur lequel on doit répondre
    switch (gsm_number) {
      case 0 :{
               if (tmp == '"'){
                 gsm_number = 1;
                 i = 0;
               }
              }; break;
      case 1 :{
               if (tmp == '+'){
                 phone_number[i] = tmp;
                 i ++;
                 gsm_number = 2;
               }
               else{
                 gsm_number = 0;
                 i = 0;
               }
              }; break;
      case 2 :{
               if (tmp >= '0' && tmp <= '9'){
                 phone_number[i] = tmp;
                 i ++;
               }
               else 
                 if 
(tmp == '"'){
                   phone_number[i] = 0;
                   i = 0;
                   gsm_number = 0;
                 }
                 else{
                   phone_number[0] = 0;
                   i = 0;
                   gsm_number = 0;
                 }
              }; break;
      default : {
                 phone_number[0] = 0;
                 i = 0;
                 gsm_number = 0;
                }
    }
 }
}
 



Je vais commencer par l'initialisation ça me parait plus cohérent . Bon on définie les constantes les variables , etc .... on met les fonctions puis on arrive dans le MAIN .
on initialise les INT, le convertisseur analogique, l'UART, l'Alim et......

PAf, on test le baud rate , et je ne comprend pas comment fonctionne cette fonction:

Code : Tout sélectionner

//------------------------------------------------------------------------------
// Test du baud rate
  while(1) {
    M95_Send(atc0);                 //On envoi la commande "AT" jusqu'a que le baud rate soit verifier ?
    Delay_ms(100);
    if (Get_response() == GSM_OK)   // Si le M95 repond "OK" au test baud rate le programme peut continuer
      break;                        // On sort de la boucle de test baud rate
  


EDIT: je pense avoir compris en décortiquant vraiment à fond

Voila ce que je crois avoir compris :


On rentre dans une boucle infinie . La seule façon d'en sortir et que la réponse soir égale à GSM_OK ( qui est une constante égale à "0").
Pour cela , on envoie une commande au M95. cette commande c'est act0, donc "AT" . cette commande "AT" d’après mes infos glané sur la toile attends une seule réponse c'est "OK"
on attend un peu ???? est ce pour laisser le temps de remplir le buffer par une réponse du M95 ?

Si pendant ces 100 ms de pause, le M95 à eu le temps normalement de renvoyer sa réponse au PIC et de la stocké dans le Buffer en écrivant un mot.

Donc si la réponse envoyé par le M95 = OK + CR + LF , alors c'est que l"on es bien à la même vitesse car on a compris le message . la réponse de Get_response() me retourne un "0" car le mot "OK"+Cr+LF à été écrit.

Je crois que c'est ça?. J'ai bon jusque la ?
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Module GSM2-Click
Jérémy
Administrateur du site
Administrateur du site
Messages : 2124
Âge : 39
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#8 Message par Jérémy » sam. 4 juin 2016 16:25 lien vers la Data-Sheet : Cliquez ici

Ok ,

Je continue alors....

Je tombe sur la partie au démarrage qui doit effacer les messages je pense .

Code : Tout sélectionner

//  Effacement de message
while(1){
   M95_Send_Ram(atc5);           // Envoi la commande pour effacer le message en place 1 si il existe
   if (get_response() == GSM_OK) // Si la réponse est "OK" message effacé, on sort de la boucle
     break;
   Delay_ms(500);
 


Je comprends :
On rentre dans une boucle infinie
On envoie la commande qui efface le message à l'index 1 : "AT+CMGD=1"; le chiffre "1" correspond à l'index de l'emplacement du message
si la réponse est OK de la part du M95, on sort et on passe à la suite , cela signifie que le message à été effacé.

Question :
==> - pourquoi n'y a t-il pas une pause de 100ms comme dans la fondation précédente , pour laisser le temps de recevoir la réponse ?
==> - Pourquoi y-a-t-il 3 messages a effacés ? et pourquoi on utilise la fonction RAM ?


Il y a aussi ca:

Code : Tout sélectionner

//------------------------------------------------------------------------------
// Envoi de commande ou donnée (const)
void M95_Send(const char *s){
   while(*
s) {
    
UART1_Write(*s++);
   }
   
UART_Wr_Ptr(0x0D);   // On termine par un CR


Une fonction qui reçoit une chaine de caractère en argument.
mais comment s’arrête la boucle while ?
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Module GSM2-Click
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 1064
Âge : 68
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#9 Message par paulfjujo » sam. 4 juin 2016 21:30 lien vers la Data-Sheet : Cliquez ici

bonsoir,



mais comment s’arrête la boucle while ?


l'argument passé à la fonction est un pointeur de string (pas la ficelle!)
un string se termine toujours par 0 (zero)
C'est ce caractere (null) specifique qui est detecté pour sortir de la boucle while

Module GSM2-Click
Jérémy
Administrateur du site
Administrateur du site
Messages : 2124
Âge : 39
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#10 Message par Jérémy » sam. 4 juin 2016 21:49 lien vers la Data-Sheet : Cliquez ici

Ah Tiens !

Mais je croyais que l’absence de test dans la boucle while , disait implicitement "== 1 " et non "==0" . Du style:
while(*s1 == 1)

Donc il faudrait détecter un "1" et pas un "0" ????

Sinon Voila 3 bonnes heures que je galère à essayer de communiquer avec le module et le terminal . Mais quelques chose ne doit pas fonctionner .

J'ai tout virer du programme initial du PIC pour ne laisser que la partie d'alimentation .

Je branche mon cable TTL/USB 3.3V sur RC6 et RC7 en prenant soin de les croiser Rx sur TX et vice versa . Je met la masse commune.
je branche ma carte easyPIC pour alimenter le module et le PIC .

Ensuite je lance terminal et j'envoie une commande AT . et j'ai rien en réponse . A force de bidouiller je recevais quelques trucs mais c’était n'importe quoi ! Alors que je pense que je devrais recevoir un "OK" .

Voici le programme du PIC :

Code : Tout sélectionner


sbit PWRKEY at RE1_bit
;
sbit PWRKEY_Direction at TRISE1_bit;


void main(){
  ANSELA = 0;             // Tous les PORT en Digital
  ANSELB = 0;
  ANSELC = 0;
  ANSELD = 0;
  ANSELE = 0;
  
  TRISA 
=  TRISB = TRISC = TRISD = TRISE = 0;
  TRISC7_bit = 1 : //RC7 en entree RX UART
  
  SLRCON 
= 0;             // Set output slew rate on all ports at standard rate

//------------------------------------------------------------------------------
//  Activation de l'alim avec la pin PWRKEY
  PWRKEY_Direction  = 0;  // PWRKEY en sortie
  PWRKEY = 0;             // Mise à zéro
  Delay_ms(2500);         // Maintenir à 0 pendant plus de 2S
  PWRKEY = 1;             // Allume le module

//##############################################################################
//####################### BOUCLE PRINCIPALE     ################################
//##############################################################################
  while(1) {

 }

}


J'ai le voyant ORANGE(STAT) qui s'allume fixe et le voyant rouge ( NET) qui clignote .
C'est en faisant des erreurs, que l'on apprend le mieux !!!


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Google [Bot] et 2 invités