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

Coquille introuvable dans mes boucles
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#1 Message par Jérémy » lun. 17 avr. 2017 14:36

Bonjour à tous ,

JE suis toujours sur mes modules radio !

J'ai changé de stratégie pour la réception. Voici le déroulé :

Le maitre envoi un message à un esclave. Pour le moment seulement au N°1.

Plusieurs solution :
- réception d'un NON_ACK c'est à dire que le module après ces tentatives me signale qu'il n'as recu ou alors une erreur de channel . ACK =2 dans ce cas la.
- Fin du time-out, au bout de 250ms si je n'ai rien reçu du tout, je sors . ( chose normalement impossible mais par sécurité)
- réception de l'ACK . Accusé est bon le module esclave est donc à portée radio . dans ce cas ACK = 1; J'attends donc la réponse de mon module esclave quite à sa réception d'un message par le maitre.
==> Dans cette attente deux cas de figure possible :
==> Je n'ai pas de réponse au bout d'un time-out, je sors de la boucle.
==> Je reçois une bonne réponse de la part de l'esclave . La variable reponse_OK=1. je traite mes infos et je sors pour renvoyer un nouveau message etc ......

Voici un petit organigramme pour être encore plus explicite du comportement qu'il faudrait !
organigramme.pdf


Même avec un analyseur logique, je vois ou se situe l'erreur mais je ne comprends pas pourquoi elle se produit !
En bleu il s'agit de RD0 qui annonce le départ d'une communication .
En jaune l’émission de l'UART . On remarque que des que RD0 passe à 1 , j'envoie un message . tout va bien .
En vert la réception UART . On voit qu’après qu'un message soit partis je reçois un Accusé de réception, puis un message de réponse.
Le problème c'est que une fois le message de réponse reçu, le comportement n'est pas bon !!!! 3 fois sur 4 ! . Normalement RD0 devrait faire un pic à 1 après la réception d'un bon message ;

En rouge , les bonnes réponses cela devrait comme ca à chaque fois.
En violet (la flèche) indique le problème du bug
analyse.png



Et voici la partie du programme simplifiée :

Code : Tout sélectionner

//#############################################################################
//#########################     BOUCLE PRINCIPALE     #########################
//#############################################################################
 
while(1){
 
 
delay_ms(10);
 
Demande_envoi();

 }
}
//########################################################################
void Demande_envoi(){
    
char Compteur 0;  // Variable locale

    
PORTD.B0 1;
    
   
//Envoi de requete  1.95ms à 38400
    
ACK_OK 0;        // Raz du flag juste avant
    
UART_Write(0x02);  // Start
    
UART_Write(0x01);  // Commande
    
UART_Write(0x03);  // Nbe de DATA Bytes
    
UART_Write(0x6A);  // Channel
    
UART_Write(0x01);  // destination adresse
    
UART_Write(0x01);  // payload
    
UART_Write(0x6A);  // CS

    
Compteur 0;
    while(
1){
      
Compteur++;     // lancement time-out
      
delay_ms(1);
      
      if (
Compteur>50 ){    // time-out depassé
          
Compteur 0;
          
PORTD.B0 0;
              
PORTD.B5 1;  // J'allume une led pour l'indiquer
              
Delay_ms (50);
              
PORTD.B5 0;
         break;
       }
       
      if(
ACK_OK == 2){      // Si je recois un NON_ACK
          
ACK_OK 0;       // Hors de portée ou non allumé ou mauvais channel
          
PORTD.B0 0;
              
PORTD.B3 1;
              
Delay_ms (50); // J'allume une led pour le signaler
              
PORTD.B3 0;
         break;
       }
      
      if (
ACK_OK == 1){     // Si j'ai recu un bon ACK
         
ACK_OK 0;
         
Compteur 0;      // RAZ du time-out
         
Reponse_OK 0;
         
PORTD.B0 0;
            
            while(
1){       // Attente de la réponse ou time out
               
Compteur++;
               
delay_ms(1); // Lancement time-out
               
               
if (Compteur>250){
                   
PORTD.B1 1;   // J'allume une LED
                   
break;          // Je sors
                
}
                
               if (
Reponse_OK == 1){  // SI je recois une BONNE reponse
                   
Reponse_OK 0;
                   
PORTD.B0 1;
                    
delay_ms(1);
                   
PORTD.B0 0;
                         
PORTD.B4 1;     // J'allume une led
                         
Delay_ms (50);
                         
PORTD.B4 0;
                   break;                 
// Je sors
                
}
             }
         break;
       }
    };

 }

 
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Coquille introuvable dans mes boucles
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#2 Message par Jérémy » lun. 17 avr. 2017 14:59

Indice de pus :

Si j’enlève la partie time-out de la première boucle

Code : Tout sélectionner

      if (Compteur>50 ){    // time-out depassé
          Compteur = 0;
          PORTD.B0 = 0;
              PORTD.B5 = 1;  // J'allume une led pour l'indiquer
              Delay_ms (50);
              PORTD.B5 = 0;
         break;
       

Le première fonctionne bien une fois, et une seule fois, ensuite il plante . je pense que je reste bloqué dans la boucle en attente que ACK=1 ou ACK=2 ;
Ce qui veut dire que je n'ai jamais reçu d'ACK=1 ou ACK=2 .
Or l'analyseur logique me dit le contraire ! ( Si je zoom les valeurs sont bonnes).
analyseur1.jpg


Je suis perdu u ntruc de fou. Je ne sais même plus où chercher
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Coquille introuvable dans mes boucles
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#3 Message par Jérémy » lun. 17 avr. 2017 18:39

Re,

Bon voila un jour et demi que je cherche cette coquille ! je me décide à demander de l'aide .... et paf je la trouve quelques heures après !

Surtout que vous n'auriez pas pus la trouver étant donné quelle se trouvait dans ma routine d'interruptions ! Un simple else de trop et ma valeur n'était pas remise à 0.

Code : Tout sélectionner

//-----------------------          UART        -----------------------------
  if (RC1IF_bit == 1) {

     tmp = UART1_Read();      // On récupere et stock la donnée

     switch (Valeur){
        case 0:     if (tmp == 0x02){    // Start signal
                       Valeur = 1;
                       Time_out = 0;
                       TMR0IE_bit = 1;  // lancement du Time-out
                     }
                     else
                       Valeur 
= 0;
                    break;
        
                    
// Numéro de la  commande recue
        case 1:     if (tmp == 0x49)       // Commande configuration des Parametres
                       Valeur = 2;
                    else if (tmp == 0x81)  // Commande reception message
                       Valeur = 10;
                    else if (tmp == 0x44)  // reponse de passage en command MODE
                       Valeur = 20;
                    else if (tmp == 0x40)  // ACK_OK ou NON
                       Valeur = 30;
                    else
                       Valeur 
= 0;
                    break;
                    
       case 2
:     if (tmp == 0x01)    // Nombre bytes
                       Valeur = 3;
                     else
                       Valeur 
= 0;
                    break;
                    
        case 3
:     if (tmp == 0x00)   //data
                       Valeur = 4;
                     else
                       Valeur 
= 0;
                    break;
                    
        case 4
:     if (tmp == 0x4A){    // checksum 0x02 0x49 0x01 0x00 0x4A
                       Parametre_OK = 1;
                     }
                    TMR0IE_bit = 0;      // Time_out OFF
                    Valeur = 0;
                    break;
                    
        case 10
:     if (tmp = 0x03)          // Nombre de bytes
                        Valeur = 11;
                     else
                       Valeur 
= 0;
                    break;
                    
        case 11
:     if ( (tmp >=0) && (tmp <8)) {  // Identifiant du satellite
                        ID_envoyeur = tmp ;         // Stock l'identifiant de celui qui à envoyé le message
                        Valeur = 12;
                      }
                     else
                       Valeur 
= 0;
                     break;
                      
        case 12
:     if ( (tmp >=0) && (tmp <8)){   // enregistrement des Data
                        Data = tmp;
                        Valeur = 13;
                      }
                     else
                        Valeur 
= 0;
                     break;

        case 13:     RSSI = tmp;
                     Valeur = 14;
                     break;
                     
        case 14
:     if (tmp = 0x80^ID_envoyeur^Data^RSSI){   // Calcul du CS
                        Reponse_OK = 1;
                        TMR0IE_bit = 0;      // Time_out OFF
                      }
                     Valeur = 0; //             <<<<<<------- ici il y avait un else . donc ma valeur ne se mettait pas à 0, et la machine d'état ne se ré-initialisait pas.
                     break;
                     
        case 20
:    if (tmp == 0x01)
                       Valeur = 21;
                     else
                       Valeur 
= 0;
                    break;
                    
        case 21
:    if (tmp == 0x10)   // 0x10 = 16 = commade mode
                       Valeur = 22;
                     else
                       Valeur 
= 0;
                    break;
                    
        case 22
:    if (tmp == 0x57){       // chekcum de 0x02 0x44 0x01 0x10 0x57
                       Commande_Mode_OK = 1;
                       TMR0IE_bit = 0;      // Time_out OFF
                     }
                    Valeur = 0;
                    break;
                    
        case 30
:    if (tmp == 0x01)        // ACK_OK
                       Valeur = 31;
                     else
                       Valeur 
= 0;
                    break;

        case 31:    if (tmp == 0x00)        // ACK_OK
                       Valeur = 32;
                    else if (tmp == 0x01)   // ACK_NON_OK , pas de réponse
                       Valeur = 33;
                    else if (tmp == 0x02)   // ACK_NON_OK , mauvais channel
                       Valeur = 34;
                    else
                       Valeur 
= 0;
                    break;
                    
        case 32
:    if (tmp == 0x43){       // ACK_OK
                       ACK_OK = 1;          // On léve le drapeau
                       TMR0IE_bit = 0;      // Time_out OFF
                     }
                    Valeur = 0;
                    break;
                    
        case 33
:    if (tmp == 0x42){       // ACK_NON_OK
                       ACK_OK = 2;          // On léve le drapeau
                       TMR0IE_bit = 0;      // Time_out OFF
                     }
                    Valeur = 0;
                    break;
                    
        case 34
:    if (tmp == 0x41){       // ACK_NON_OK
                       ACK_OK = 2;          // On léve le drapeau
                       TMR0IE_bit = 0;      // Time_out OFF
                     }
                    Valeur = 0;
                    break;

        default:    Valeur = 0;
     }
  

Bon maintenant je vais cherche à optimiser ceci.

Je suis à 325ms pour actualiser les 8 esclaves quand ceux ci sont "connectés" . Et je suis à 875ms quand ils ne sont pas connectés !

Première idée , un Accusé de réception qui me dit qu'il n'a rien reçu est trop long . 60ms . Alors qu'un ACK bon arrive en seulement 11ms . Donc au bout de 11ms si je n'ai pas reçu de BON ACK, cela signifie que c'est mauvais par déduction . Ou alors il arrivera trop tard et ne sera pas compter tant pis !

Apres il faudrait que j'arrive a gagner un peu de temps lors de la réception d'un bon ACK .
C'est en faisant des erreurs, que l'on apprend le mieux !!!


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 35 invités