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

Calculez un checksum avec un tableau de char ?
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 » mar. 2 janv. 2018 01:44 lien vers la Data-Sheet : Cliquez ici

Bonsoir,

Je n'arrive pas a envoyer un message par voie radio car le Cheksum est faux !

Je dois envoyer un premier lieu un 0x02 qui est le start byte.
Ensuite 0x00 qui est le mode 0 .( le plus simple)
Ensuite un chiffre qui est le nombre de data qui vont être envoyées.

Suivis d'un checksum qui est un XOR de toute cette trame .

Moi; je souhaiterais envoyer un tableau de char en tant que data. Mais ca ne fonctionne pas, j'ai essayé beaucoup de possibilités au petit bonheur la chance sans succès.


Code : Tout sélectionner



 char txt
[4];
---
---
---
txt[0] = txt[1] = txt[2] = txt[3] = 0;

    //Envoi d'un message
       UART1_Remappable_Write(0x02);             // Start
       UART1_Remappable_Write(0x00);             // Commande
       UART1_Remappable_Write(0x04);             // Nbe de DATA
       UART1_Remappable_Write_Text(txt);         // DATA
       UART1_Remappable_Write(0x02^0x00^0x04^0x00^0x00^0x00^0x00);   //CS
       


Mais un tableau y'a pas forcement un " \0" ? donc si txtest un tableau de 4 char , je vais envoyer mes 4 char ? donc 4 données ? mais ça ne fonctionne pas
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Calculez un checksum avec un tableau de char ?
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#2 Message par satinas » mar. 2 janv. 2018 02:22 lien vers la Data-Sheet : Cliquez ici

La fonction UART_Write_text() envoie une chaine (sans le 0 final), pas un tableau de caracteres. Dans ton cas, elle envoie rien car la chaine est vide. Une fonction envoyant un tableau sera du genre :
void write(char *s, int size)
car la fonction ne connait pas la taille du tableau, il faut lui donner.

Calculez un checksum avec un tableau de char ?
pspic
Passioné
Passioné
Messages : 357
Âge : 77
Enregistré en : septembre 2017
Localisation : 68

#3 Message par pspic » mar. 2 janv. 2018 08:10 lien vers la Data-Sheet : Cliquez ici

Bonjour,
Ne faut il pas terminer la trame avec un End of text 0x03 ?
Essaye de ne pas compter le 0x02 et 0x03 dans le checksum
Es tu maitre du contrôle du checksum à la réception ?

Calculez un checksum avec un tableau de char ?
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#4 Message par Jérémy » mar. 2 janv. 2018 10:09 lien vers la Data-Sheet : Cliquez ici

Bonjour ,

Merci pour vos réponses .

pspic a écrit :Source du message Ne faut il pas terminer la trame avec un End of text 0x03 ?

Non pas besoin

pspic a écrit :Source du message Es tu maitre du contrôle du checksum à la réception ?

Non pas vraiment. C'est le module qui gère tout

J'ai juste un probléme de compréhension de fonctionnement. Je vais faire une pause car ca me saoule . ca à l'air très simple et je n'y arrive pas.
Apparement lire deux valeurs analogiques, puis les envoyer en uart à un module radio c'est trop pour moi. 2018 commence déjà mal pour moi!:
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Calculez un checksum avec un tableau de char ?
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#5 Message par satinas » mar. 2 janv. 2018 10:20 lien vers la Data-Sheet : Cliquez ici

Bonjour à tous,
Jeremy tu as surtout un problème de compréhension du C. Le fait de te donner des solutions clé en main, t'empêche de progresser. La fonction UART_Write_Text() ne peut pas envoyer un octet nul, puisque que comme toutes les fonctions qui traitent une chaine, elle s'arrête sur le premier caractère nul rencontré.
Le seul moyen d'envoyer un octet nul, c'est la fonction MikroC
void UARTx_Write(char data_);

Calculez un checksum avec un tableau de char ?
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#6 Message par paulfjujo » mar. 2 janv. 2018 11:08 lien vers la Data-Sheet : Cliquez ici

Bonjour à tous, et mes meileurs voeux de santé

Que la force soit dans vos neurones !

Jeremy, quelle sorte de checsum tu veux .. un simple checksum = Somme modulo 256
ou un checksum calulé suivant un polynome CRC16 , CRC32 ... ectc

un site interessant
un executable est meme telechargable

mais pour moi Bizarre , ou j'ai pas compris, meme le checksum simple
puisque je ne trouve pas le meme resultat, dans l'exemple 2
0xC2 au lieu de 0x81 ???

donc le resultat du 1er (0x41) exemple peut etre aussi faux ?

[list=][/list]

Code : Tout sélectionner



       txt1
[0] =120;
       txt1[1] =65;
       txt1[2] = 99;
       txt1[3] =37;
       CRC=0;
    //Envoi d'un message
       UART1_Write(0x02);             // Start
       UART1_Write(0x00);             // Commande
       UART1_Write(0x04);             // Nbe de DATA
       for (i=0;i<4;i++)
       {
         UART1_Write(txt1[i]);     // DATA
         CRC=CRC + txt1[i];
       }
       UART1_Write(CRC);   //CS
       UART1_Write(0x03);
       
    
//   02 00 04 78 41 63 25 41 03      (CRC=0x41)

// exemple du site Developpez.com

       strConstRamCpy(txt1,"Bonjour Papa");
       k=strlen(txt1);
       CRC=0;
          for (i=0;i<k;i++)
       {
         UART1_Write(txt1[i]);     // DATA
         CRC=CRC + txt1[i];
       }
       UART1_Write(CRC);   //CS

    // resultat sur realterm
    // 42 6F 6E 6A 6F 75 72 20 50 61 70 61   
    // CRC=C2

       CRLF1();
      while(1);
 
Aide toi, le ciel ou FantasPic t'aidera

Calculez un checksum avec un tableau de char ?
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#7 Message par Jérémy » mar. 2 janv. 2018 11:28 lien vers la Data-Sheet : Cliquez ici

Re,

Désolé les gars, je suis en burn-out et je n'arrive à rien.

Le checksum est un XOR entre toute les valeurs de la trame. Rien de bien compliqué. Si le cheksum est bon , je vois la led d'envoi de message s'allumée un coup. Si elle s'allume c'est gagné mes données partent bien par Voir Radio.

De l'autre coté je récupère les données avec ce module : http://fr.farnell.com/amber-wireless/am ... dp/2470032 et je les affichent sur mon hyper terminal.

J'ai mis un joystick sur deux entrées analogiques ( RD5 et RD7). pour envoyer les valeurs lues par VR

Voici mon programme dans un état pitoyable :

Les données partent bien, mais j'ai deux fois la même valeur qui s’affichent au lieu d'avoir deux valeurs différentes ! incompréhensible pour moi en ce moment

Code : Tout sélectionner

// PROGRAMME pour la télécommande-radio du robot

// DS du PIC : http://ww1.microchip.com/downloads/en/DeviceDoc/40001844D.pdf

/*
Fosc = 64Mhz
UART1 = 57600 bauds
UART2 = 57600 bauds
*/

#define RESET      LATC.B3  // Sortie
#define CONFIG     LATD.B0  // Sortie
#define CTS        LATC.B4  // Sortie
#define RTS        PORTC.B5 // Entrée
#define DATA_REQ   LATD.B2  // Sortie
#define DATA_IND   PORTD.B3 // Entrée
#define TRX_DIS    LATD.B1  // Sortie

#define LED_R      LATC.B2  // Sortie led rouge
#define LED_V      LATC.B1  // Sortie led verte
#define BP         PORTE.B0 // Entree pour BP

#define ADC_RD5    0b00011101  // Defini le ADPCH = RD5
#define ADC_RD7    0b00011111  // Defini le ADPCH = RD7
#define ADC_RC0    0b00010000  // Defini le ADPCH = RC0
#define ADC_RA7    0b0000111   // Defini le ADPCH = RA7


//##################################     Variables    ##############################################
 
char iCompteurOk ;
 
char Joystick_D_HBJoystick_D_DGJoystick_G_HBJoystick_G_DG;
 
unsigned int temp ;
 
 
unsigned int Valeur_lue;
 
char txt[4];
 
char txt2[7];
 
//--- UART
 
char Reception_UART1Reception_UART2Index_Buff1Index_Buff2Buffer1_pleinBuffer2_plein;
 
char ValeurCommande_Mode_OKParametre_OKRESET_OKTEST_OK;
 
char Buffer_UART1[30];
 
char Buffer_UART2[30];

//##################################     PROTOTYPE    ##############################################


//##############################################################################
//------------------------     INTERRUPTION        -----------------------------
void interrupt(){

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

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

     
switch (Valeur){
        case 
0:     if (Reception_UART1 == 0x02){     // reception du Start signal
                       
Valeur ;
                     }
                     else
                       
Valeur 0;
                    break;

                    
// Numéro de la  commande recue
        
case 1:     if (Reception_UART1 == 0x49)       // Parametre OK
                       
Valeur 2;
                    else if (
Reception_UART1 == 0x81)  // Reception d'un message
                       
Valeur 10;
                    else if (
Reception_UART1 == 0x44)  // Command_MODE OK
                       
Valeur 20;
                    else if (
Reception_UART1 == 0x40)  // ACK_OK ou NON_ACK
                       
Valeur 30;
                    else if (
Reception_UART1 == 0x99){  // TEST_OK
                        
TEST_OK ;
                        
Valeur 0;
                       }
                    else
                       
Valeur 0;
                    break;

       case 
2:     if (Reception_UART1 == 0x01)        // Nombre bytes
                       
Valeur 3;
                     else
                       
Valeur 0;
                    break;

        case 
3:     if (Reception_UART1 == 0x00)       //data
                       
Valeur 4;
                     else
                       
Valeur 0;
                    break;

        case 
4:     if (Reception_UART1 == 0x4A){     // checksum 0x02 0x49 0x01 0x00 0x4A
                       
Parametre_OK 1;              // Je léve le FLAG
                     
}
                    
Valeur 0;
                    break;

        case 
20:    if (Reception_UART1 == 0x01)      // Command_MODE OK
                       
Valeur 21;
                     else
                       
Valeur 0;
                    break;

        case 
21:    if (Reception_UART1 == 0x10)      // Command_MODE OK
                       
Valeur 22;
                     else
                       
Valeur 0;
                    break;

        case 
22:    if (Reception_UART1 == 0x57){     //Command_MODE OK : 0x02 0x44 0x01 0x10 0x57
                       
Commande_Mode_OK 1;
                     }
                    
Valeur 0;
                    break;

        default:    
Valeur 0;
      }
   }

 
//-----------------------          UART 2        -----------------------------
  
if((RC2IF_bit==1) && (RC2IE_bit==1)) {

     
Reception_UART2 UART2_Read();                  // On récupere et stock la donnée

     
if (Reception_UART2 == 13){ // Verifie fin de message(Carriage Return) ou Buffer plein

      
}
   }
}

#include "Initialisation_AMB8626.h"
 
//#################################################################################################
//#########################################      MAIN      ########################################
//#################################################################################################
void main() {

    
// RAZ des broches
    
LATA LATB LATC LATD LATE 0;

    
// registres des I/O
    
TRISA 0xEF;            // RA4 en sortie pour liaison
    
TRISB 0xDF;            // RB5 en sortie Pour UART-TX2
    
TRISC 0xA1;            // En sortie RC1 et RC2 pour led test, RC3 et RC4 pour liaison AMB et RC6 pour Tx1
    
TRISD 0xF8;            // En sortie RC0, RC1 et RC2 pour liaison AMB
    
TRISE 0xFF;            // Tout en entrée

    // registre analogiques
    
ANSELA 0x80;           // RA7 en analogique
    
ANSELC 0x01;           // RC0 en analogique
    
ANSELD 0xA0;           // RD5 et RD7 en analogique
    
ANSELB=ANSELE 0x00;

    
// Registre des Pull-UP
    
WPUA 0x0F;             // RA0, RA1, RA2 et RA3 en Pull UP
    
WPUB 0x0F;             // RB0, RB1, RB2 et RB3 en Pull UP
    
WPUE 0x01;             // RE0 en pull up pour BP
    
WPUC WPUD 0x00;

    
//---------------------------     PPS     --------------------------------------------------
    // Séquence de déverouillage des PPS page 218 de la DS
    
INTCON.GIE 0;               // On désactive les INT
    
Unlock_IOLOCK();              // On deverouille les PPS
    
RX1PPS 0x17 ;               // RC7->EUSART1:RX1;
    
RC6PPS 0x09;                // RC6->EUSART1:TX1;
    
RX2PPS 0x0F;                // RB7->EUSART2:RX2;
    
RB5PPS 0x0B;                // RB5->EUSART2:TX2;
    
Lock_IOLOCK();                // On verouille les PPS

    // -----------------     Initialisation UART  ----------------------------------
    //-----   UART2
    
UART2_Remappable_Init(57600);
    
RC2IE_bit 1;         // Active les Interruptions sur Rx UART 2
    
RC2IF_bit 0;         // RAZ flag
    //-----   UART1
    
UART1_Remappable_Init(57600);
    
RC1IE_bit 1;         // Active les Interruptions sur Rx UART 2
    
RC1IF_bit 0;         // RAZ flag
    
    //------------------------------   INTERRUPTION    -------------------------------------
    //-----      GLOBAL
    
INTCON.PEIE ;       // On active les INT périphériques
    
INTCON.GIE  ;        // On active toutes les INT

    
Initialisation_AMB8626();  // Se trouve dans un Header a dé-commenter pour un changement de la config

    // -----------------     Initialisation de la lecture analogique/numérique  ----------------------------------
    
ADC_Init();
    
ADFM_bit 0;               // Justification à gauche. ainsi je transforme la lcture sur 10 bits en 8 bits et jignore les petits chiffres
    
TRISD.B5 TRISD.B7 1;    // met RD5 et RD7 en entrée
    
ADPCH 0b011101;           // Lecture de RD5 par défaut

    
UART_Set_Active(&UART1_Remappable_Read, &UART1_Remappable_Write, &UART1_Remappable_Data_Ready, &UART1_Remappable_Tx_Idle);

    
// séquence de clignotement au demarrage (3 fois)
    
for (i=0;i<=5;i++){
       
LED_R = ~LED_R ;
       
delay_ms(100);
     }

//#################################################################################################
//###############################      BOUCLE PRINCIPALE      #####################################
//#################################################################################################

 
while(1){

     
ADPCH ADC_RD5;                // On change de broche pour lire la suivante ici RD5
     
delay_ms(10);
     
ADCON0.ADGO 1;                // lancement de la conversion
     
while (ADCON0.ADGO);            // On attend la fin de la conversion
     
Joystick_G_DG ADRESH;         // On enregistre le résultat
     
     
ADPCH ADC_RD7;                // On change de broche pour lire la suivante ici RD5
     
delay_ms(10);
     
ADCON0.ADGO 1;                // lancement de la conversion
     
while (ADCON0.ADGO);            // On attend la fin de la conversion
     
Joystick_G_HB ADRESH;         // On enregistre le résultat

     //Envoi d'un message
     
UART1_Remappable_Write(0x02);             // Start
     
UART1_Remappable_Write(0x00);             // Commande
     
UART1_Remappable_Write(0x02);             // Nbe de DATA
     
UART1_Remappable_Write(Joystick_G_DG);    // DATA
     
UART1_Remappable_Write(Joystick_G_HB);    // DATA
     
UART1_Remappable_Write(0x02^0x00^0x02^Joystick_G_DG^Joystick_G_HB);   //CS
    
    
delay_ms(200);

 }
}

//#################################################################################################
//###############################      PROGRAMME SECONDAIRE     ###################################
//#################################################################################################

  /*
     if ( TEST_OK == 1){
      TEST_OK =0 ;
      LED_R = ~LED_R ;
      LED_V = ~LED_V ;
    }
  */

 /*
   if ( BP == 0){
      delay_ms(50);
      if ( BP == 0){
          LED_R = 1 ;

           ADPCH = ADC_RD5;                        // On change de broche pour lire la suivante ici RD5
           delay_ms(50);
           ADCON0.ADGO = 1;                        // lancement de la conversion
           while (ADCON0.ADGO);                    // On attend la fin de la conversion
           Joystick_G_DG = ADRESH;   // On enregistre le résultat

           ADPCH = ADC_RD7;                        // On change de broche pour lire la suivante ici RD5
           delay_ms(50);
           ADCON0.ADGO = 1;                        // lancement de la conversion
           while (ADCON0.ADGO);                    // On attend la fin de la conversion
           Joystick_G_HB = (ADRESH<<8) + ADRESL;   // On enregistre le résultat
           Joystick_G_HB = Joystick_G_HB >> 2 ;

           //Envoi d'un message
           UART1_Remappable_Write(0x02);             // Start
           UART1_Remappable_Write(0x00);             // Commande
           UART1_Remappable_Write(0x04);             // Nbe de DATA
           UART1_Remappable_Write(Joystick_G_DG);    // payload N°1
           UART1_Remappable_Write(Joystick_G_HB);    // payload N°1
           UART1_Remappable_Write(0x0A);    // payload N°1
           UART1_Remappable_Write(0x0D);    // payload N°1
           UART1_Remappable_Write(0x02^0x00^0x04^Joystick_G_DG^Joystick_G_HB^0x0A^0x0D);          // CS

            LED_R = 0 ;

            while (BP == 0);
       }

    }

    delay_ms (500);
   // LATC.B1 = ~PORTC.B1 ;            // Clignotement d'une led pour voir le programme tourner

    UART_Set_Active(&UART1_Remappable_Read, &UART1_Remappable_Write, &UART1_Remappable_Data_Ready, &UART1_Remappable_Tx_Idle);
    UART1_Write_Text("1 \r\n");

    UART_Set_Active(&UART2_Remappable_Read, &UART2_Remappable_Write, &UART2_Remappable_Data_Ready, &UART2_Remappable_Tx_Idle);
    UART2_Write_Text("2 \r\n");
  */ 
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Calculez un checksum avec un tableau de char ?
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#8 Message par satinas » mar. 2 janv. 2018 11:47 lien vers la Data-Sheet : Cliquez ici

Pur moi, un checksum se calcule avec des unsigned char, des octets, quoi ...
De voir tous ces char partout, ça me gêne.

Calculez un checksum avec un tableau de char ?
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#9 Message par paulfjujo » mar. 2 janv. 2018 13:44 lien vers la Data-Sheet : Cliquez ici

Jeremy, tu ne peux pas ecrire
UART1_Remappable_Write(0x02^0x00^0x02^Joystick_G_DG^Joystick_G_HB); //CS

je verrai plutot comme cela

Code : Tout sélectionner


    
//Envoi d'un message
       
CRC=0;
       
UART1_Write(0x02);             // Start trame
       
UART1_Write(0x00);             // Commande
       
UART1_Write(0x02);             // Nbe de DATA
       
UART1_Write(Joystick_G_DG);     // DATA 1
       
CRC=CRC Joystick_G_DG;
        
UART1_Write(Joystick_G_HB);   // DATA 2
       
CRC=CRC Joystick_G_HB;
       
UART1_Write(CRC);   //CRC
       
UART1_Write(0x03);  // fin de trame
 


j'ai repris l'exemple du site Developpez.com
et pour un CRC simple, il faut utiliser Somme (+) et non XOR (^)

Code : Tout sélectionner


 unsigned char CRC
;
 unsigned char txt1[25];
 
  strConstRamCpy
(txt1,"Bonjour Papa");
       k=strlen(txt1);
       CRC=0;
          for (i=0;i<k;i++)
       {
         UART1_Write(txt1[i]);     // DATA
         CRC=CRC + txt1[i];
       }
       UART1_Write(CRC);   //CS
    while(1);


// avec simple addition
// 42 6F 6E 6A 6F 75 72 20 50 61 70 61 81 <-- correspond au resultat escompté
// avec XOR ^
// 42 6F 6E 6A 6F 75 72 20 50 61 70 61 41 <-- bad result


D'autre part, il faut verifier si tu peut envoyer ton message fractionné ( avec plusieur write )
ou si il doit etre d'un seul tenant
dans ce cas, il faudrait geg=nerer un string qui contient tout le message
pour l'envoyer d'un seul coup..
j'ai rencontré ce genre de probleme avec des liaisons bluetooth..
Aide toi, le ciel ou FantasPic t'aidera

Calculez un checksum avec un tableau de char ?
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#10 Message par satinas » mar. 2 janv. 2018 13:57 lien vers la Data-Sheet : Cliquez ici

Paul, la doc de la commande et du checksum est là, voir page 15
download/file.php?id=1865


Retourner vers « Langage C »

Qui est en ligne

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