IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Embarqué Discussion :

L´envoi du contenu d´un fichier texte vers le port serie RS232


Sujet :

Embarqué

  1. #41
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 361
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 361
    Points : 20 381
    Points
    20 381
    Par défaut
    Citation Envoyé par Hibernatus34 Voir le message
    Rhô... c'est un test !
    de guerre lasse...je préfère abandonner
    Si tu as un minimum de bon sens tu vois bien que ça ne peut pas marcher !

  2. #42
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    726
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 726
    Points : 1 645
    Points
    1 645
    Par défaut
    arthurdubois:
    Pas de problème, par contre, j'avoue que je ne comprends pas le décalage.
    Hier j'ai vérifié que je comprenais bien l'API avec une vieille machine de 1988 à 2400 bps, ça a bien fonctionné.
    Quant au programme du µC, il est très simple et je ne vois pas comment il pourrait causer ce décalage.

    Si tu es encore motivé, tu peux tester cette version du programme PC :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    #include <fstream>
    #include <string>
    #include <vector>
    #include <iostream>
    #include <sstream>
     
    #include <Windows.h>
     
    using namespace std;
    
    string AttendEtLitTout(HANDLE h)
    {
    	COMSTAT			stat;
    	vector<char>	s;
    
    	Sleep(500);
    	ClearCommError(h, NULL, &stat);
    	if (stat.cbInQue > 0)
    	{
    		s.resize(stat.cbInQue);
    		ReadFile(h, s.data(), s.size(), NULL, NULL);
    	}
    	return string(s.begin(), s.end());
    }
    
    int main(void)
    {
    	COMMTIMEOUTS timeouts = { 0 };
    	HANDLE h = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    	if (h == INVALID_HANDLE_VALUE)
    	{
    		cout << "Erreur: Impossible d´ouvrir le port série" << endl;
    		return 1;
    	}
     	DCB dcb = { 0 };
    	BOOL dcbOk = GetCommState(h, &dcb);
    	dcb.BaudRate = CBR_115200;
    	dcb.ByteSize = 8;
    	dcb.Parity = NOPARITY;
     	dcb.StopBits = TWOSTOPBITS;
    	dcbOk = SetCommState(h, &dcb);
    	timeouts.ReadIntervalTimeout = 100;
    	timeouts.ReadTotalTimeoutMultiplier = 100;
    	timeouts.ReadTotalTimeoutConstant = 100;
    	timeouts.WriteTotalTimeoutMultiplier = 100;
    	timeouts.WriteTotalTimeoutConstant = 100;
    	if (!SetCommTimeouts(h, &timeouts))
    		return 1;
    	// Test de l'écho
    	for (int i = 0; i < 5; ++i)
    	{
    		char sentChar = '0' + i;
    		if (!WriteFile(h, &sentChar, 1, NULL, 0))
    			return 1;
    		cout << sentChar << " : " << AttendEtLitTout(h) << endl;
    	}
    	CloseHandle(h);
    	return 0;
    }
    Ca reste du Quick & Dirty, mais là j'essaie de voir ce qui est réellement dans la file d'attente après chaque écriture, pas uniquement le 1er caractère.

    Sinon, j'ai essayé d'écrire l'écho du µC avec les interruptions au lieu du poll :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    #include <avr/io.h>
    #include <avr/interrupt.h> 
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdint.h> 
    
    
    #define FOSC 8000000 // Clock Speed
    #define BAUD 115200UL
    
    #define UBRR_VAL ((FOSC+BAUD*8)/(BAUD*16)-1)   // clever runden
    
    #define usart_buffer_max_size 50             
    
    char usart0_rx_buffer[usart_buffer_max_size];
    volatile uint8_t usart0_rx_buffer_size = 0;
    
    void USART_Init (unsigned int ubrr)
    {
      UBRR0H = (unsigned char)(ubrr>>8);
      UBRR0L = (unsigned char) ubrr;
      UCSR0B = (1<<RXEN0) | (0<<TXEN0) | (1<<RXCIE0) | (0<<UDRIE0);
      UCSR0C = (1<<USBS0) | (1<<UCSZ01) | (1<<UCSZ00);
    } 
    
    /* La fonction d´interruption de reception du byte */
    /* Cette fonction est active lorsque RXCIE0 = 1 */ 
    ISR(USART0_RXC0_vect)
    {
      char data = UDR0;
      /* Pour eviter ce depassement de buffer, il est possible de faire du flow control avec XOn/XOff par exemple */
      if (usart0_rx_buffer_size < usart0_rx_buffer_max_size)
      {
        usart0_rx_buffer[usart0_rx_buffer_size] = data;
        ++usart0_rx_buffer_size;
        /* Active l'emission de donnees, car on a des donnees dans la file */
        UCSR0B |= 1<<UDRIE0;
      }
    }
     
    /* La fonction d´interruption d´envoi de byte */
    /* Cette fonction est active lorsque UDRIE0 = 1 */ 
    ISR(USART0_UDRE0_vect)
    {
      int i;
      if (usart0_rx_buffer_size == 0)
        /* S'il n'y a plus de données à envoyer on arrete l'emission */
        UCSR0B &= ~(1<<UDRIE0);
      else
      {
        UDR1 = usart0_rx_buffer[0];
        --usart0_rx_buffer_size;
        /* S'il n'y a plus de données à envoyer on arrete l'emission */
        if (usart0_rx_buffer_size == 0)
          UCSR0B &= ~(1<<UDRIE0);
        else
          /* Pour l'instant je gere la file de maniere bete et mechante, */
          /* mais ca pourrait etre un buffer cyclique */
          for (i = 0; i < usart0_rx_buffer_size; ++i)
            usart0_rx_buffer[i] = usart0_rx_buffer[i + 1];
      }
    }
    
    int main (void)
    { 
      USART_Init(UBRR_VAL) ;  // initialisation USART
      sei(); // Activation des  fonctions d´interruption
      while(1)
      {
      }
    }
    Je me suis basé sur ton code.
    Il y avait d'ailleurs une petite erreur : UCSZ02 n'est pas dans UCSR0C, il est dans UCSR0B. Mais ça change rien vu que tu y mets 0.

    Je n'ai pas vu dans la doc si les 2 interruptions risquent de s'interrompre l'une l'autre. C'est peut-être une évidence (qu'elles ne le peuvent pas), mais je n'ai pas d'expérience dans ce domaine.

  3. #43
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    726
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 726
    Points : 1 645
    Points
    1 645
    Par défaut
    Citation Envoyé par Mat.M Voir le message
    de guerre lasse...je préfère abandonner
    Si tu as un minimum de bon sens tu vois bien que ça ne peut pas marcher !
    Mat.M, je reconnais sans problème qu'il faudra bien attendre les moteurs au niveau du µC, puis attendre le µC au niveau du PC, et donc un dialogue entre les 2.
    Maintenant, le code que j'ai donné pour l'écho fonctionne, je l'ai testé hier. C'est juste une programme qui s'exécute en série.
    Je ne vois vraiment pas ce qui te gêne là-dedans.
    Moi je peux te dire ce qui me gênait un peu dans ton intervention : c'est que l'auteur de la question a de toute évidence assez de problèmes à résoudre avant de se perdre dans les pages d'aide de CreateThread, I/O cancellation (mauvaise idée, je le répète) etc.

    Mais encore une fois, tu as raison sur le fait qu'il y aura un dialogue entre les machines, et c'est vrai que j'ai laissé ça de côté pour le moment. Ça n'empêche pas le développement d'un programme monothread bête et méchant sur le PC, si le cahier des charges dit : "exécuter la séquence du fichier texte et quitter". (d'ailleurs l'objet de la mission c'est probablement le µC, plus que le PC qui n'est là que pour tester)

  4. #44
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 110
    Points : 27
    Points
    27
    Par défaut
    Bonjour,

    Hibernatus: j´ai deboggue le code que tu as poste tout a l´heure et une fenêtre contenant le message suivant s´est affiche:
    Signal received

    Programm received signal SIGSEGV, Segmentation fault
    .

    Au même instant la fenêtre "call stack" s´est affiche a mon ecran.
    La fenêtre "call stack" contient les donnees suivante:

    Nr Adress Function File line

    0 7C810EAC WriteFile() C:\WINDOWS\SY..
    1 00000000 0x0022ff0c in ?? ()
    2 00000000 0x00000794 in ?? ()
    3 00000000 0x0022fef0 in ?? ()
    4 00000000 0x0022ff0c in ?? ()
    5 00000000 0x00000794 in ?? ()
    0 00000000 0x00000000 in ?? ()

    J´ai essaye a plusieurs reprises de tester le nouveau code, helas les deux fenêtres apparaîssent. Bref le deboggage ne marche pas.

  5. #45
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    726
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 726
    Points : 1 645
    Points
    1 645
    Par défaut
    Oups, désolé, je n'ai rien pour tester ici, et j'ai pas lu totalement la doc de WriteFile (un paramètre était noté "optionnel" mais dans les commentaires ils expliquent qu'il ne l'est pas toujours).

    Voilà une correction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    #include <fstream>
    #include <string>
    #include <vector>
    #include <iostream>
    #include <sstream>
     
    #include <Windows.h>
     
    using namespace std;
     
    string AttendEtLitTout(HANDLE h)
    {
    	COMSTAT			stat;
    	vector<char>	s;
    	DWORD sizeRead;
     
    	Sleep(500);
    	ClearCommError(h, NULL, &stat);
    	if (stat.cbInQue > 0)
    	{
    		s.resize(stat.cbInQue);
    		ReadFile(h, s.data(), s.size(), &sizeRead, NULL);
    	}
    	return string(s.begin(), s.end());
    }
     
    int main(void)
    {
    	COMMTIMEOUTS timeouts = { 0 };
    	HANDLE h = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    	if (h == INVALID_HANDLE_VALUE)
    	{
    		cout << "Erreur: Impossible d´ouvrir le port série" << endl;
    		return 1;
    	}
     	DCB dcb = { 0 };
    	BOOL dcbOk = GetCommState(h, &dcb);
    	dcb.BaudRate = CBR_115200;
    	dcb.ByteSize = 8;
    	dcb.Parity = NOPARITY;
     	dcb.StopBits = TWOSTOPBITS;
    	dcbOk = SetCommState(h, &dcb);
    	timeouts.ReadIntervalTimeout = 100;
    	timeouts.ReadTotalTimeoutMultiplier = 100;
    	timeouts.ReadTotalTimeoutConstant = 100;
    	timeouts.WriteTotalTimeoutMultiplier = 100;
    	timeouts.WriteTotalTimeoutConstant = 100;
    	if (!SetCommTimeouts(h, &timeouts))
    		return 1;
    	// Test de l'écho
    	for (int i = 0; i < 5; ++i)
    	{
    		char sentChar = '0' + i;
    		DWORD sizeWritten;
    		if (!WriteFile(h, &sentChar, 1, &sizeWritten, 0))
    			return 1;
    		cout << sentChar << " : " << AttendEtLitTout(h) << endl;
    	}
    	CloseHandle(h);
    	return 0;
    }

  6. #46
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 110
    Points : 27
    Points
    27
    Par défaut
    Salut,

    j´ai deboggue a plusieurs reprises la version corrigee du code que tu as poste tout a l´heure et j´obtiens toujours un decalage. Voici ce que j´obtiens:

    0:
    1:0
    2:1
    3:2
    4:3

  7. #47
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 110
    Points : 27
    Points
    27
    Par défaut
    Salut,

    J´ai aussi donnes plusieurs valeurs au timeout afin d´eviter le decalage. Helas je n´obtiens rien de bon.

    J´obtiens les resultats aleatoires suivants:

    0:
    1:
    2:1
    3:2
    4:3

    ou

    0:
    1:0
    2:1
    3:2
    4:3

    ou

    0:0
    1:
    2:1
    3:1
    4:3

    ou

    0:
    1:
    2:01
    3:2
    4:3

  8. #48
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Cela ressemble soit à un problème de configuration du micro soit à une absence d'acquittement (lecture ?) aboutissant à un écho.
    1/ Vérifies avec la datasheet de ton micro que tout est bien configuré et si la réception doit être acquittée et comment
    2/ Utilises un espion sur ton lien (au pire un oscilloscope mais ça risque d'être + compliqué) pour voir ce qui se transmet sur celui-ci.

  9. #49
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    726
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 726
    Points : 1 645
    Points
    1 645
    Par défaut
    Citation Envoyé par arthurdubois Voir le message
    0:0
    1:
    2:1
    3:1
    4:3
    Tu es sûr de celui-là ? Parce que là ça serait vraiment bizarre. A l'ouverture d'un port COM, la file d'entrée est vidée, donc ça ne pourrait même pas s'expliquer par des restes d'un test précédent.

    Malheureusement j'ai encore du mal à comprendre comment on peut obtenir ce décalage alors que le µC se contente de renvoyer chaque caractère immédiatement. C'est comme s'il y avait un contrôle de flux et l'envoi d'un caractère par le PC débloquerait l'envoi d'un caractère par le µC. Mais la doc n'en parle pas du tout. D'ailleurs c'est quelque chose d'obsolète, donc je suis parti du principe qu'il n'y en avait pas.

    Peux-tu essayer la version basée sur les interruptions ?

  10. #50
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 110
    Points : 27
    Points
    27
    Par défaut
    Peux-tu essayer la version basée sur les interruptions ?
    J´ai essaye la version avec les interruptions et j´ai obtenu ceci:

    0:0
    1:1
    2:
    3:
    4:

    Apparement j´ai rate quelque chose lors du deboggage. Je vais reessayer.

    Le code du microcontrôleur avec interruption (RXCIE0 --->1):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    #include <avr/io.h>
    #include <avr/interrupt.h> 
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    // #include "uart.h"
    #include <avr/pgmspace.h>
    
    #define FOSC 8000000 // Clock Speed
    #define BAUD 115200UL
    
    // Berechnungen zur Baudrate:
    
    #define UBRR_VAL ((FOSC+BAUD*8)/(BAUD*16)-1)   // clever runden
    
    /***************************************************/
    
    volatile unsigned char data;
    
    /****************************************************/
    void USART_Init (unsigned int ubrr)
    {
      UBRR0H = (unsigned char)(ubrr>>8);
      UBRR0L = (unsigned char) ubrr;
      UBRR1H = (unsigned char)(ubrr>>8);
      UBRR1L = (unsigned char) ubrr;
      
    
      UCSR0B = (1<<RXEN0) | (1<<TXEN0) |(1<<RXCIE0)|(0<<TXCIE0);
      UCSR0C = (1<<USBS0) | (0<<UCSZ02)|(1<<UCSZ01)|(1<<UCSZ00);
      UCSR1B = (0<<RXEN1) | (0<<TXEN1) |(0<<RXCIE1)|(0<<TXCIE1);
      UCSR1C = (1<<USBS1) | (0<<UCSZ12)|(1<<UCSZ11)|(1<<UCSZ10);
      
    } 
    
    /**********************************************************/
    
    /*-- function receive USART0 --*/
    
    unsigned char USART0_Receive (void)
    {
        while(!(UCSR0A & (1<<RXC0)) ); // warten bis Zeichen verfuegbar
        
         return UDR0; // Zeichen aus UDR an Aufrufer zurueckgeben
    }
    
    
    /*-- function transmit USART0 --*/
    
    void USART0_Transmit (unsigned char data0)
    {
      while ( !(UCSR0A & (1<<UDRE0)) ); // warten bis Senden moeglich 
     
       UDR0 = data0;
    } 
    
    /*-- function receive USART1 --*/
    
    unsigned char USART1_Receive (void)
    {
      while(!(UCSR1A & (1<<RXC1)) );  // warten bis Zeichen verfuegbar
        
       return UDR1; // Zeichen aus UDR an Aufrufer zurueckgeben
    }
    
    /*-- function transmit USART1 --*/  
    
    void USART1_Transmit (unsigned char data1)
    {
      while ( !(UCSR1A & (1<<UDRE1)) ) ; 
        
       UDR1 = data1; // sende Zeichen 
    }
    
    /**********************************************************/
    
    /*-Aktivierung der Datenübertragung über RS485 von USART1-*/
    
     void RS485_Init (void)
    {
      DDRD = (1<<PD4)|(1<<PD3)|(1<<PD5);//Steuer- und Datenausgang aktivieren
      PORTD = (1<<PD4);	//auf Senden stellen (Aktivierung Datensendung)
    }
    
    ISR(USART0_RX_vect)
    
    {
      data = UDR0;		// Lecture du byte
      UDR0 = data;		// Renvoie du byte comme echo
     // UDR1 = data2;  // Transmission du byte au port serie RS485 
    }
    
    int main (void)
    
    { 
    
      unsigned char c ;
    
      USART_Init(UBRR_VAL) ;  // USART Initialisierung
      RS485_Init (); // serielle Schnittstelle USART1
      sei();
      while(1)
    
      {
    
     
    
    /*-- Test USART0 (Receive and Transmit) --*/
        
     //     USART0_Transmit('X');
    
      //  c = USART0_Receive();
    
       // USART0_Transmit(c);
    	 
    
    /*-- Test USART1 (Receive and Transmit) --*/
    
    //	USART1_Transmit( 'X' );
    //	c = USART0_Receive();
    //	USART1_Transmit(c);
    	
     
          
      }
    
    }

  11. #51
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    726
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 726
    Points : 1 645
    Points
    1 645
    Par défaut
    Pour moi ton code n'est pas correct car tu écris dans UDR0 sans savoir s'il est dispo en émission.
    Si tu regardes plus haut, je t'ai donné le code que je pense être correct (épuré de tout ce qui concerne l'usart1).
    L'important est que j'utilise l'ISR UDRE0 pour l'envoi, comme indiqué dans la doc.
    C'est une interruption répétée tant que UDRE0 (UDR0 dispo pour écriture) et UDRIE0 (interruption activée) sont vrais. Le principe est donc de stocker tout ce qui est reçu dans une file d'attente, et d'activer UDRIE0 pour lancer le transfert du contenu de cette file d'attente.
    Dans l'ISR UDRE0, on envoie 1 octet de la file d'attente et si elle est vide on désactive UDRIE0 car on n'a plus rien à envoyer, sinon l'ISR sera déclenchée à nouveau pour le prochain octet.
    D'après ce que j'ai lu dans la doc, ça me paraît une bonne manière de faire, surtout en préparation du programme final.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    #include <avr/io.h>
    #include <avr/interrupt.h> 
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdint.h> 
    
    
    #define FOSC 8000000 // Clock Speed
    #define BAUD 115200UL
    
    #define UBRR_VAL ((FOSC+BAUD*8)/(BAUD*16)-1)   // clever runden
    
    #define usart_buffer_max_size 50             
    
    char usart0_rx_buffer[usart_buffer_max_size];
    volatile uint8_t usart0_rx_buffer_size = 0;
    
    void USART_Init (unsigned int ubrr)
    {
      UBRR0H = (unsigned char)(ubrr>>8);
      UBRR0L = (unsigned char) ubrr;
      UCSR0B = (1<<RXEN0) | (0<<TXEN0) | (1<<RXCIE0) | (0<<UDRIE0);
      UCSR0C = (1<<USBS0) | (1<<UCSZ01) | (1<<UCSZ00);
    } 
    
    /* La fonction d´interruption de reception du byte */
    /* Cette fonction est active lorsque RXCIE0 = 1 */ 
    ISR(USART0_RX_vect)
    {
      char data = UDR0;
      /* Pour eviter ce depassement de buffer, il est possible de faire du flow control avec XOn/XOff par exemple */
      if (usart0_rx_buffer_size < usart0_rx_buffer_max_size)
      {
        usart0_rx_buffer[usart0_rx_buffer_size] = data;
        ++usart0_rx_buffer_size;
        /* Active l'emission de donnees, car on a des donnees dans la file */
        UCSR0B |= 1<<UDRIE0;
      }
    }
     
    /* La fonction d´interruption d´envoi de byte */
    /* Cette fonction est active lorsque UDRIE0 = 1 */ 
    ISR(USART0_UDRE_vect)
    {
      int i;
      if (usart0_rx_buffer_size == 0)
        /* S'il n'y a plus de données à envoyer on arrete l'emission */
        UCSR0B &= ~(1<<UDRIE0);
      else
      {
        UDR1 = usart0_rx_buffer[0];
        --usart0_rx_buffer_size;
        /* S'il n'y a plus de données à envoyer on arrete l'emission */
        if (usart0_rx_buffer_size == 0)
          UCSR0B &= ~(1<<UDRIE0);
        else
          /* Pour l'instant je gere la file de maniere bete et mechante, */
          /* mais ca pourrait etre un buffer cyclique */
          for (i = 0; i < usart0_rx_buffer_size; ++i)
            usart0_rx_buffer[i] = usart0_rx_buffer[i + 1];
      }
    }
    
    int main (void)
    { 
      USART_Init(UBRR_VAL) ;  // initialisation USART
      sei(); // Activation des  fonctions d´interruption
      while(1)
      {
      }
    }
    PS. Et je le répète, même si ça change rien au code généré, UCSZ02 n'est pas dans UCSR0C, il est dans UCSR0B.

    PS2. J'ai peut-être pas les bons noms d'interruptions, à toi de corriger.

    PS3. J'ai cherché des exemples sur internet, et apparemment ce que tu fais (transmettre directement depuis l'ISR de réception), c'est une pratique courante. Moi je complique inutilement pour l'instant, mais il est probable que tu aies besoin d'un buffer plus tard de toute façon.

  12. #52
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 110
    Points : 27
    Points
    27
    Par défaut
    Bonjour,

    Salut Hibernatus34: lorsque je deboggue le code c++ et le code c contenant les interruptions que tu as poste, j´obtiens ceci:

    0 :
    1 :
    2 :
    3 :
    4 :

    Je suis nocive dans le domaine du microcontrôleur et je suis vraiment impressionne par ta maniere de vite comprendre le fonctionnement. Je trouve que tu as bien programme la fonction d´interruption ISR(USART0_RX_vect). Par contre je ne comprends pas le travail de la fonction ISR(USART0_UDRE_vect). Apparement dans la fonction ISR(USART0_UDRE_vect) tu ne renvoies pas les bytes recus par le buffer UDR0 a nouveau sur le port serie. Ou du moins pêut-être que tu l´as fait, mais je n´apercois pas cela dans ton code.

  13. #53
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    726
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 726
    Points : 1 645
    Points
    1 645
    Par défaut
    Ne t'inquiète pas, moi je suis pire que novice, puisque non seulement je n'ai pas d'expérience là dedans, mais en plus je ne peux pas tester ce que j'écris !
    En fait il y a une faute de frappe dans mon code, j'ai écrit UDR1 à la place de UDR0 :
    UDR1 = usart0_rx_buffer[0]; devrait être UDR0 = usart0_rx_buffer[0];.
    Peux-tu tester avec cette correction ?

    De toute façon, comme j'ai dit dans mon PS3, mon code n'est probablement pas meilleur que le tien pour un simple écho.
    Sinon, le nom de l'interruption était le bon ? (USART0_UDRE_vect)

  14. #54
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 110
    Points : 27
    Points
    27
    Par défaut
    Sinon, le nom de l'interruption était le bon ? (USART0_UDRE_vect)
    En effet, le nom de l´interruption est juste.

    J´ai remplace
    UDR1 = usart0_rx_buffer[0];
    par
    UDR0 = usart0_rx_buffer[0];
    comme convenu. Mais j´obtiens toujours ceci:

    0 :
    1 :
    2 :
    3 :
    4 :

    Je vais encore effectuer des tests.

  15. #55
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    726
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 726
    Points : 1 645
    Points
    1 645
    Par défaut
    J'ai probablement mal compris la doc.
    Là j'ai pas mal de boulot, mais dès que j'ai un moment je m'y remets.
    Si tu vois une erreur dans mon code, n'hésite pas à corriger. Par exemple le UDR1 à la place de UDR0 tu aurais pu le voir sans moi.

  16. #56
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 110
    Points : 27
    Points
    27
    Par défaut
    Ok, pas de soucis . Merci tout de même pour ton soutien. Je vais continuer a chercher .

  17. #57
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 110
    Points : 27
    Points
    27
    Par défaut
    Salut,

    Bonjour hibernatus34, j´espere que ton week-end a ete agreable et que la semaine qui est en cours le sera aussi.

    Comme convenu, j´ai effectue a plusieurs reprises differents tests afin d´abtenir la synchronisation suivante:
    0 : 0
    1 : 1
    2 : 2
    3 : 3
    4 : 4
    .
    En fin de compte, le test a marcher tout a l´heure.
    J´ai utilise ton programme c et ainsi que le mien pour tester l´echo. Les resultats ont ete satisfaisants.

    Voici la version modifiee de ton code avec les interruptions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    #include <avr/io.h>
    #include <avr/interrupt.h> 
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <avr/pgmspace.h>
    
    #define FOSC 8000000 // Clock Speed
    #define BAUD 115200UL
    
    // Berechnungen zur Baudrate:
    
    #define UBRR_VAL ((FOSC+BAUD*8)/(BAUD*16)-1)   // clever runden
    
    #define usart0_rx_buffer_max_size 50 
    /***************************************************/
    
    char usart0_rx_buffer[usart0_rx_buffer_max_size];
    volatile uint8_t usart0_rx_buffer_size = 0;
    
    /****************************************************/
    void USART_Init (unsigned int ubrr)
    {
      UBRR0H = (unsigned char)(ubrr>>8);
      UBRR0L = (unsigned char) ubrr;
    //  UBRR1H = (unsigned char)(ubrr>>8);
    //  UBRR1L = (unsigned char) ubrr;
      
    
      UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0)|(0<<TXCIE0)|(0<<UCSZ02)|(0<<UDRIE0);
      UCSR0C = (1<<USBS0) | (1<<UCSZ01)|(1<<UCSZ00);
      
    } 
    
    /**********************************************************/
    
    /*-- function receive USART0 --*/
    
    unsigned char USART0_Receive (void)
    {
        while(!(UCSR0A & (1<<RXC0)) ); // warten bis Zeichen verfuegbar
        
         return UDR0; // Zeichen aus UDR an Aufrufer zurueckgeben
    }
    
    
    /*-- function transmit USART0 --*/
    
    void USART0_Transmit (unsigned char data0)
    {
      while ( !(UCSR0A & (1<<UDRE0)) ); // warten bis Senden moeglich 
     
       UDR0 = data0;
    } 
    
    /**********************************************************/
    
    /* La fonction d´interruption de reception du byte */
    /* Cette fonction est active lorsque RXCIE0 = 1 */ 
    ISR(USART0_RX_vect)
    {
      char data = UDR0;
      /* Pour eviter ce depassement de buffer, il est possible de faire du flow control avec XOn/XOff par exemple */
      if (usart0_rx_buffer_size < usart0_rx_buffer_max_size)
      {
        usart0_rx_buffer[usart0_rx_buffer_size] = data;
        ++usart0_rx_buffer_size;
        /* Active l'emission de donnees, car on a des donnees dans la file */
        UCSR0B |= 1<<UDRIE0;
      }
    }
     
    /* La fonction d´interruption d´envoi de byte */
    /* Cette fonction est active lorsque UDRIE0 = 1 */ 
    ISR(USART0_UDRE_vect)
    {
      int i;
      if (usart0_rx_buffer_size == 0)
        /* S'il n'y a plus de données à envoyer on arrete l'emission */
        UCSR0B &= ~(1<<UDRIE0);
      else
      {
        UDR0 = usart0_rx_buffer[0];
        --usart0_rx_buffer_size;
        /* S'il n'y a plus de données à envoyer on arrete l'emission */
        if (usart0_rx_buffer_size == 0)
          UCSR0B &= ~(1<<UDRIE0);
        else
          /* Pour l'instant je gere la file de maniere bete et mechante, */
          /* mais ca pourrait etre un buffer cyclique */
          for (i = 0; i < usart0_rx_buffer_size; ++i)
            usart0_rx_buffer[i] = usart0_rx_buffer[i + 1];
      }
    }
    
    
    int main (void)
    
    { 
      USART_Init(UBRR_VAL) ;  // USART Initialisierung
      
      sei();
      while(1)
    
      {   
      }
    
    }
    Le code pour le test de l´echo sans interruption:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    #include <avr/io.h>
    #include <avr/interrupt.h> 
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include <avr/pgmspace.h>
    
    #define FOSC 8000000 // Clock Speed
    #define BAUD 115200UL
    
    // Berechnungen zur Baudrate:
    
    #define UBRR_VAL ((FOSC+BAUD*8)/(BAUD*16)-1)   // clever runden
    
    #define usart0_rx_buffer_max_size 50 
    /***************************************************/
    
    char usart0_rx_buffer[usart0_rx_buffer_max_size];
    volatile uint8_t usart0_rx_buffer_size = 0;
    
    /****************************************************/
    void USART_Init (unsigned int ubrr)
    {
      UBRR0H = (unsigned char)(ubrr>>8);
      UBRR0L = (unsigned char) ubrr;
    
      
    
      UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(0<<RXCIE0)|(0<<TXCIE0)|(0<<UCSZ02)|(0<<UDRIE0);
      UCSR0C = (1<<USBS0) | (1<<UCSZ01)|(1<<UCSZ00);
    
      
    } 
    
    /**********************************************************/
    
    /*-- function receive USART0 --*/
    
    unsigned char USART0_Receive (void)
    {
        while(!(UCSR0A & (1<<RXC0)) ); // warten bis Zeichen verfuegbar
        
         return UDR0; // Zeichen aus UDR an Aufrufer zurueckgeben
    }
    
    
    /*-- function transmit USART0 --*/
    
    void USART0_Transmit (unsigned char data0)
    {
      while ( !(UCSR0A & (1<<UDRE0)) ); // warten bis Senden moeglich 
     
       UDR0 = data0;
    } 
    
    /**********************************************************/
    
    int main (void)
    
    { 
    
      unsigned char c ;
    
      USART_Init(UBRR_VAL) ;  // USART Initialisierung
    //  sei();
      while(1)
    
      {
    
    /*-- Test USART0 (Receive and Transmit) --*/
        
     //     USART0_Transmit('X');
    
       c = USART0_Receive();
    
       USART0_Transmit(c);
    	       
      }
    
    }
    Test d´echo avec interruption :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    #include <avr/io.h>
    #include <avr/interrupt.h> 
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include <avr/pgmspace.h>
    
    #define FOSC 8000000 // Clock Speed
    #define BAUD 115200UL
    
    // Berechnungen zur Baudrate:
    
    #define UBRR_VAL ((FOSC+BAUD*8)/(BAUD*16)-1)   // clever runden
    
    #define usart0_rx_buffer_max_size 50 
    /***************************************************/
    
    char usart0_rx_buffer[usart0_rx_buffer_max_size];
    volatile uint8_t usart0_rx_buffer_size = 0;
    
    /****************************************************/
    void USART_Init (unsigned int ubrr)
    {
      UBRR0H = (unsigned char)(ubrr>>8);
      UBRR0L = (unsigned char) ubrr;
    
      
    
      UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0)|(0<<TXCIE0)|(0<<UCSZ02)|(0<<UDRIE0);
      UCSR0C = (1<<USBS0) | (1<<UCSZ01)|(1<<UCSZ00);
    
      
    } 
    
    /**********************************************************/
    
    /*-- function receive USART0 --*/
    
    unsigned char USART0_Receive (void)
    {
        while(!(UCSR0A & (1<<RXC0)) ); // warten bis Zeichen verfuegbar
        
         return UDR0; // Zeichen aus UDR an Aufrufer zurueckgeben
    }
    
    
    /*-- function transmit USART0 --*/
    
    void USART0_Transmit (unsigned char data0)
    {
      while ( !(UCSR0A & (1<<UDRE0)) ); // warten bis Senden moeglich 
     
       UDR0 = data0;
    } 
    
    /**********************************************************/
    
    
    
    
    ISR(USART0_RX_vect)
    
    {
      char data;
      data = UDR0;		// Lecture du byte
      UDR0 = data;		// Renvoie du byte comme echo
    
     
    }
    
    
    int main (void)
    
    { 
    
    
      USART_Init(UBRR_VAL) ;  // USART Initialisierung
    //  sei();
      while(1)
    
      {	       
      }
    
    }
    .

    En bref les testes avec les codes ci-dessus ont ete un succes .

    Peut-on des maintenant passer a l´envoi des positions x et y au microcontrôleur ? Qu´en penses-tu ? C´est clair que le programme d´envoi des positions x et y doit être modifie.

    Merci pour ton aide.

  18. #58
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 110
    Points : 27
    Points
    27
    Par défaut
    salut,

    Sinon, pour le programme complet, il faut que je relise un peu ce qu'on avait dit.
    Qu'est-ce qui est le mieux pour toi ?
    - Que le PC envoie tout déjà formaté comme "#2C\r" ?
    - Ou bien que le PC envoie seulement X,Y et que ça soit le µC qui transforme ça en 2 messages ?
    Je desire que le PC envoie tout au microntrôleur deja formate sous la forme "#2C\r".

    J´ai modifie ton code c++ en tenant compte du fichier texte contenant les positions x et y afin de tester les fonctions WriteFile et ReadFile. Mais je ne m´en sors pas. Pourrais-tu me filer un coup de pouce s´il te plaît ?

    Par ailleurs je ne sais pas comment je pourrais formater les positions x et y sous la forme "#2C\r". S´il te plaît, aide moi.

    Merci d´avance.

    code d´envoi des positions x et y.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    #include <fstream>
    #include <string>
    #include <vector>
    #include <iostream>
    #include <sstream>
    #include <Windows.h>
    
    using namespace std;
    
    string AttendEtLitTout(HANDLE h)
    {
    	COMSTAT			stat;
    	vector<char>	s;
    	DWORD sizeRead;
    
    	Sleep(500);
    	ClearCommError(h, NULL, &stat);
    	if (stat.cbInQue > 0)
    	{
    		s.resize(stat.cbInQue);
    		ReadFile(h, s.data(), s.size(), &sizeRead, NULL);
    	}
    	return string(s.begin(), s.end());
    }
    
    int main(void)
    {
        ifstream file("koordinaten.txt", ios::in | ios::binary);
    	string line;
    	if (!file)
    	{
    		cout << "Erreur: Impossible d´ouvrir le fichier en mode lecture" << endl;
    		return 1;
    	}
        COMMTIMEOUTS timeouts = { 0 };
    	HANDLE h = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    	if (h == INVALID_HANDLE_VALUE)
    	{
    		cout << "Erreur: Impossible d´ouvrir le port série" << endl;
    		return 1;
    	}
     	DCB dcb = { 0 };
    	BOOL dcbOk = GetCommState(h, &dcb);
    	dcb.BaudRate = CBR_115200;
    	dcb.ByteSize = 8;
    	dcb.Parity = NOPARITY;
     	dcb.StopBits = TWOSTOPBITS;
    	dcbOk = SetCommState(h, &dcb);
    	timeouts.ReadIntervalTimeout = 200;
    	timeouts.ReadTotalTimeoutMultiplier = 200;
    	timeouts.ReadTotalTimeoutConstant = 200;
    	timeouts.WriteTotalTimeoutMultiplier = 200;
    	timeouts.WriteTotalTimeoutConstant = 200;
    	if (!SetCommTimeouts(h, &timeouts))
    		return 1;
    
    /*  Extraction et Conversion des positions X et Y */
    
    // Lecture ligne par ligne
     while (getline(file, line))
    	{
         int x;					// x, y du texte
         int y;
         int x_steps;			// x, y en pas moteur
         int y_steps;
         stringstream input;		// flux d'entrée (une ligne du texte)
         stringstream output_x;	// flux de sortie (une paire de coordonnées)
         stringstream output_y;
         stringstream input_x;	// une paire de coordonnées
         stringstream input_y;
         int x1;
         int y1;
    
        // Une ligne devient un flux d'entrée
         input.str(line);
        // Extraction du X et du Y.
         if (input.get() != 'X')
              continue;
         input >> x;
         if (input.get() != 'Y')
              continue;
          input >> y;
        // Conversion de la position en pas de moteur
        // J'ai rendu le calcul compatible avec le type int. (et je le trouve plus lisible)
          x_steps = x * 127 / 500;
          y_steps = y * 127 / 500;
    
    /* Writting to the serial port */
         DWORD byteswritten ;
    
         output_x << x_steps;	// TODO: Ne manque-t-il pas un terminateur ou un cadrage ?
         string s_x = output_x.str(); //string s(output_x.str());
            for (size_t i = 0; i < s_x.size(); ++i)
            {
            if (!WriteFile(h, &s_x[i], 1, &byteswritten, NULL))
                return 2;
            cout << s_x[i] << " : " << AttendEtLitTout(h) << endl;
            }
    
            output_y << y_steps;	// TODO: Ne manque-t-il pas un terminateur ou un cadrage ?
            string s_y = output_y.str(); //string s(output_y.str());
            for (size_t j = 0; j < s_y.size(); ++j)
            {
            if (!WriteFile(h, &s_y[j], 1, &byteswritten, NULL));
                return 3;
            cout << s_y[j] << " : " << AttendEtLitTout(h) << endl;
            }
    
    /*
    	// Test de l'écho
    	for (int i = 0; i < 10; ++i)
    	{
    		char sentChar = '0' + i;
    		DWORD sizeWritten;
    		if (!WriteFile(h, &sentChar, 1, &sizeWritten, 0))
    			return 1;
    		cout << sentChar << " : " << AttendEtLitTout(h) << endl;
    	} */
    
    	}
    	CloseHandle(h);
    	return 0;
    }

  19. #59
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    726
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 726
    Points : 1 645
    Points
    1 645
    Par défaut
    Salut,

    Content de voir que ça fonctionne. Si tu sais quelle était mon erreur, je serais curieux de savoir.

    Sinon, pour le programme final, il vaut mieux se baser sur la toute 1ère version que j'ai postée plutôt que sur le test de l'écho qui est bâclé. (je pense à la fonction AttendEtLitTout que je vois en haut de ton code)

    Avant de l'écrire, j'aimerais savoir comment on sait si le moteur est prêt à recevoir une commande, ou s'il a bien effectué la commande demandée.
    Par exemple :
    - Est-ce qu'il répond que la commande est prise en compte ?
    - Est-ce qu'il envoie un message en fin de rotation ?
    - Est-ce qu'il peut répondre "commande invalide", remettre à zéro son buffer de commande ?
    - Est-ce qu'on peut l'interroger sur sa disponibilité ou sa position actuelle ?
    - Est-ce qu'il a un contrôle du flux comme RTS/CTS ou XOn/XOff ?
    etc.


    PS. Rassure-moi, le test de l'écho fonctionnait à tous les coups à la fin ? Il n'est pas question de faire du bancal, même si dans le principe mon test l'est, puisqu'il dépend d'un timing pour la réponse, mais à 500 ms d'attente si ça buggue ne serait-ce qu'une fois sur 100 c'est qu'on fait quelque chose de travers.

  20. #60
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 110
    Points : 27
    Points
    27
    Par défaut
    Salut,

    Si tu sais quelle était mon erreur, je serais curieux de savoir.
    Reponse: Disons que c´est moi qui ai fait n´importe quoi lors du debogguage. Ton code c possedait seulement des erreurs de syntaxe. En realite ton raisonnement sur les fonctions d´interruption etait correct.

    Avant de l'écrire, j'aimerais savoir comment on sait si le moteur est prêt à recevoir une commande, ou s'il a bien effectué la commande demandée.
    Par exemple :
    - Est-ce qu'il répond que la commande est prise en compte ?
    - Est-ce qu'il envoie un message en fin de rotation ?
    - Est-ce qu'il peut répondre "commande invalide", remettre à zéro son buffer de commande ?
    - Est-ce qu'on peut l'interroger sur sa disponibilité ou sa position actuelle ?
    - Est-ce qu'il a un contrôle du flux comme RTS/CTS ou XOn/XOff ?
    etc.
    - Est-ce qu'il répond que la commande est prise en compte ?
    Reponse: je ne crois pas. Mais le moteur SMCI33-2 accepte par definition le protocole suivant:
    * Debut de l´instruction: #
    * Adresse du moteur: 1 a 255
    * Ordre de mission: Exemple: A , c, C, i ...etc
    * Fin de l´instruction: \r
    * Presence de guillemets au debut et a la fin du protocole. Exemple: "#2A\r"

    Pour le demarrage du moteur, le caractere 'A' est indispensable.( "#2A\r")

    - Est-ce qu'il envoie un message en fin de rotation ?
    Reponse: aucune idee. Par contre avec l´instruction "#2S\r", on peut stopper le moteur pas a pas. 'S' ---> Arrêt du moteur

    Avec le caractere 'W', on peut definir le nombre de repetition.
    Exemple: "#2W\r" ---> une repetition
    "#2W2\r" ---> deux repetitions

    - Est-ce qu'on peut l'interroger sur sa disponibilité ou sa position actuelle ?
    Reponse: oui, on peut l´interroger sur sa position actuelle.
    l´instruction est : "#2C\R", C ---> Renvoie la position actuelle

    - Est-ce qu'il a un contrôle du flux comme RTS/CTS ou XOn/XOff ?
    Reponse: Je ne crois pas.

    - Est-ce qu'il peut répondre "commande invalide", remettre à zéro son buffer de commande ?
    Reponse: Oui
    'c' --------> Remettre la position du moteur a zero. Exemple ----> "#2c\r"
    '?' --------> Commande invalide. Exemple -----> "#2?\r"

    - Mode de deplacement ---------> 'p'. ("#2p2\r")
    - Distance a parcourrir ----------> 's'. ("#2s100\r"), 100 est la distance

    J´espere que j´ai reponsu a tes question. En piece jointe se trouve le manuel de programmation du moteur pas a pas.
    Images attachées Images attachées

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 30/04/2010, 21h24
  2. Réponses: 3
    Dernier message: 26/10/2009, 13h32
  3. Lecture d´un fichier texte .
    Par pilouface dans le forum C
    Réponses: 5
    Dernier message: 20/01/2006, 23h48
  4. importation d'un fichier texte vers excel
    Par darkpocket dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 07/01/2005, 11h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo