- 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 ---
Modérateur : Jérémy
-
Jérémy
Administrateur du site- Messages : 2722
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Je galère un peu ( pour ne pas dire beaucoup) à fiabiliser à 100% mon programme. Peut être est ce a cause de l'UART qu(il m'arrive parfois d'avoir des bugs inexplicables ( ou incompréhensibles pour moi).
Je cherche donc une manière de ne jamais rendre mon programme bloquant ( pas de boucle infinie). cela implique que sur chaque envoi ou attente de réponse je dois comptabiliser les boucles et si blocage soit en sortir soit carrément reseter le module.
Pour ce faire je souhaiterais créer une fonction avec du texte en paramètre d'entrée. mais je me mélange les pinceaux avec ces pointeurs.
Comme j'ai plusieurs fois le même style de dialogue une fonction me parait approprié. Partons sur un exemple simple : l'effacement des messages.
Je dois envoyer une commande à mon module GSM: AT+QMGDA="DEL ALL" suivis d'un CR
Celui une fois fait doit me répondre avec un Ok
Pour le moment j'en suis la :
Code : Tout sélectionner
//----- On efface le message (tous les messages)
i = 0;
do {
i++;
UART1_Write_Text("AT+QMGDA=\"DEL ALL\"\n");
delay_ms(100);
if (i>10) break;
} while(Ok == 0);
Je RAZ mon index
- J’exécute la boucle au moins une fois
- J’incrémente mon index pour compter le nombre de boucle
- J'envoie mon message
- j'attends 100ms afin de recevoir une réponse (le drapeau Ok se léve)
- Je regarde le nombre de boucle, si supérieur a 10 je sors a quand même ( ou je reset).
- Si je n'ai pas reçu de Ok je réessaye.
Je souhaiterais faire une fonction appelée Envoi_Commande(ma commande) par exemple, avec le texte en paramètres .
La notion de pointeur reste vraiment difficile encore pour moi !
j'ai essayé ceci sans sucés
Création d'un tableau pour enregistre le texte :
Code : Tout sélectionner
char Commande[50];
Code : Tout sélectionner
Envoi_Commande("AT+QMGDA=\"DEL ALL\"\n");
Code : Tout sélectionner
// ----------------- Envoi d'un commande -----------------------------
// Elle permet d'envoyer une commande et de s'assurer de celle ci
void Envoi_commande(*Commande){
i = Ok = 0;
do {
i++;
UART1_Write_Text(Commande);
delay_ms(100);
if (i>10) break;
} while(Ok == 0);
}
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
Code : Tout sélectionner
char Commande[50];
tableau de char en RAM
Code : Tout sélectionner
void Envoi_commande(*Commande)
{
...
tu envoies en parametre le caractere pointé par Commande,et non pas le pointeur ..
Code : Tout sélectionner
void Envoi_commande(Commande)
{
....
autre probleme:
Code : Tout sélectionner
Envoi_Commande("AT+QMGDA=\"DEL ALL\"\n");
texte en ROM (dans le programme)
exemple :
Code : Tout sélectionner
Send_Cde_display_response("AT+CREG?\r", Drapeaux.Visible);
avec texte en ROM
usage d'un cast pour sepecifier que le message est en ROM et non en RAM
Code : Tout sélectionner
void Send_Cde_display_response(const char* Cde, char B)
{
sinon utiliser prealablement
Code : Tout sélectionner
strConstRamCpy(Commande,"AT+QMGDA=\"DEL ALL\"\n");
puis
Code : Tout sélectionner
Envoi_commande(Commande);
-
Jérémy
Administrateur du site- Messages : 2722
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Entre temps j'avais réussis à faire une espèce de mixe entre l'exemple et ton explication . Mais je reste encore dans le flou, car même si mon test fonctionne plutôt bien, des fois j'ai encore des ratés , je ne comprends vraiment pas je suis a 2400bauds pourtant !
est ce normal de ne pas pouvoir être certains de la reception d'un bon caractère ?
Voila ma fonction actuelle , voyez vous des erreurs ? :
Code : Tout sélectionner
void Envoi_Commande(const char *Commande){
char j=i=Ok=0;
while(1){
while(*Commande) { // Boucle pour balayer le texte a envoyer jusqu'au "NULL"
UART_Write(*Commande++);
}
UART_Write(13); // On envoie un CR
while (Ok == 0) // Je rentre dans une boucle pour attendre la reponse "Ok"
{
delay_ms(100);
i++;
if (i>20) // Si au bout de 20 tentatives je sors pour re-envoyer la commande
{
j++;
i=0;
break;
}
}
if (j>=5) asm reset; // Au bout de 3 boucles de 20 tentatives je reset
if ((Ok) && (erreur==0) ) break;// Si j'ai recu "Ok" et sans erreur , je peux sortir
}
i = j = Ok = 0;
}
Et voici la commade qui lance ma fonction :
Code : Tout sélectionner
// ----- On efface les messages
Envoi_Commande("AT+QMGDA=\"DEL ALL\"");
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
on peut integrer le UART_Write(13) direct dans le message à envoyer
Code : Tout sélectionner
Envoi_Commande("AT+QMGDA=\"DEL ALL\"\r");
"j" me semble mal placé...pour reiterer l'envoi d'une commande
Code : Tout sélectionner
void Envoi_Commande(const char *Commande)
{
char i=j=Ok=0;
while(1)
{
while(*Commande)
{ // Boucle pour balayer le texte a envoyer jusqu'au "NULL"
UART_Write(*Commande++);
}
while (Ok == 0) // Je rentre dans une boucle pour attendre la reponse "Ok"
{
delay_ms(100);
i++;
if (i>20) // Si au bout de 20 tentatives je sors pour re-envoyer la commande
{
break;
}
}
j++;
if (j>5) asm reset; // Au bout de 5 boucles de 20 tentatives je reset
if((Ok) && (erreur==0) ) break;// Si j'ai recu "Ok" et sans erreur , je peux sortir
}
// i = j = Ok = 0;
// pas la peine de RAZER les variables, Qui sont locales dans ce cas là
// non visibles depuis le main program
}
au niveau de la machine d'etat, à la reception de "OK" ,
je bloquerai la reception pour ne pas avoir le risque de fausse detection tel
que 'E' ,'M' .. les autres caracteres detectables..de la machine d'etat
et ne reactiverait la reception que sur la commande suivante
je n'utilise pas de machine d'etat,mais un buffer de reception de 384 car,
rempli par interruption RX,
permettant largement de stocker un ou 2 SMS complet (tailla maxi SMS simple= 160 cars)
la reception etant bloquée sur debordement du buffer ou chaine specifique de caractere detectée.
Certaines commandes GSM sont tres BAVARDES : beaucoup d'info en retour !
et je pense que la solution machine d'état ne peut pas repondre aux cas litigieux..
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
on peut integrer le UART_Write(13) direct dans le message à envoyer
Code : Tout sélectionner
Envoi_Commande("AT+QMGDA=\"DEL ALL\"\r");
"j" me semble mal placé...pour reiterer l'envoi d'une commande
Code : Tout sélectionner
void Envoi_Commande(const char *Commande)
{
char i=j=Ok=0;
while(1)
{
while(*Commande)
{ // Boucle pour balayer le texte a envoyer jusqu'au "NULL"
UART_Write(*Commande++);
}
while (Ok == 0) // Je rentre dans une boucle pour attendre la reponse "Ok"
{
delay_ms(100);
i++;
if (i>20) // Si au bout de 20 tentatives je sors pour re-envoyer la commande
{
break;
}
}
j++;
if (j>5) asm reset; // Au bout de 5 boucles de 20 tentatives je reset
if((Ok) && (erreur==0) ) break;// Si j'ai recu "Ok" et sans erreur , je peux sortir
}
// i = j = Ok = 0;
// pas la peine de RAZER les variables, Qui sont locales dans ce cas là
// non visibles depuis le main program
}
au niveau de la machine d'etat, à la reception de "OK" ,
je bloquerai la reception pour ne pas avoir le risque de fausse detection tel
que 'E' ,'M' .. les autres caracteres detectables..de la machine d'etat
et ne reactiverait la reception que sur la commande suivante
je n'utilise pas de machine d'etat,mais un buffer de reception de 384 car,
rempli par interruption RX,
permettant largement de stocker un ou 2 SMS complet (tailla maxi SMS simple= 160 cars)
la reception etant bloquée sur debordement du buffer ou chaine specifique de caractere detectée.
Certaines commandes GSM sont tres BAVARDES : beaucoup d'info en retour !
et je pense que la solution machine d'état ne peut pas repondre aux cas litigieux..
test de cette cde sur mon programme:
2016-10-18 11:35:33:533_R:] HDecal= 2
[2016-10-18 11:35:33:542_R:] Delete ALL MSG ("AT+QMGDA="DEL ALL"
[2016-10-18 11:35:38:064_R:] AT+QMGDA="DEL ALL"
[2016-10-18 11:35:38:080_R:]
[2016-10-18 11:35:38:087_R:] OK
[2016-10-18 11:35:38:097_R:] Step: 5
[2016-10-18 11:35:39:588_R:] Phase d'init en 5 pas/5.. OK
[2016-10-18 11:35:41:618_R:]
[2016-10-18 11:35:41:631_R:] Constitution du SMS à envoyer
[2016-10-18 11:35:41:649_R:]
[2016-10-18 11:35:41:740_R:] Arme RX IT UART1 ..
[2016-10-18 11:35:41:763_R:] 0 EA1= 1; EA2 Now= 64;Waiting filtering ; No MCP23017;BP1=1; BP2=1; LD1=0; LD2=0;Dialog=1; SOM=0; STAT=1; DTR=0
"OK" arrive 23 ms apres la commande
liaison UART <-> GSM à 19200 bads
FOSC à 48MHz
-
Jérémy
Administrateur du site- Messages : 2722
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
J'ai essayer d'intégrer tes conseils.
Je pense après mures réflexions que mon programme est mal fichu ( pas nouveau lol) .
Ton idée de variables locales et TRES intéressantes . Mais je n'ai pas assez d’expérience la dessus c'est pourquoi je ne travaille qu'avec des variables globales pour me simplifier la vie, mais j'avoue que ce n'est pas forcement TOP et surtout peut-être la cause de mes erreurs.
Ceci m’amène quelques questions ?
Peut -on déclarer des variables locales avec le même nom que les Globales ? dans ce cas la lesquelles sont prises en compte ? car mon "i" et mon compteur temporaire que j'ai pris l'habitude de mettre un peu partout .
tu déclares 4 variables locales, mais le Ok est une variable modifier en dehors de la fonction ( dans la machine d'état) , sera-t-elle modifier ? ne risque-t-il pas d'avoir conflit ?
Merci pour ton bout de code , je l'étudie.
-
Jérémy
Administrateur du site- Messages : 2722
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Pour le moment je laisse le UART_Write(13);, car je vais oublié de mettre un \r à la fin de mon texte c'est sur .
Je également laissé les variables en globales, tant que je ne suis pas sur de ce que je fais .
Pour le moment je suis à une trentaine de texto sans aucune erreur ! je touche au BUT !
Sinon cette aprés midi au travail, j'ai pensé a tout passé en machine d'état. même les textos recus et pas seulement les réponses du modules .
cela m'aurait allonger la machine d'état, mais je pense que ca aurait été mieux au final. Car au saut de switch case reste un saut ? en terme de temps ? qu'il saute à la fin ou au début c'est pareil non ? A partir du moment ou j'ai peu de traitement dans l'INT peut importe le nombre de cas de figure possible ?
Voila ma fonction qui pour le moment fonctionne bien , je croise les doigts pour la suite .
Code : Tout sélectionner
void Envoi_Commande(const char *Commande){
j=i=Ok=Erreur=0;
while(1){
while(*Commande) { // Boucle pour balayer le texte a envoyer jusqu'au "NULL"
UART_Write(*Commande++);
}
UART_Write(13); // On envoie un CR
while ((Ok==0) && (Erreur==0)) // Je rentre dans une boucle pour attendre la reponse "Ok"
{
delay_ms(100);
i++;
if (i>20) // Si au bout de 20 tentatives je sors pour re-envoyer la commande
{
j++;
if (j>=5) asm reset; // Au bout de 3 boucles de 20 tentatives je reset
i=0;
break;
}
}
if ((Ok) && (Erreur==0) ) break;// Si j'ai recu "Ok" et sans erreur , je peux sortir
}
i=j=Ok=0;
}
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
par le fait d'ecrire
char i=j=ok=0;
sans la definition char
on reste en variable globale pour i,j et ok
mais tu pourrais conserver i et j en locale
puisque ne servent que dans la procedure
d'ou
char i=j=0; // sans le ok
au cas ou i et j serait utilsé par ailleurs..
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 64 invités