communication modbus PIC16F877
Répondre à la discussion
Affichage des résultats 1 à 20 sur 20

communication modbus PIC16F877



  1. #1
    invitef57db61e

    communication modbus PIC16F877


    ------

    Bonjour,

    Je voulais communiquer mon pic16F877 via le protocole modbus en utlisant un RS232. Je voulais lire des variables depuis un esclave. j'ai procédé comme ceci mais rien ne se passe :

    int downstream_sol()
    {
    char input[15];
    putc(0x01);//@ esclave
    putc(0x01);//num de la fonction
    putc(0x00);//@ registre à lire MSB
    putc(0x2F);// @regustre à lire LSB
    putc(0x00);// nombre de reg à lire MSB
    putc(0x01); //nombre de reg à lire LSB
    putc(0xCC);// CRC16 LSB
    putc(0x03);// CRC16MSB
    gets(input);
    return input[4];
    }
    Est ce que c'est correct ? svp j'ai besoin de l'aide si vs avez besoin d'encore plus de details je vous les donnerai
    merci enormement

    -----

  2. #2
    invitef57db61e

    Re : communication modbus PIC16F877

    Eoo y'a quelqu'un ??? je voulais communiquer le 16f877 avec un slave dont le but est de lire quelques registres contenant des variables. Svp à l'aideee !!
    merciii

  3. #3
    carcan

    Re : communication modbus PIC16F877

    Hello !

    - est-ce que les données sortent du PIC (visu à l'oscillo ou espion modbus) ?
    - est-ce que l'esclave répond (toujours visu avec instrument) ?
    - gets attend un caractère de fin de trame (0x0A ou 0x0C je sais plus), est-ce que ton esclave l'envoie ??

    Donne ton code complet et le type de compilateur si tu veux plus d'aide !

    A+
    Laurent

  4. #4
    invitef57db61e

    Re : communication modbus PIC16F877

    Salut,
    mon programme est en piéce jointe.
    Merciii

    int downstream_sol()
    {
    char input[15];
    putc(0x01);//@ esclave
    putc(0x01);//num de la fonction
    putc(0x00);//@ registre à lire MSB
    putc(0x2F);// @regustre à lire LSB
    putc(0x00);// nombre de reg à lire MSB
    putc(0x01); //nombre de reg à lire LSB
    putc(0xCC);// CRC16 LSB
    putc(0x03);// CRC16MSB
    gets(input);
    return input[4];
    } ==> C'est une demande de lecture

    le pic sert à lire les variable. L'esclave ne repond pas !! je vois rien ! je ne vois pas la trame
    Fichiers attachés Fichiers attachés

  5. A voir en vidéo sur Futura
  6. #5
    carcan

    Re : communication modbus PIC16F877

    Réponds à mes 3 questions par oui ou non ... tu n'es pas clair et on va tourner en rond !

  7. #6
    invitef57db61e

    Re : communication modbus PIC16F877

    - est-ce que les données sortent du PIC (visu à l'oscillo ou espion modbus) ? NON
    - est-ce que l'esclave répond (toujours visu avec instrument) ? NON ( normalement il repond mais jusqu'a maintenant j'ai pas réussi à recevoir une reponse ! )
    - gets attend un caractère de fin de trame (0x0A ou 0x0C je sais plus), est-ce que ton esclave l'envoie ?? NON la réponse de l'esclave finit par le CRC

  8. #7
    paulfjujo

    Re : communication modbus PIC16F877

    bonsoir



    Citation Envoyé par ikbel Voir le message
    - est-ce que les données sortent du PIC (visu à l'oscillo ou espion modbus) ? NON
    C'est largement suffisant pour que l'esclave ne reponde pas !
    dans ton code
    #use rs232(baud=9600,parity=N,xmit= PIN_C6,rcv=PIN_C7,bits=8)

    je ne vois pas d'init de la liaison UART dans le main
    ni d'interruption traitant la reception.
    putc gere t-il le test de registre emission vide ?

    Est-ce que la definition ci dessus #use rs232 ...
    fait bien tout le travail necessaire ?

    et les bits de config ?

    ( Je ne connais pas ce compilateur, apparament ni C18 (puisque c'est un 16Fxxx) ,ni MikroC )

  9. #8
    carcan

    Re : communication modbus PIC16F877

    Re !

    le code semble bon, mais pas besoin de placer 2 fois l'instruction #use RS232 (une dans le .h et une dans le .c). Comme ta première réponse est NON, c'est normal que l'instrument ne réponde pas ...
    Tu as testé comment ? as-tu connecté un PC avec HyperTerminal à la place de ton appareil ?
    Un schéma ou descriptif détaillé de ton interface RS232 serait la bienvenue !

    Sinon quand tu arriveras à faire répondre ton esclave, il faudra utiliser autre chose que gets(). gets()est utilisé pour recevoir une chaine de caractères qui se termine par CR ou LF, ce qui n'arrive pas en ModBUS.
    Utilises plusieurs getc() en fonction du nombre d'octets que ton instrument envoie.

    Bon week-end
    Laurent

  10. #9
    invitef57db61e

    Re : communication modbus PIC16F877

    Salut
    Merci tout le monde.
    @paulfjujo Merciii et Svp Commet elle doit etre l'init de la liaison UART? le compilateur que j'utilise c'est le PIC C Compiler.
    @Carcan merciii. ouii j'ai connecté un pc en espérant de voir la trame que le pic envoie mais j'ai rien vu :/ j'ai utilisé l'interface RS232 standard Pin2 RX pin3 TX pin5 gnd ( DB9) et concernant le gets je vais suivre tes instructions mercii.

    BN8

  11. #10
    carcan

    Re : communication modbus PIC16F877

    Et donc pas de MAX232 ou équivalent ????

    A+
    Laurent

  12. #11
    invitef57db61e

    Re : communication modbus PIC16F877

    Bsr,

    Si si j'ai utilisé un max 232. Ci joint un imprime ecran de ma carte sous ISIS.
    Mercii enormement.
    Images attachées Images attachées  

  13. #12
    invitef57db61e

    Re : communication modbus PIC16F877

    bsrr,

    Alors people !! tjrs po d sol :/

  14. #13
    carcan

    Re : communication modbus PIC16F877

    Re !

    ton code semble bon, le câblage su MAX aussi.
    Testes ta ligne de comm. jusqu'au PC : tu retires le PIC, tu mets un strap sur le support entre les pin TX et RX, et tu écris qqch sur l'hyperterminal ... si tout est ok, tu as un echo en retour.

    N'oublie pas que ta fonction gets() ne marche pas pour ton appli.
    Ajoute aussi un TimeOut dans la fonction #use RS232 (idéal pour les fonctions getc(), gets(), ... sinon elles attendront indéfiniment un retour).

    A+
    Laurent

  15. #14
    invitef57db61e

    Re : communication modbus PIC16F877

    Bonjour,

    Merci énormément Carcan. Je vais refaire le test.
    Bon après midi.

  16. #15
    paulfjujo

    Re : communication modbus PIC16F877

    et alors,ce test ?

    je suis en rain de tester un module ITB 8EST esclave modbus RTU
    avec la particularite que la liaison Rs232 est en Parite paire!
    si la parite n'est pas respectee,le module ne repond JAMAIS.
    D'autre part le Crc16 est dans l'ordre Msb,puis Lsb.
    contrairement a ton exemple.

    J'ai rajoute une Uart soft 9600,N,8,1
    pour suivre parrallelement les trames Envoi et Retour
    modbus sur un terminal Vbray.
    L'uart hardware gere les echanges modbus 9600,E,8,1.

    je vais mettre les resultats de ces tests d'ici demain sur ma
    page Web, rubrique Modbus (pic18f258).
    je ne travaille qu'avec C18 ! et dans le monde reel.

  17. #16
    invitef57db61e

    Re : communication modbus PIC16F877

    Salut,
    J'ai pas encore fait le test vu que j'ai d'autres probléme avec mon Pic.. Bref, j'ai respecté la parité et tout, concernant le Crc16 j'ai respecté la structure du message d'interrogation selon les documentations de mon esclave. Voici la structure:
    Nom : structure du message.jpg
Affichages : 167
Taille : 35,2 Ko
    Prière de publier les résultats de tes tests.
    Merci

  18. #17
    invitef57db61e

    Re : communication modbus PIC16F877

    Salut,

    Alors ils sont bons vos test paulfjujo ??
    Merci de les publier

  19. #18
    paulfjujo

    Re : communication modbus PIC16F877

    Bonjour,

    Citation Envoyé par ikbel Voir le message
    Alors ils sont bons vos test paulfjujo ??
    Merci de les publier

    bonjour,

    J'attends une autorisation du constructeur du module ITB
    pour publier mes tests et un logiciel windows XP pouvoir l'utiliser en RS485 et modifier sa configuration
    sinon il cause deja en RS232.
    ..à suivre

  20. #19
    invitef57db61e

    Re : communication modbus PIC16F877

    Okii bon chance

    Mercii.

  21. #20
    paulfjujo

    Re : communication modbus PIC16F877

    En attendant de voir ta progression sur le sujet.
    quelques morceaux du code en C18 , permettant deja d'entrevoir comment se fait le dialogue..
    surtout sur la partie reception.
    Le dossier complet bientot sur ma page web.

    Code:
    .... init diverses
    .. init des UART ..
    ... reception UART hardware en mode interrupt ..resultat dans buffer[]
    .. subroutine pour gerer la parite paire : Put_RS_P(txt);
    
    
    rom const char chaine0[]="Port comm2 Hardware 9600,E,8,1 <-> ITB  ouvert \n\r";
    rom const char chaine1[]="Port comm1 Software 19200,N,8,1   -> Vbray ouvert \n\r";
    rom const char chaine2[]="C18: 18F258_Modbus_ITB_C18.c \n\r";
    rom const char chaine3[]="Envoi Trame (Hexa): ";
    rom const char chaine4[]="Recep.Trame (Hexa): ";
    rom const char chaine5[]="8 Voies Entrees Analogiques 10bits :\n\r";
    rom const char chaine6[]="CRC16= ";
    rom const char chaine7[]="STATUS = ";
    rom const char chaine8[]="Entrees TOR I0 .. I3 = ";
    rom const char chaine9[]="Sorties TOR O0 .. O3 = ";
    rom char *RS_Str[]={chaine0,chaine1,chaine2,chaine3,chaine4,chaine5,chaine6,chaine7,chaine8,chaine9};
    
    
    //CRC 16 for modbus checksum 
    unsigned int  CRC16(unsigned int dataLength,char check)
    {
    // trame 01 03 00 0A 00 01 A4 08    envoi  avec check=0
    // trame 01 03 02 02 03 F9 25       reception avec check=1
    unsigned int CheckSum;
    unsigned int i,j;
    CheckSum = 0xffff;
    for (j=0; j<dataLength; j++)
    {
    CheckSum = CheckSum^(unsigned int)buffer[j];
    for(i=8;i>0;i--)
         {
            if(CheckSum & 1)
            CheckSum = (CheckSum>>1)^0xa001;
            else
            CheckSum>>= 1;
         }   
    }
    // attention rangement Checksum inversé
    CRC16_Value=CheckSum ;  // for checking purpose 
    CRC16_H = CheckSum>>8;
    CRC16_L = CheckSum & 0x00FF;
    if (check==1)
      {
      if ( (buffer[dataLength] == CRC16_L) && (buffer[dataLength+1] ==CRC16_H  ))
        return CheckSum;
      else
        return 0;
      }
      else
      {
      buffer[dataLength] = CRC16_L;
      buffer[dataLength+1] = CRC16_H;
      return CheckSum;
      }
     }
    
    
    void Envoi_Trame_Modbus(char ID,char Type_Requete,unsigned int Adr1,unsigned int Nb)
    { unsigned int crc,k,i;
        // 01 03 00 0A 00 01 A4 08 
        buffer[0]=ID;
        buffer[1]=Type_Requete;
        buffer[2]=(unsigned char)(Adr1>>8);           //MSB
        buffer[3]=(unsigned char)(Adr1 & 0x00FF);     //LSB
        buffer[4]=(unsigned char)(Nb >> 8);                //MSB
        buffer[5]=(unsigned char)(Nb & 0x00FF);          //LSB   nombre de mots !
        
        if (Type_Requete==1)
        {  //.. to do
        } 
        if (Type_Requete==3)
        {   
            CRLF(); 
            k=8;
            crc=CRC16(6,0);    // pas de check CRC a l'emission ,buf[6] buf[7]=CRC16
            txt=&Texte[0];
            strcpypgm2ram(txt,RS_Str[3]);
            putsUART_(txt);
            putcUART(TAB);
            for (i=0;i<k;i++)
            {
              Octet2Hex(buffer[i],0); // link to Terminal
              putcUART(' ');
            }  
            for (i=0;i<k;i++)
            {
              Put_RS_P(buffer[i]); // ITB link Hardware UART
            }  
           
           buffer[k]=0;
         } 
         Index=0;
             
    }    
    
    unsigned int  Recoi_Trame_Modbus(char ID,char Type_Requete)
    { 
        unsigned int crc,k2,i,j,t;
        // buffer contient la trame recue
        // exemples:
        //01 03 02 02 00 B9 24
        //01 03 02 02 01 78 E4
        //01 03 02 02 03 F9 25
        j=0;
        k2=0;
        crc=0;
        if ( buffer[0]==ID)
        {
        if (buffer[1]==3) 
        {
          t= 3 + (unsigned int) buffer[2];  // Nb d'octets recus
          crc=CRC16(t,1);  // check 
          if (crc > 0)
           { 
             k2= (unsigned int) buffer[2]; // nb d'octets a lire
            } 
            else
            k2=0;   
          } // requete
         }  // Num esclave
       return k2; // nb d'octets a lire
    }   
        
    ... autres subroutines
    
    
    
    void main ()
    {
    
    void main()
    {
     Init_Hardware() ;
     OUT_RS232
     Led_Blanche=0;
    
     Init_UART_Even(); // 9600,E,8,1 ITB modbus, usage du 9em bit
     
     OpenUART(); // 19200,N,8,1 Terminal
     Tempo(10000L);
     putcUART(CLS);
     Tempo(150000L); 
     CRLF();
     
     txt=&Texte[0];
     strcpypgm2ram(txt,RS_Str[0]);
     putsUART_(txt);
    
    ..... etc ..
    
    do
    {
    
    .....etc 
    
      Index=0;
      // Esclave#1 lecture de 8 mot a l'adresse 10h   (registre ANA0 a 7 sur ITB 8EA)
      // 01 03 00 03 00 08 B4 0C     avec CRC16=0CB4
      Envoi_Trame_Modbus(1,3,3,8); // lecture EA0 a EA7
      Tempo(5000L);  // <- Ok avec ce delai de retournement et a 9600bds
     
      
      Index=0;
      c1=0;
      k1=Recoi_Trame_Modbus(1,3);  // ex: 01 03 02 02 03 F9 25 pour lecture EA7
      CRLF();
      txt=&Texte[0];
      strcpypgm2ram(txt,RS_Str[4]);
      putsUART_(txt);
      putcUART(TAB);
      l=(unsigned int) (buffer[2]) +4;
      for (i=0;i<=l;i++)
      {
         Octet2Hex(buffer[i],0);
         putcUART(' ');
      }
      putcUART(TAB); 
      txt=&Texte[0];
      strcpypgm2ram(txt,RS_Str[6]); // CRC16=
      putsUART_(txt); 
      putcUART(TAB);
      Octet2Hex(CRC16_L,0); putcUART(' '); 
      Octet2Hex(CRC16_H,0);
      CRLF();
      
      if (k1>0)  // Nb de mots a lire
      { 
        txt=&Texte[0];
        strcpypgm2ram(txt,RS_Str[5]); // 8 EA Analog
        putsUART_(txt);  
        j=0;
        Led_Blanche=!Led_Blanche;
        for (i=0;i<k1;i=i+2)
         {
            putcUART('E');putcUART('A');
            putcUART(j+48);   putcUART('=');
            MSB=buffer[i+3];
            LSB=buffer[i+4];
            Analog[j]=(unsigned int)(MSB <<8) + (unsigned int)LSB;
            Write_Word(Analog[j],0,0);
            putcUART(TAB);
            j++;
         } 
       }
      CRLF();  
    
    	Tempo(25000L);
     }
    while(1);
    }
    Resultat du Dialogue recupéré sur un terminal espion

    Port comm2 Hardware 9600,E,8,1 <-> ITB ouvert
    Port comm1 Software 19200,N,8,1 -> Vbray ouvert
    Projet:18F25x_Modbus.mcp
    Port Com2 9600,Even Parity,8,1
    VBray <-> UART Soft 9600,N,8,1
    18F258 + Pickit 2.61


    Envoi Trame (Hexa): 01 03 00 00 00 01 84 0A
    Recep.Trame (Hexa): 01 03 02 00 01 79 84 CRC16= 79 84
    STATUS = 00 01

    Envoi Trame (Hexa): 01 03 00 01 00 01 D5 CA
    Recep.Trame (Hexa): 01 03 02 00 00 B8 44 CRC16= B8 44
    Entrees TOR I0 .. I3 = 00 00000000

    Envoi Trame (Hexa): 01 03 00 03 00 08 B4 0C
    Recep.Trame (Hexa): 01 03 10 00 00 00 00 00 03 00 00 00 01 00 00 00 00 02 F3 BA F8 CRC16= BA F8
    8 Voies Entrees Analogiques 10bits :
    EA0=0 EA1=0 EA2=3 EA3=0 EA4=1 EA5=0 EA6=0 EA7=755

Discussions similaires

  1. mikroC + communication RS232 ( pic16f877 )
    Par invite0d541d2c dans le forum Électronique
    Réponses: 1
    Dernier message: 18/10/2012, 14h20
  2. communication clavier avec pic16f877
    Par inviteb8298f1a dans le forum Électronique
    Réponses: 5
    Dernier message: 13/05/2012, 22h04
  3. la communication via Modbus
    Par invitef44aa575 dans le forum Électronique
    Réponses: 37
    Dernier message: 02/04/2012, 17h39
  4. Communication modbus sur Ethernet
    Par invite0f178c4b dans le forum Internet - Réseau - Sécurité générale
    Réponses: 6
    Dernier message: 24/11/2011, 20h00
  5. Modbus Protocol Communication
    Par invitec782be84 dans le forum Électronique
    Réponses: 1
    Dernier message: 27/02/2008, 20h40
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...