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. #61
    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
    Je parle des réponses du moteur, donc à priori pas des messages de la forme "#2x\r", mais "#1x\r" (en considérant que ton µC prenne le numéro 1).
    Non ?

    En fait, je voulais savoir si le moteur répondait aux commandes par un acquittement, un peu comme notre écho. Il y a des machines qui répondent ACK/NAK pour des commandes à sens unique (sans retour de données), il y en a aussi qui répondent quelque chose longtemps après avoir reçu la commande, car l'opération a pris du temps (mécanique), etc.

    Mais de toute façon je ne pourrai regarder ça que demain ou après-demain, donc je jetterai un oeil à la doc d'ici là.

  2. #62
    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,

    Je parle des réponses du moteur, donc à priori pas des messages de la forme "#2x\r", mais "#1x\r" (en considérant que ton µC prenne le numéro 1).
    Non ?
    Les chiffres 1 et 2 des messages "#2x\r" et "#1x\r" representent l´adresse de deux moteurs de commande different, et non celui du µC. 1 represente l´adresse d´un moteur de commande et 2 represente l´adresse de l´autre moteur de commande. Le µC quant a lui sert tout simplement de plateforme afin de recevoir les positions x et y envoyes par le pc et ensuite le µC se chargera d´envoyer les positions recues a deux moteurs de commande. Un moteur de commande recevra uniquement les positions x et l´autre moteur receptionera seulement les positions y. Ainsi la communication entre le µC et les deux moteurs de commande s´etabliera a partir du 2ieme port serie RS485 (USART1) du µC. Pour cela, j´ai bricole et teste un câble permettant de connecter le µC et les deux moteurs de commandes. un bout du câble possede une entree et l´autre bout a ete multiplie et possede deux sorties. Le bout detenant l´entree est connecte a l´USART1 du µC et le bout de câble possedant deux sorties est connecte aux deux moteurs de commandes . Les deux moteurs de commande sont quant a eux connectes a deux moteurs pas a pas identiques via quatre fils de bobines.

    Bref je tenais tout simplement a te decrire l´autre partie de mon travail. Mais a ce que je sache, je ne pense pas que les deux moteurs pas a pas que j´utilise retourne des reponses. La marque de mes moteurs pas a pas est la suivante: QMot.eu 50-0035
    QSH5718-51-28-101

    Comme moteur de commande, j´utilise deux moteurs de commande identique de nanotec nommes SMCI33-2 .

    Bonne soiree.

  3. #63
    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
    OK. Je pensais que c'était comme certaines machines qui utilisent l'adresse 1 par défaut pour le maître, et 2, 3, 4... pour les machines. J'avais vu ça sur des monnayeurs par exemple.
    J'ai pas encore lu la doc, cet après-midi peut-être.

  4. #64
    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,

    Je pensais que c'était comme certaines machines qui utilisent l'adresse 1 par défaut pour le maître, et 2, 3, 4... pour les machines. J'avais vu ça sur des monnayeurs par exemple.
    En fait les moteurs pas a pas (SMCI33-2) de nanotec que je dispose, possede tous le chiffre 1 comme adresse par defaut. Plus tard il est possible de modifier l´adresse d´un moteur pas a pas a l´aide d´un software gratuit de nanotec qui s´appelle NAnoPRO. Ce software est telechargeable via le site internet de nanotec. De plus les moteurs pas a pas que j´utilise peuvent prendre les adresses comprises entre 1 et 255. Dans mon cas, j´ai change les adresses de mes deux moteurs pas a pas et j´ai choisis comme adresse les chiffres 2 et 3.

  5. #65
    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 hibernatus34,

    as-tu fait des progres avec la doc ? Ou es-tu encore tres occupe ? J´essaie de mon côte d´ameliorer la configuration du microcontrôleur.

    Bon apres midi.

  6. #66
    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,

    Je suis désolé, mais j'ai eu plus de boulot que prévu.
    Je viens de jeter un oeil, et les réponses à mes questions sont en page 10 de la doc, dans le paragraphe "Controller response".
    On peut transférer bêtement ces réponses vers le PC pour les gérer plus facilement, mais du coup à quoi servira le µC, à part fournir son interface RS-485 ?
    Ce projet est un exercice de style ou bien il répond à un vrai besoin ?

    J'aimerais t'aider aujourd'hui mais je n'aurai probablement pas le temps. Ca attendra la semaine prochaine, si personne d'autre ne t'aide d'ici là.

  7. #67
    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,

    On peut transférer bêtement ces réponses vers le PC pour les gérer plus facilement, mais du coup à quoi servira le µC, à part fournir son interface RS-485 ?
    Reponse: le µC receptionne par son port serie RS232 (USART0) les positions x, y envoyes par le PC. Ensuite le µC doit envoyer par son port serie RS485 (USART1) les positions recues aux deux moteurs de commande(SMCi33-2 ). les moteurs de commande sont identiques.

    Ce projet est un exercice de style ou bien il répond à un vrai besoin ?
    Reponse: Le projet repond a un vrai besoin.

    J'aimerais t'aider aujourd'hui mais je n'aurai probablement pas le temps. Ca attendra la semaine prochaine, si personne d'autre ne t'aide d'ici là.
    Je te remercie deja pour la peine que tu te donnes pour m´aider. Franchement je te dis merci. C´est pas grave si tu ne trouves pas le temps aujourd´hui pour m´aider. Mais j´attends tout de même ton intervention. Je vais continuer a configurer la communication entre l´USART0 et l´USART1 du µC.

  8. #68
    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
    Bonsoir Hibernatus,

    J´ai essaye vendredi d´effectuer un echo test en envoyant les position x, y vers le µC, afin de verifier l´envoi des donnees. Helas sa n´a pas marche. Voici le programme:

    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
    #include <fstream>
    #include <string>
    #include <iostream>
    #include <sstream>
    #include <Windows.h>
    
    using namespace std;
    
    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;
    	}
    	// Ouverture du port COM (c'est votre code tel quel)
    	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;
    	dcb.fOutxCtsFlow = FALSE;	// Pourquoi ça et puis ensuite un test manuel du CTS ?
    	dcbOk = SetCommState(h, &dcb);
    	timeouts.ReadIntervalTimeout = 10;
    	timeouts.ReadTotalTimeoutMultiplier = 10;
    	timeouts.ReadTotalTimeoutConstant = 10;
    	timeouts.WriteTotalTimeoutMultiplier = 10;
    	timeouts.WriteTotalTimeoutConstant = 10;
    	if (!SetCommTimeouts(h, &timeouts))
    		return 1;
    
    	// 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;
    
    		// 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 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;
    
    		// Envoi des coordonnées par le port série, à compléter car votre code ne permet pas de savoir ce que vous deviez réellement faire.
    
    		string receivedChar ;
    		DWORD bytesWritten;
    		DWORD bytesRead;
    
    		output_x << x_steps;	// TODO: Ne manque-t-il pas un terminateur ou un cadrage ?
    		string s_x = output_x.str() ; // string s_x(output_x);
    		for (size_t i = 0; i < s_x.size(); ++i)
    	    {
    		 if (!WriteFile(h, &s_x[i], 1, &bytesWritten, 0))
    			return 1;
    		 if (!ReadFile(h, &receivedChar, 1, &bytesRead, 0) || bytesRead != 1)
    			cout << s_x[i] << " : pas de reponse ?" << endl;
    		 else
    			cout << s_x[i] << " = " << receivedChar << endl;
    	    }
    
    
    	    output_y << y_steps ; // TODO: Ne manque-t-il pas un terminateur ou un cadrage ?
            string s_y = output_y.str() ; // string s_y(output_y);
    
    	for (size_t j = 0; j < s_y.size(); ++j)
    	 {
    		if (!WriteFile(h, &s_y[j], 1, &bytesWritten, 0))
    			return 1;
    		if (!ReadFile(h, &receivedChar, 1, &bytesRead, 0) || bytesRead != 1)
    			cout << s_y[j] << " : pas de reponse ?" << endl;
    		else
    			cout << s_y[j] << " = " << receivedChar << endl;
    	 }
    
    		// TODO: Et là, il ne faut pas attendre un retour ?
    	}
    	CloseHandle(h);
    	return 0;
    }
    Je desire transferer tout simplement les positions du fichier texte sur le port serie en direction du µC sans toutefois les formates avant l´envoi. Une fois que le µC aura recu les positions, il se chargera d´envoyer les positions vers les moteurs de commande. Biensûr le µC devra envoyer les positions en tenant compte du protocôle de transfert que les deux moteurs de commandes comprenent.

    Bonne soiree.

  9. #69
    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
    Reponse: le µC receptionne par son port serie RS232 (USART0) les positions x, y envoyes par le PC. Ensuite le µC doit envoyer par son port serie RS485 (USART1) les positions recues aux deux moteurs de commande(SMCi33-2 ). les moteurs de commande sont identiques.
    OK, mais là tu pourrais acheter une carte RS485 pour ton PC et tu n'aurais plus besoin du µC. Donc je ne comprends toujours pas l'intérêt.

    Je desire transferer tout simplement les positions du fichier texte sur le port serie en direction du µC sans toutefois les formates avant l´envoi. Une fois que le µC aura recu les positions, il se chargera d´envoyer les positions vers les moteurs de commande. Biensûr le µC devra envoyer les positions en tenant compte du protocôle de transfert que les deux moteurs de commandes comprenent.
    Tu as changé d'avis alors ?
    Que veux-tu dans la version finale ?

  10. #70
    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,

    OK, mais là tu pourrais acheter une carte RS485 pour ton PC et tu n'aurais plus besoin du µC. Donc je ne comprends toujours pas l'intérêt.
    Reponse : En fait mon encadreur veut a tout prix que le microcontrôleur recoivent les positions envoyes par le pc. Ensuite le µC se chargera du formatage des positions et il les transfera aux moteurs de commandes. Les moteurs de commande sont quant-a elles connectes a deux moteurs disposes sur deux axes (Axe x et y). l´axe X et Y representent le repere orthonorme d´une platine. Une fois que les deux moteurs de commandes receptioneront les positions, alors les moteurs respectifs de chaque axe se mettront en marche et la platine se deplacera dans le repere orthonorme. Une fois cela realise, il va falloir programmer le µC, afin de contrôler si les positions envoyes au µC correspondent avec les distances parcourues par la platine sur l´axe x et y. J´aurais besoin d´un encodeur pour verifier cela. Voila en bref la raison qui me pousse a bosser avec le µC.

    Tu as changé d'avis alors ?
    Que veux-tu dans la version finale ?
    Reponse: Oui, j´ai change d´avis et j´aimerais tout simplement dans la version finale envoyer les positions du fichier texte sous forme de byte au µC. Le µC se chargera d´envoyer aux moteurs de commande les positions en tenant compte du protocôle d´envoi que comprennent les moteurs de commande.

  11. #71
    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
    Je viens de réaliser que pour l'écho tu n'as pas récupéré le code où j'utilisais l'interruption sur UDRE0. Mais tu auras besoin de l'interruption sur UDRE1 pour le programme final, donc c'est mal parti si tu n'as pas pu faire fonctionner un programme de test l'utilisant.

  12. #72
    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
    Je viens de réaliser que pour l'écho tu n'as pas récupéré le code où j'utilisais l'interruption sur UDRE0. Mais tu auras besoin de l'interruption sur UDRE1 pour le programme final
    Reponse: Si, j´ai récupéré le code où tu utilisais l'interruption sur UDRE0. Je l´ai teste lors du test de l´echo et le resultat etait satisfaisant. Je comptais bien utiliser aussi l´interruption sur UDRE1 pour le programme final.

  13. #73
    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
    OK, donc il suffit de remplacer la file de transfert par un buffer de commande.
    Je te rappelle que dans ton fichier texte il y a des valeurs supérieures à 255 même après conversion en pas moteur, donc il ne faut pas considérer que X ou Y peut tenir dans un octet.
    Le format des commandes est totalement libre, mais j'aime bien l'ASCII pour la possibilité d'avoir un caractère de contrôle à tout moment.
    Donc je te propose :
    - "\n" : démarre une commande (vide le buffer)
    - "42,51" : X et Y en ASCII, séparés par une virgule
    - "\r" : termine et exécute une commande
    Si une commande reçue est invalide, on renvoie NAK sur UDR0.
    Sinon on exécute la commande sur le moteur et on renvoie ACK sur UDR0.

    Dans le µC :
    - à la réception d'un \n je vide le buffer.
    - à la réception de \r je traite la commande (en différé si c'est long, mais je ne pense pas que ça soit nécessaire), j'alimente une file d'émission pour UDR1 et je vide le buffer.
    - à la réception d'autre chose je stocke dans le buffer. (et si ça dépasse la taille du buffer je ne fais rien)
    - J'émets sur UDR1 le contenu de la file, de la même manière que dans mon écho. (interruption sur UDRE1)

    Sur le PC :
    - pour chaque paire x,y j'envoie "\n42,51\r" puis j'attends la réponse ACK ou NAK.

    C'est pas forcément parfait, je rappelle que j'ai peu d'expérience, mais ça devrait fonctionner.

  14. #74
    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
    C'est pas forcément parfait, je rappelle que j'ai peu d'expérience, mais ça devrait fonctionner.
    Wow, je crois que ta proposition est superbe et j´aimerais qu´on la teste.

    Merci.

  15. #75
    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
    Pas la peine de me flatter.
    Voici du code approximatif comme d'habitude, car je n'ai pas de compilo C++ aujourd'hui non plus :

    Microcontrôleur :
    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
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    #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 64u
    #define usart_command_max_size 10
    
    char usart_command[usart_command_max_size + 1] = {0};
    char usart0_tx_buffer[usart_buffer_max_size];
    char usart1_tx_buffer[usart_buffer_max_size];
    volatile uint8_t usart_command_size = 0;
    volatile uint8_t usart0_tx_buffer_size = 0;
    volatile uint8_t usart0_tx_buffer_start = 0;
    volatile uint8_t usart1_tx_buffer_size = 0;
    volatile uint8_t usart1_tx_buffer_start = 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) | (0<<TXEN0) | (1<<RXCIE0) | (0<<UDRIE0);
      UCSR0C = (1<<USBS0) | (1<<UCSZ01) | (1<<UCSZ00);
      UCSR1B = (1<<RXEN1) | (0<<TXEN1) | (1<<RXCIE1) | (0<<UDRIE1);
      UCSR1C = (1<<USBS1) | (1<<UCSZ11) | (1<<UCSZ10);
    } 
    
    /* Ajout dans une file */
    void USART0_QueueIn(char c)
    {
      int i;
    
      if (usart0_tx_buffer_size < usart_buffer_max_size)
      {
        i = (usart0_tx_buffer_size + usart0_tx_buffer_start) % usart_buffer_max_size;
        usart0_tx_buffer[i] = data;
        ++usart0_tx_buffer_size;
      }
    }
    
    /* Sortie d'une file */
    /* J'utilise le caractère nul pour dire qu'il ne reste rien dans la file */
    /* Ca signifie que la file n'est pas prête à recevoir du binaire */
    char USART0_QueueOut(void)
    {
      char c;
    
      if (usart0_tx_buffer_size == 0)
        return 0;
      c = usart0_tx_buffer[usart0_tx_buffer_start];
      --usart0_tx_buffer_size;
      usart0_tx_buffer_start = (usart0_tx_buffer_start + 1) % usart_buffer_max_size;
      return c;
    }
    
    /* Ajout dans une file */
    void USART1_QueueIn(char c)
    {
      int i;
    
      if (usart1_tx_buffer_size < usart_buffer_max_size)
      {
        i = (usart1_tx_buffer_size + usart1_tx_buffer_start) % usart_buffer_max_size;
        usart1_tx_buffer[i] = data;
        ++usart1_tx_buffer_size;
      }
    }
    
    /* Sortie d'une file */
    /* J'utilise le caractère nul pour dire qu'il ne reste rien dans la file */
    /* Ca signifie que la file n'est pas prête à recevoir du binaire */
    char USART1_QueueOut(void)
    {
      char c;
    
      if (usart1_tx_buffer_size == 0)
        return 0;
      c = usart1_tx_buffer[usart1_tx_buffer_start];
      --usart1_tx_buffer_size;
      usart1_tx_buffer_start = (usart1_tx_buffer_start + 1) % usart_buffer_max_size;
      return c;
    }
    
    /* Envoie une réponse sur l'USART0 via la file de transfert */
    static void USART0_Send(const char *s)
    {
      int i;
      
      for (i = 0; s[i] != 0; ++i)
        USART0_QueueIn(s[i]);
      if (usart0_tx_buffer_size > 0)
        UCSR0B |= 1 << UDRIE0;
    }
    
    /* Envoie une commande sur l'USART1 via la file de transfert */
    static void USART1_Send(const char *s)
    {
      int i;
      
      for (i = 0; s[i] != 0; ++i)
        USART1_QueueIn(s[i]);
      if (usart1_tx_buffer_size > 0)
        UCSR1B |= 1 << UDRIE1;
    }
    
    /* La fonction d´interruption de reception du byte */
    /* Cette fonction est active lorsque RXCIE0 = 1 */ 
    ISR(USART0_RX_vect)
    {
      char data;
      int i;
      int x;
      int y;
      char x_moteur[12];
      char y_moteur[12];
    
      data = UDR0;
      if (data == '\r')
      {
        /* Traitement de la commande : */
        /* On extrait le X et le Y, puis on génère les commandes moteurs */
        for (i = 0; i < usart_command_size; ++i)
          if (usart_command[i] == ',')
            break;
        if (i <= 0 || i >= usart_command_size - 1)
        {
          /* On n'a pas trouvé la virgule au milieu de la chaîne -> erreur */
          USART_Send("\x15");  /* NAK */
          usart_command_size = 0;
          return;
        }
        /* Je transforme volontairement x et y en int pour te permettre des contrôles ou des calculs */
        usart_command[i] = 0;
        usart_command[usart_command_size] = 0;
        x = atoi(usart_command);
        y = atoi(usart_command + i + 1);
        usart_command_size = 0;
        /* Envoi des commandes moteurs */
        itoa(x, x_moteur, 10);
        itoa(y, y_moteur, 10);
        USART1_Send("#1s");
        USART1_Send(x_moteur);
        USART1_Send("\r");
        USART1_Send("#2s");
        USART1_Send(y_moteur);
        USART1_Send("\r");
        /* TODO:
        Le moteur répond par un écho pour confirmer la commande
        Il faut le gérer, mais pas directement ici, car ici on ne doit pas rester trop longtemps */
        USART0_Send("\x06");  /* ACK */
        return;
      }
      if (data == '\n')
      {
        /* Démarrage d'une nouvelle commande */
        usart_command_size = 0;
        return;
      }
      /* Quand on ne reçoit ni \r ni \n, on enregistre le caractère dans la commande */
      if (usart_command_size < usart_command_max_size)
      {
        usart_command[usart_command_size] = data;
        ++usart_command_size;
      }
    }
    
    /* La fonction d´interruption d´envoi de byte */
    /* Cette fonction est active lorsque UDRIE0 = 1 */
    ISR(USART0_UDRE_vect)
    {
      UDR0 = USART0_QueueOut();
      /* S'il n'y a plus de données à envoyer on arrete l'emission */
      if (usart0_tx_buffer_size == 0)
        UCSR0B &= ~(1 << UDRIE0);
    }
    
    /* La fonction d´interruption d´envoi de byte */
    /* Cette fonction est active lorsque UDRIE1 = 1 */
    ISR(USART1_UDRE_vect)
    {
      UDR1 = USART1_QueueOut();
      /* S'il n'y a plus de données à envoyer on arrete l'emission */
      if (usart1_tx_buffer_size == 0)
        UCSR1B &= ~(1 << UDRIE1);
    }
    
    int main (void)
    { 
      USART_Init(UBRR_VAL);
      sei();
      /* TODO: Ici il faut paramétrer les moteurs (mode de positionnement etc.) */
      while (1)
      {
      }
    }
    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
    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
    #include <fstream>
    #include <string>
    #include <iostream>
    #include <sstream>
    
    #include <Windows.h>
    
    using namespace std;
    
    // Envoie une commande caractère par caractère, et teste la réception d'un ACK
    static bool EnvoieCommande(HANDLE h, const char *s)
    {
    	DWORD	dummy;
    	char	c;
    
    	// S'il y avait des réponses à lire depuis la dernière commande,
    	// trop tard, on les supprime.
    	PurgeComm(h, PURGE_RXCLEAR);
    	for (int i = 0; s[i] != 0; ++i)
    		if (!WriteFile(h, s + i, 1, &dummy, 0))
    			return false;
    	if (!ReadFile(h, &c, 1, &dummy, 0))
    		return false;	// Time-out
    	return c == '\x06';	// ACK
    }
    
    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;
    	}
    	// Ouverture du port COM (c'est votre code tel quel)
    	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);
    	COMMTIMEOUTS timeouts = { 0 };
    	timeouts.ReadIntervalTimeout = 100;
    	timeouts.ReadTotalTimeoutMultiplier = 100;
    	timeouts.ReadTotalTimeoutConstant = 100;
    	timeouts.WriteTotalTimeoutMultiplier = 100;
    	timeouts.WriteTotalTimeoutConstant = 100;
    	if (!SetCommTimeouts(h, &timeouts))
    	{
    		cout << "Erreur: SetCommTimeouts" << endl;
    		return 1;
    	}
    	// 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;	// flux de sortie (une paire de coordonnées)
    
    		// 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 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;
    		// Envoi des coordonnées par le port série
    		output << '\n';
    		output << x_steps;
    		output << ',';
    		output << y_steps;
    		output << '\r';
    		cout << "Envoi de : " << output.str() << endl;
    		if (EnvoieCommande(h, output.str().c_str()))
    			cout << "OK" << endl;
    		else
    			cout << "ERREUR" << endl;
    	}
    	CloseHandle(h);
    	return 0;
    }
    Ca devrait te donner une idée de ce qu'il y a à faire.
    N'hésite pas à poser des questions et à corriger mes erreurs.

  16. #76
    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
    Pas la peine de me flatter.
    Reponse: Je dois bien le faire, car tu m´aides assez et je suis tres ravis. Franchement, j´ai fait d´enorme progres grâce a toi. Merci.

    Ca devrait te donner une idée de ce qu'il y a à faire.
    N'hésite pas à poser des questions et à corriger mes erreurs.
    Je vais effectuer le test tout de suite.

  17. #77
    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 en même temps lu et essaye de comprendre le programme du pc et du µC.

    Apres avoir lance le debuggage, l´IDE m´a signale plusieurs fautes. J´ai corriges les fautes, mais j´ai toutefois quelques questions.
    Code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void USART0_QueueIn(char c)
    {
      int i;
      char data;
      if (usart0_tx_buffer_size < usart0_tx_buffer_max_size)
      {
        i = (usart0_tx_buffer_size + usart0_tx_buffer_start) % usart0_tx_buffer_max_size;
        usart0_tx_buffer[i] = data;
        ++usart0_tx_buffer_size;
      }
    }
    La variable
    usart0_tx_buffer_max_size
    et
    usart1_tx_buffer_max_size
    n´etaient pas definis dans le programme du µC et j´aimerais que tu me communiques les valeurs qu´elles doivent contenir. Je leur ai attribue la valeur 64u, vu que c´est la valeur que contenait la variable usart_buffer_max_size avant le deboggage. Pourquoi avoir opte pour 64u et non 64 tout court.

    Tu as declare la variable i et ensuite definis comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    i = (usart0_tx_buffer_size + usart0_tx_buffer_start) % usart0_tx_buffer_max_size;
    La tu essais de donner le reste de la division de cette expression a la variable i.

    Au depart, usart0_tx_buffer_size = 0 et usart0_tx_buffer_start = 0. mais usart0_tx_buffer_max_size = 64u ou ???.

    Ensuite tu incrementes usart0_tx_buffer_size et les autres variables ne changent pas.

  18. #78
    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 en même temps lu et essaye de comprendre le programme du pc et du µC.

    Apres avoir lance le debuggage du programme du µC, l´IDE m´a signale plusieurs fautes. J´ai corriges les fautes, mais j´ai toutefois quelques questions.
    Code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void USART0_QueueIn(char c)
    {
      int i;
      char data;
      if (usart0_tx_buffer_size < usart0_tx_buffer_max_size)
      {
        i = (usart0_tx_buffer_size + usart0_tx_buffer_start) % usart0_tx_buffer_max_size;
        usart0_tx_buffer[i] = data;
        ++usart0_tx_buffer_size;
      }
    }
    La variable
    usart0_tx_buffer_max_size
    et
    usart1_tx_buffer_max_size
    n´etaient pas definis dans le programme du µC et j´aimerais que tu me communiques les valeurs qu´elles doivent contenir. Je leur ai attribue la valeur 64u, vu que c´est la valeur que contenait la variable usart_buffer_max_size avant le deboggage. Pourquoi avoir opte pour 64u et non 64 tout court.

    Tu as declare la variable i et ensuite definis comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    i = (usart0_tx_buffer_size + usart0_tx_buffer_start) % usart0_tx_buffer_max_size;
    La tu essais de donner le reste de la division de cette expression a la variable i.

    Au depart, usart0_tx_buffer_size = 0 et usart0_tx_buffer_start = 0. mais usart0_tx_buffer_max_size = 64u ou ???.

    Ensuite tu incrementes usart0_tx_buffer_size et les autres variables ne changent pas. Je me trompe ou bien mon raisonement est ok ? Bref je me demande bien pourquoi tu utilises la variable i de cette maniere !!!!

  19. #79
    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
    Hello,
    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
    /* Ajout dans une file */
    void USART0_QueueIn(char c)
    {
      int i;
      char data;
      if (usart0_tx_buffer_size < usart0_tx_buffer_max_size)
      {
        i = (usart0_tx_buffer_size + usart0_tx_buffer_start) % usart0_tx_buffer_max_size;
        usart0_tx_buffer[i] = data;
        ++usart0_tx_buffer_size;
      }
    }
    
    /* Sortie d'une file */
    /* J'utilise le caractère nul pour dire qu'il ne reste rien dans la file */
    /* Ca signifie que la file n'est pas prête à recevoir du binaire */
    char USART0_QueueOut(void)
    {
      char c;
    
      if (usart0_tx_buffer_size == 0)
        return 0;
      c = usart0_tx_buffer[usart0_tx_buffer_start];
      --usart0_tx_buffer_size;
      usart0_tx_buffer_start = (usart0_tx_buffer_start + 1) % usart0_tx_buffer_max_size;
      return c;
    }
    Qu´en penses-tu si je modifie les codes ci-dessus de la maniere suivante:
    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
    /* Ajout dans une file */
    void USART0_QueueIn(char c)
    {
      char data;
      if (usart0_tx_buffer_size < usart0_tx_buffer_max_size)
      {
        usart0_tx_buffer[++usart0_tx_buffer_size;] = data;
        ++usart0_tx_buffer_size;
      }
    }
    
    /* Sortie d'une file */
    /* J'utilise le caractère nul pour dire qu'il ne reste rien dans la file */
    /* Ca signifie que la file n'est pas prête à recevoir du binaire */
    char USART0_QueueOut(void)
    {
      char c;
      if (usart0_tx_buffer_size == 0)
        return 0;
      c = usart0_tx_buffer[usart0_tx_buffer_start];
      --usart0_tx_buffer_size;
      ++usart0_tx_buffer_start;
      return c;
    }
    Du moins je n´arrive pas a saisir l´impact de la variable i et l´impact de l´expression suivante : usart0_tx_buffer_start = (usart0_tx_buffer_start + 1) % usart0_tx_buffer_max_size; dans le programme.

  20. #80
    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
    Concernant les "...max_size" j'ai oublié en cours de route que j'en avais défini une pour les 2 buffers. Donc remplace usart0_tx_buffer_max_size et usart1_tx_buffer_max_size par usart_buffer_max_size.

    Concernant le "i", le modulo est là pour une bonne raison :
    Je veux gérer une file, c'est à dire un buffer où les premiers octets entrés sont les premiers sortis (FIFO).
    Pour ça j'implémente un buffer circulaire basique :
    http://fr.wikipedia.org/wiki/Buffer_circulaire

    La variable "..._start" (désolé pour les noms à rallonge, mais j'ai voulu respecter ton style) sert à connaître le début de la file dans le buffer.
    Donc, quand le 1er élément de la file sort, on avance "..._start" au lieu de décaler toutes les données du buffer.
    Maintenant, si tu prends un buffer de 8 octets, avec le début à la position 4, et tu le remplis de A, B, C, D... ça donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    0 1 2 3 4 5 6 7
    E F G H A B C D
            ^----------(start = 4)
    Tu vois que l'élément de la position 5 (F) est à la position 1, car 4 + 5 > 7.
    Comment tu transformes 9 en 1 ? 9 % 8 = 1.
    J'utilise 64u parce que c'est une puissance de 2 et les 2 opérandes seront non-signées, et je compte donc sur le fait que le compilo transformera l'opération en "& 63". (plus rapide)


    Donc évidemment ta correction ne fonctionnera pas.
    Sinon, j'ai corrigé mon code entre temps, il manquait un "+ 1" à la ligne 146.

    PS. J'ai corrigé vite fait le code du µC ci-dessus. Ca reste très sujet aux fautes de frappes, j'ai modifié dans le navigateur directement.

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 30/04/2010, 22h24
  2. Réponses: 3
    Dernier message: 26/10/2009, 14h32
  3. Lecture d´un fichier texte .
    Par pilouface dans le forum C
    Réponses: 5
    Dernier message: 21/01/2006, 00h48
  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, 12h47

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