Précédent   Forum du club des développeurs et IT Pro > Général Développement > Programmation système > Embarqué
Embarqué Forum d'entraide sur la programmation des systèmes embarqués
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 04/09/2012, 15h59   #61
Hibernatus34
Membre Expert
 
Inscription : août 2010
Messages : 533
Détails du profil
Informations forums :
Inscription : août 2010
Messages : 533
Points : 1 006
Points : 1 006
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à.
Hibernatus34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/09/2012, 16h58   #62
arthurdubois
Invité régulier
 
Homme arthur
Étudiant
Inscription : mars 2012
Messages : 110
Détails du profil
Informations personnelles :
Nom : Homme arthur
Localisation : Allemagne

Informations professionnelles :
Activité : Étudiant
Secteur : Enseignement

Informations forums :
Inscription : mars 2012
Messages : 110
Points : 9
Points : 9
Salut,

Citation:
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.
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/09/2012, 11h48   #63
Hibernatus34
Membre Expert
 
Inscription : août 2010
Messages : 533
Détails du profil
Informations forums :
Inscription : août 2010
Messages : 533
Points : 1 006
Points : 1 006
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.
Hibernatus34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/09/2012, 12h11   #64
arthurdubois
Invité régulier
 
Homme arthur
Étudiant
Inscription : mars 2012
Messages : 110
Détails du profil
Informations personnelles :
Nom : Homme arthur
Localisation : Allemagne

Informations professionnelles :
Activité : Étudiant
Secteur : Enseignement

Informations forums :
Inscription : mars 2012
Messages : 110
Points : 9
Points : 9
Bonjour,

Citation:
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.
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2012, 14h07   #65
arthurdubois
Invité régulier
 
Homme arthur
Étudiant
Inscription : mars 2012
Messages : 110
Détails du profil
Informations personnelles :
Nom : Homme arthur
Localisation : Allemagne

Informations professionnelles :
Activité : Étudiant
Secteur : Enseignement

Informations forums :
Inscription : mars 2012
Messages : 110
Points : 9
Points : 9
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.
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/09/2012, 09h58   #66
Hibernatus34
Membre Expert
 
Inscription : août 2010
Messages : 533
Détails du profil
Informations forums :
Inscription : août 2010
Messages : 533
Points : 1 006
Points : 1 006
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à.
Hibernatus34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/09/2012, 10h30   #67
arthurdubois
Invité régulier
 
Homme arthur
Étudiant
Inscription : mars 2012
Messages : 110
Détails du profil
Informations personnelles :
Nom : Homme arthur
Localisation : Allemagne

Informations professionnelles :
Activité : Étudiant
Secteur : Enseignement

Informations forums :
Inscription : mars 2012
Messages : 110
Points : 9
Points : 9
Bonjour,

Citation:
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.

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

Citation:
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.
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/09/2012, 20h19   #68
arthurdubois
Invité régulier
 
Homme arthur
Étudiant
Inscription : mars 2012
Messages : 110
Détails du profil
Informations personnelles :
Nom : Homme arthur
Localisation : Allemagne

Informations professionnelles :
Activité : Étudiant
Secteur : Enseignement

Informations forums :
Inscription : mars 2012
Messages : 110
Points : 9
Points : 9
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 :
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.
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/09/2012, 10h15   #69
Hibernatus34
Membre Expert
 
Inscription : août 2010
Messages : 533
Détails du profil
Informations forums :
Inscription : août 2010
Messages : 533
Points : 1 006
Points : 1 006
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.

Citation:
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 ?
Hibernatus34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/09/2012, 10h45   #70
arthurdubois
Invité régulier
 
Homme arthur
Étudiant
Inscription : mars 2012
Messages : 110
Détails du profil
Informations personnelles :
Nom : Homme arthur
Localisation : Allemagne

Informations professionnelles :
Activité : Étudiant
Secteur : Enseignement

Informations forums :
Inscription : mars 2012
Messages : 110
Points : 9
Points : 9
Bonjour,

Citation:
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.

Citation:
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.
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/09/2012, 11h24   #71
Hibernatus34
Membre Expert
 
Inscription : août 2010
Messages : 533
Détails du profil
Informations forums :
Inscription : août 2010
Messages : 533
Points : 1 006
Points : 1 006
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.
Hibernatus34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/09/2012, 11h32   #72
arthurdubois
Invité régulier
 
Homme arthur
Étudiant
Inscription : mars 2012
Messages : 110
Détails du profil
Informations personnelles :
Nom : Homme arthur
Localisation : Allemagne

Informations professionnelles :
Activité : Étudiant
Secteur : Enseignement

Informations forums :
Inscription : mars 2012
Messages : 110
Points : 9
Points : 9
Citation:
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.
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/09/2012, 12h02   #73
Hibernatus34
Membre Expert
 
Inscription : août 2010
Messages : 533
Détails du profil
Informations forums :
Inscription : août 2010
Messages : 533
Points : 1 006
Points : 1 006
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.
Hibernatus34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/09/2012, 12h11   #74
arthurdubois
Invité régulier
 
Homme arthur
Étudiant
Inscription : mars 2012
Messages : 110
Détails du profil
Informations personnelles :
Nom : Homme arthur
Localisation : Allemagne

Informations professionnelles :
Activité : Étudiant
Secteur : Enseignement

Informations forums :
Inscription : mars 2012
Messages : 110
Points : 9
Points : 9
Citation:
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.
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/09/2012, 16h34   #75
Hibernatus34
Membre Expert
 
Inscription : août 2010
Messages : 533
Détails du profil
Informations forums :
Inscription : août 2010
Messages : 533
Points : 1 006
Points : 1 006
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 :
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 :
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.
Hibernatus34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/09/2012, 17h00   #76
arthurdubois
Invité régulier
 
Homme arthur
Étudiant
Inscription : mars 2012
Messages : 110
Détails du profil
Informations personnelles :
Nom : Homme arthur
Localisation : Allemagne

Informations professionnelles :
Activité : Étudiant
Secteur : Enseignement

Informations forums :
Inscription : mars 2012
Messages : 110
Points : 9
Points : 9
Citation:
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.

Citation:
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.
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/09/2012, 12h25   #77
arthurdubois
Invité régulier
 
Homme arthur
Étudiant
Inscription : mars 2012
Messages : 110
Détails du profil
Informations personnelles :
Nom : Homme arthur
Localisation : Allemagne

Informations professionnelles :
Activité : Étudiant
Secteur : Enseignement

Informations forums :
Inscription : mars 2012
Messages : 110
Points : 9
Points : 9
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 :
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
Citation:
usart0_tx_buffer_max_size
et
Citation:
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 :
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.
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/09/2012, 12h30   #78
arthurdubois
Invité régulier
 
Homme arthur
Étudiant
Inscription : mars 2012
Messages : 110
Détails du profil
Informations personnelles :
Nom : Homme arthur
Localisation : Allemagne

Informations professionnelles :
Activité : Étudiant
Secteur : Enseignement

Informations forums :
Inscription : mars 2012
Messages : 110
Points : 9
Points : 9
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 :
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
Citation:
usart0_tx_buffer_max_size
et
Citation:
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 :
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 !!!!
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/09/2012, 13h50   #79
arthurdubois
Invité régulier
 
Homme arthur
Étudiant
Inscription : mars 2012
Messages : 110
Détails du profil
Informations personnelles :
Nom : Homme arthur
Localisation : Allemagne

Informations professionnelles :
Activité : Étudiant
Secteur : Enseignement

Informations forums :
Inscription : mars 2012
Messages : 110
Points : 9
Points : 9
Hello,
Code :
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 :
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.
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/09/2012, 14h23   #80
Hibernatus34
Membre Expert
 
Inscription : août 2010
Messages : 533
Détails du profil
Informations forums :
Inscription : août 2010
Messages : 533
Points : 1 006
Points : 1 006
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 :
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.
Hibernatus34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 09h17.


 
 
 
 
Partenaires

Hébergement Web