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 08/08/2012, 15h17   #1
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
Par défaut L´envoi du contenu d´un fichier texte vers le port serie RS232

Bonsoir,

je desire depuis mon PC transmettre le contenu de mon fichier texte au microcontrôleur Atmega 644p. Mon Pc et l´Atmega 644p communiquent a travers l´interface de transmission RS232.

J´ai redige un code en C++ pouvant lire le contenu du fichier Texte. La compilation de mon programme a ete un succes et aucune faute n´a ete mentionne dans mon code. Helas, je n´arrive pas a transmettre le contenu du fichier texte a l´Atmega 644p via la peripherie RS232. Bref je ne sais pas si j´ai loupe une procedure fondamentale.

N.B: Dans mon fichier texte, je ne lis que les coordonnees X et Y. Les autres symboles se trouvant dans le fichier texte sont d´aucune utilite pour moi. Bref je desire envoyer progressivement les couple de coordonnes (X,Y) vers l´interface de transmission RS232.


Je vous prie de bien vouloir m´aider, car je suis a cours d´inspiration.

Mon code source et mon fichier texte sont attaches a ce message.

Merci d´avance.

Arthur
Fichiers attachés
Type de fichier : cpp main.cpp (7,4 Ko, 18 affichages)
Type de fichier : txt koordinaten.txt (786 octets, 7 affichages)
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/08/2012, 08h47   #2
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
Bonjour,

Il y a plein de choses à dire sur votre code, mais je vais commencer par les bugs :
1. La variable x n'est qu'une seule chaîne, pourtant vous écrivez dedans tous les X du fichier.
Donc à la fin de la boucle il ne reste que le dernier X dans x.
En plus, avec i_x <= l_x vous allez trop loin et copiez un X non initialisé au final !
Tout ça est valable aussi pour la variable y, bien sûr.
2. Dans la boucle d'émission, vous testez control == 0 pour savoir si vous envoyez un X ou un Y.
Sauf qu'aucun code ne touche à control !
3. Quand vous écrivez while (k1 < i_help_x), ni k1, ni i_help_x ne bouge, donc soit ça fait rien soit c'est une boucle infinie.
4. Le test de CTS seul n'a pas de sens. Si j'ai bien compris le principe, il faut émettre un RTS pour espérer recevoir un CTS. Laissez le système se charger du contrôle de flux !

Maintenant, quelques remarques supplémentaires :
1. Pour lire un fichier complet, il vaut mieux faire un seul read qu'une série de get. Mais en fait il n'y a aucune raison de tout charger en mémoire.
2. Votre code ne compile pas sur un compilateur respectant le standard C++ car vous utilisez les VLA (variables x et y).
VLA = Variable Length Array. La solution c'est de déclarer x1 et y1 dans un enum.
Pensez d'ailleurs à utiliser les vector à la place de tous vos tableaux fixes, c'est pas plus lourd, vous verrez.
3. L'insertion de zéros dans le texte complet pour ensuite vous simplifier la lecture des X/Y, c'est moins fiable, moins performant, et plus lourd à coder que la simple extraction d'entiers via un istream.
4. atof renvoie un double, donc en mettant le résultat dans un float ça fait un warning.
5. Le calcul du pas moteur ne nécessitait pas de passer par les float pour ensuite revenir à un int.

Voici du code qui fait à peu près pareil que le vôtre, avec le même style, mais en bien plus simple.
La partie qui reste floue c'est l'envoi sur le port série, car votre code ne permet pas vraiment de comprendre le protocole.
Qui a programmé le microcontrôleur ? Quelqu'un de votre boîte ? Vous avez une doc qui décrit le protocole ?
Il n'y a pas des lectures à faire aussi ? (un echo, un accusé de réception, l'indication qu'une action est terminée...)

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
#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)
	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);
	// 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.
		DWORD written = 0;
		output_x << x_steps;	// TODO: Ne manque-t-il pas un terminateur ou un cadrage ?
		WriteFile(h, output_x.str().c_str(), output_x.str().size(), &written, 0);
		output_y << y_steps;	// TODO: Ne manque-t-il pas un terminateur ou un cadrage ?
		WriteFile(h, output_y.str().c_str(), output_y.str().size(), &written, 0);
		// TODO: Et là, il ne faut pas attendre un retour ?
	}
	CloseHandle(h);
	return 0;
}
Hibernatus34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/08/2012, 14h51   #3
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 a tous,

tout d´abord je tiens a remercier Hibernatus34 pour ses precieuses explications et pour le temps qu´il a investis pour mieux m´eclairer sur mon probleme. En fait la tâche que j´essaie d´effectuer est une partie de mon memoire de fin d´etude. Jusqu´ici, je n´avais pas encore programme en c++ et c. Bref je suis un debutant dans la programmation et je te remercie une fois de plus d´avoir pris la peine de m´eclairer sur les erreurs de mon programme. En fait je ne beneficie d´aucun soutien dans l´institut ou je bosse sur mon memoire. Mon encadreur principal n´a aucune de la pragrammation en c++, mais il sait ce qu´il veut que j´obtiens comme resultat. Sa fait des mois que je me demerde tout seul et je suis tres heureux d´avoir recus tes conseils.

Concernant la programmation du microcontrôleur, je l´ai programme moi même. Veux-tu que je t´envoie le fichier de programmation du microcontroleur, pour que tu y vois plus clair. Bref, je vais le joindre a ce message.

Merci encore pour ton aide. Je vais de ce pas continuer a bosser afin de comprendre tes suggestions. Merci encore pour ton aide.

Arthur
Fichiers attachés
Type de fichier : c 644p_zu_smci33-2.c (6,4 Ko, 7 affichages)
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/08/2012, 15h42   #4
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
Avec plaisir.
Mais alors si vous êtes le développeur aux 2 extrémités de la connexion, ça risque d'être difficile de savoir ce qui ne marche pas.
Le code du microcontrôleur ne me parle pas beaucoup parce que d'une part je n'ai malheureusement pas d'expérience là-dedans (j'ai toujours développé le côté PC uniquement), et d'autre part je ne parle pas l'allemand !

Que fait la machine quand elle reçoit ces coordonnées ?
Comment distinguez-vous le X du Y ? Vous pourriez envoyer "42,51\n" pour un couple de coordonnées par exemple.
Pourquoi faire de l'ASCII, c'est pas plus facile en binaire ? (attention à l'endianness cependant)
Avez-vous essayé le sens inverse ? (plus facile à vérifier dans un premier temps)

Pas mal de machines font un écho sur le port série, c'est à dire qu'elles renvoient ce qu'elles ont reçu tel quel. Ca serait une bonne idée pour faire un test simple.
En mode ASCII, pas mal utilisent un retour à la ligne comme terminateur, et un caractère du genre \r pour faire un reset (dire "laisse tomber la séquence que j'ai commencé à envoyer, je vais en envoyer une autre").
Enfin, dans les domaines où j'ai bossé, j'ai vu ça, et c'était pas mal, mais j'ai pas énormément d'expérience.
Hibernatus34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/08/2012, 16h33   #5
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
Merci pour ta prompt reaction, je te donnerais les details a propos de tes questions plus tard. Car a force de parler en allemand, c´est devenu difficile pour moi de formuler mes phrases en francais.

Merci pour ta comprehension.

Arthur
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/08/2012, 12h00   #6
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,

desole de t´embêter une fois de plus.

J´ai analyse le code que tu as modifie et franchement je suis impressionne. Je n´aurais pas fait mieux. Cependant j´ai quelques soucis.

1- Les positions X et Y du fichier texte sont des string(ASCii). Alors j´ai encore modifie le code et par la suite essaye de convertir les positions de Ascii en integer. En suite j´ai transforme les positions de integer en pas de moteur. Cependant quand j´essaie de visualiser les differentes conversions avec l´instruction , helas aucune position n´apparaît sur la console de mon IDE (Code::block).
Quelle betise ai-je encore fait.

2- A la fin du code modifie que tu m´as poste, tu as ecris en commentaire :
" // 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 ".

Que dois-je completer au juste ? En fait je desire tout simplement envoyer par couple toutes les positions (X,Y) du fichier sur le port serie RS232 du PC. Ces Positions doivent être receptiones par le microcontrôleur Atmega 644p. Quant-au microcontrôleur, il possede une entree RS232 a travers laquelle il doit être en mesure de recevoir toutes les positions (X,Y). L´envoi d´un couple de position (X,Y) doit se faire sous forme de 16 bytes. A raison de 8 Bytes pour la position X et 8 Bytes pour la position Y.

Bref, j´aimerais faire marcher d´abord le protocol d´envoi du couple des positions (X,Y) sur le port serie RS232.

3- S´il te plaît, a quoi fais-tu allusion avec le commentaire suivant:
Code :
output_x << x_steps;	// TODO: Ne manque-t-il pas un terminateur ou un cadrage ?
. J´ai essaye de comprendre, mais j´ai pas saisis ta question. Du moins je n´ai aucune idee, car je suis debutant dans l´envoi du contenu d´un fichier via le port serie.

S´il te plaît tes corrections, suggestions et propositions sont les bienvenues.
Je te prie de bien vouloir m´accorder encore de ton temps.

Merci.

Le code:

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
#include <fstream>
#include <string>
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>

#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)

	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);

	// Lecture ligne par ligne

	while (getline(file, line))
	{
		char x[10] ;					// x, y du texte
		char y[10] ;
		int x1;
		int y1;
		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;
        cout << x << endl;
		if (input.get() != 'Y')
			continue;
		input >> y;
        //cout << y << endl ;

		// Les positions x et y du fichier sont en ASCii (string)
		// Conversion des positions x et y de ASCii en integer

		x1 = atoi(x);
		//cout << x1 << endl ;
		y1 = atoi(y);

		// Conversion des positions x et y de integer en pas moteur
		// J'ai rendu le calcul compatible avec le type int. (et je le trouve plus lisible)

		x_steps = (x1 * 127) / 500;
		//cout << x_steps << endl ;
		y_steps = (y1 * 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.

		DWORD written = 0;
		output_x << x_steps;	// TODO: Ne manque-t-il pas un terminateur ou un cadrage ?
		WriteFile(h, output_x.str().c_str(), output_x.str().size(), &written, 0);
		output_y << y_steps;	// TODO: Ne manque-t-il pas un terminateur ou un cadrage ?
		WriteFile(h, output_y.str().c_str(), output_y.str().size(), &written, 0);
		// TODO: Et là, il ne faut pas attendre un retour ?
	}
	CloseHandle(h);
	return 0;
}
Arthur
Fichiers attachés
Type de fichier : cpp main.cpp (2,5 Ko, 1 affichages)
Type de fichier : txt koordinaten.txt (786 octets, 2 affichages)
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/08/2012, 13h24   #7
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
Bonjour,

1. La modif que tu as faite n'est pas bonne :
Le code exécuté par l'opérateur >> dépend du type qu'on lui passe.
En lui passant un int, j'extrais les caractères représentant une valeur entière, et je récupère un int (la conversion équivalente à atoi/atof est faite par l'opérateur >>).
Garde mon code et fais un cout << x << ", " << y << endl;. Tu verras que l'extraction fonctionne bien.
Je t'aurais pas donné un code qui ne marche pas.

2. OK, donc finalement c'est du binaire ?
Dans ton code d'origine, j'ai peut-être mal vu, mais il me semble que tu envoyais de l'ASCII (donc pour envoyer 42 tu envoyais 2 caractères '4' et '2').
Tu parles vraiment de 8 bytes (64 bits) ou de 8 bits par coordonnée ? Ca me paraît surprenant que ton microcontrôleur soit à l'aise avec du 64 bits. Cependant les valeurs étaient trop grandes pour du 8 bits...

Donc si je veux envoyer (42, 51) puis (12, 34), et en imaginant que ça soit sur 8 bytes (octets), on envoie en réalité ceci ?
Code :
char sequence[] = { 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 34 }
(là je suis parti du principe qu'on veut du big endian)
Je trouve surprenant un tel protocole, en cas de décalage on peut envoyer n'importe quoi. Habituellement on a au moins un code de départ, un séparateur...

3. Quand on envoie de l'ASCII, comment le récepteur peut-il savoir quand on a fini d'envoyer le X, et quand on commence à envoyer le Y ?
- Soit avec du cadrage : "0042" ou " 42" (cadré à droite) et je décide que tout nombre fait 4 caractères
- Soit avec un terminateur : "42\n" (le \n indique la fin)

Mais visiblement tu veux faire du binaire, et là c'est un peu pareil, sauf qu'au lieu de parler de cadrage on va juste dire que la taille est fixe : 1 octet ou 2 ou 3...


PS. Si tu me confirmes que c'est du binaire que tu veux, je te donnerai le code adapté (en gros il suffit de virer les "output" et copier par morceaux les x et y dans un char[]).
Hibernatus34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/08/2012, 14h32   #8
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 a nouveau,

en fait je desirais envoyer les couples de position (X,Y) du fichier texte sous forme de deux Bytes, et non 8 bytes. 8 Bytes c´est trop !! Je m´escuse pour mon erreur. Lors de l´envoi d´un couple de position (X,Y), le port serie rs232 doit recevoir 2 bytes. Soit 1 byte pour la position X et 1 byte pour la position car Le microcontrôleur Atmega 644p a une capacite de 64K.

Disons que c´est pour l´option binaire que j´avais envie de opter.

Mais je me rends compte que cela me compliquera la tâche plus tard. Es-ce possible de transferer les couples de position (X,Y) du fichier sous forme ASCii sur le port serie RS232 ?. Si oui, j´aimerais que tu m´aides dans ce sens la. Si non, alors j´opte pour l´option binaire.

Bref, Je prefere envoyer les positions sous forme ASCii.

1- Quand on envoie de l'ASCII, comment le récepteur peut-il savoir quand on a fini d'envoyer le X, et quand on commence à envoyer le Y ?

Je pense comme tu l´as proposes que c´est avec un terminateur [ "42\n" (le \n indique la fin)] que l´on peut marquer la fin de l´envoi d´une position.

2- Si je ne me trompe pas, le programme que tu m´as suggeres envoie les positions sous la forme ASCii. Ou bien je me trompe ? Si c´est le cas, alors je devrais conserver le code que tu m´as suggere !!

3- Quel code est adequat pour envoyer progressivement les positions (X,Y) sur le port serie avec le terminateur. Du moins, qu´es ce que je dois encore adapter au programme pour que le processus marche?

Escuse moi, si je pose trop de questions. Je suis tellement confus et j´aimerais comprendre le processus. Merci pour ta disponibilite et ton aide..

N.B: ta consigne de tout a l´heure marche. merci


Arthur.
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/08/2012, 14h56   #9
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
On va y aller en douceur...

Laissons tomber pour l'instant les X et les Y, le fichier texte, le choix binaire ou ASCII.

Il faut que tu sois capable de programmer sur le microcontrôleur une écoute du port série et un écho.
1 J'attends de recevoir quelque chose sur le port série
2 Je lis un caractère sur le port série
3 J'envoie ce caractère sur le port série
4 GOTO 1

Je peux pas t'aider à faire ça, ou alors il va falloir me faire un petit cours accéléré sur ton microcontrôleur.

Ensuite, côté PC, c'est simple :
- CreateFile, GetCommState, SetCommState (SetCommTimeouts ?)
- WriteFile
- ReadFile

Quand tu auras ça, tu sauras que tu es capable de les faire dialoguer et on choisira un protocole adapté. ASCII ou binaire, c'est presque une affaire de goût, car les avantages/inconvénients sont négligeables.
J'ai encore une question : à quoi vont servir les X et les Y ? (piloter 2 moteurs ?) Vont-ils être utilisés dès réception, ou mémorisés dans une séquence ?
Hibernatus34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/08/2012, 16h04   #10
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,

okay, on va proceder comme tu suggeres.

A quoi vont servir les X et les Y ? --> Ils serviront a piloter exactement deux moteurs.
les positions X et Y representent en fait les positions d´une platine dans un repere orthonorme. Les positions X piloteront un moteur pendant que les positions Y piloteront l´autre moteur. Cependant les deux moteurs sont pilotables lorsqu´ils recoivent les Positions X et Y sous forme ASCii.

Le microntrôleur sert de transition entre le PC et les deux moteurs. Mon microcontrôleur possede deux ports serie. A savoir: RS232 et RS485. Le port serie RS232 du microcontrôleur permettra la communication avec le PC. Par ailleur le port serie RS485 permettra la communication entre le microcontrôleur Atmega 644p et les deux moteurs.

Concernant la programmation du microcontrôleur, je vais te faire un bref resume de la maniere dont-il fonctionne dans le prochain fichier que je vais poster.

Merci encore pour ton soutien.

Arthur.
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/08/2012, 13h49   #11
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 Hibernatus34,

Voici les instructions que tu m´as donnes lors de notre derniere conversation:

1 J'attends de recevoir quelque chose sur le port série
2 Je lis un caractère sur le port série
3 J'envoie ce caractère sur le port série
4 GOTO 1 .

En piece jointe se trouve un fichier qui effectue exactement tes instructions.

Je vais te faire un bref resume du fonctionement de L´USART.
En fait mon microcontrôleur atmega 644p possede deux USARTs. A savoir l´usart0 qui fonctionne comme port serie rs232 et l´usart1 qui fonctionne comme port serie rs485. L´usart0 et l´usart1 possede respectivement le buffer UDR0 et le buffer UDR1. Les buffers UDR0 et UDR1 recoivent respectivement un byte. Ceci dit, lorsque les positions x et y du fichier texte seront envoyes a l´atmega 644p via le port serie rs232, c´est le buffer UDR0 qui recevra progressivement les donnees. UDR0 ne peut recevoir qu´un byte. Alors pour recevoir les autres bytes, une fonction sera necessaire pour liberer le buffer UDR0 afin de recevoir les autres positions. Ce processus sera effectue jusqu´a ce que UDR0 recoivent toutes les positions.

Cependant les positions recues par le buffer UDR0 devront être envoyes au buffer UDR1 qui peut seulement aussi contenir 1 byte. Les positions se trouvant dans UDR1 seront a leur tour envoye aux deux moteurs de commande. Pour cela les positions qui se trouvaent dans UDR1 seront enregistres progressivement dans deux variables ( car on dispose des positions x et y) qui seront ensuite envoye sur le port serie rs485 pour permettre la communication avec les deux moteurs de commande. J´ai redige un 2ieme code en C qui pourra me permettre de recevoir les positions x et y du fichier texte avec l´atmega 644p, en suite ces positions seront envoyes vers les deux moteurs de commande . Si tu veux bien, jete y un coup d´oeil. Peut-être que tu pourras deceler des erreurs de raisonnement dans mon travail.

Est-ce que mes expliations sont suffisants pour qu´on puisse finir le code c++ concernant l´envoie des positions x et y du fichier texte au microcontrôleur atmega 644p. J´attends ton intervention avec impatience.

cordialement.

Arthur
Fichiers attachés
Type de fichier : c Test.c (4,2 Ko, 6 affichages)
Type de fichier : c 644p_smci33-2.c (7,5 Ko, 4 affichages)
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/08/2012, 11h55   #12
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
Oui c'est clair, le code aussi est clair. Je devine évidemment que UDR0 c'est le "data register", UBRR0H/L c'est le "baud rate register", UCSR0A/B/C "control and status register", UDRE0 le flag "data register empty" etc. (je plaisante, j'ai trouvé la doc, mais c'est quand même simple en fait)

Il manque un ";" dans la fonction USART0_Receive après le while.
Par la suite, si ton microcontrôleur doit faire d'autres choses, tu pourras utiliser les interruptions à la place des boucles.

As-tu testé le code ? Sur PC il faut faire un WriteFile puis un ReadFile pour voir si tu reçois le caractère que tu as envoyé.

PS. Je n'avais lu que test.c (que je te recommande de tester en premier avec la connexion au PC)

Je viens de lire vite fait 644p_smci-2.c.
En fait tu utilises déjà les interruptions, donc c'est parfait. Cependant je ne comprends pas le code :
- Dans l'ISR USART0_RXC0, tu testes !usart0_rx_flag. Mais ce booléen n'est jamais remis à zéro, donc tu ne peux faire qu'une réception. C'est parce que le code n'est pas fini ?
- Dans la même routine, tu écris immédiatement dans UDR1 sans savoir s'il est dispo, et puis du coup à quoi bon stocker dans usart0_rx_buffer ?
- Dans l'ISR USART1_UDRE1, tu lis dans UDR1, alors que tu devrais y écrire.
- L'écriture dans x et y ne sert à rien pour le moment, et le test counter % 2 non plus, du coup.

L'interruption UDRE1 signale que UDR1 est prêt à recevoir un octet, ça ne signale pas que tu viens d'écrire dans UDR1. (si je me trompe dis-le moi)
Tu as plusieurs manières de coder ça correctement, mais j'aimerais que tu testes d'abord un simple écho. (test.c)

J'ai une nouvelle question : le protocole entre le microcontrôleur et le moteur (via l'USART1) est bien défini, non ? Quel est-il ? (ASCII/Binaire, avec terminateur...)
Hibernatus34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/08/2012, 15h38   #13
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 Hibernatus34,

tout d´abord je tiens a te remercier pour ton soutien et tes encouragements.

J'ai une nouvelle question : le protocole entre le microcontrôleur et le moteur (via l'USART1) est bien défini, non ? Quel est-il ? (ASCII/Binaire, avec terminateur...)

En effet, il existe un protocole bien defini entre le microcontrôleur et les deux moteurs de comande.
Le protocole est en ASCii et sous la forme suivante: "#2C\r"
Explication du protocole : # ---> debut de l´instruction
2 ---> Adresse du moteur de commande
c---> Instruction a envoyer au moteur de

commande
\r --> fin de l´instruction

Concernant la programmation de l´ISR USART0_RXC0 et de l´ISR USART1_UDRE1, j´y travaille encore. Neanmoins je trouve tes remarques pertinentes. Je vais modifier a nouveau mes codes.

J´ai essaye par ailleurs de modifier le programme qui me permettra d´envoyer les positions x et y au microcontrôleur , afin de tester l´envoi et la reception des coordonnees. Helas j´obtiens des fautes lorsque je compile le code.

A savoir :
error: request for member 'str' in 'input_x', which is of non-class type 'char [5]'|
error: request for member 'str' in 'input_x', which is of non-class type 'char [5]'|
error: request for member 'str' in 'input_y', which is of non-class type 'char [5]'|
error: request for member 'str' in 'input_y', which is of non-class type 'char [5]'|

Comment pourrais-je corriger ses fautes ?

Cependant, l´instruction
Code :
 cout << "error: " << GetLastError() << endl << fmsg << endl; // Affichage de l´erreur
m´informe que le systeme ne retrouve pas le fichier texte. Et pourtant le fichier texte se trouve dans le même dossier que le fichier de mon programme c++.

Je te prie de bien vouloir m´aider.

le code:

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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#include <fstream>
#include <string>
#include <iostream>
#include <sstream>
#include <tchar.h>
#include <Windows.h>
#include <stdio.h>

using namespace std;

void PrintCommState(DCB dcb)
{
    //  Imprimez certaines des valeurs de structure DCB
    _tprintf( TEXT("\nBaudRate = %d, ByteSize = %d, Parity = %d, StopBits = %d\n"),
              dcb.BaudRate,
              dcb.ByteSize,
              dcb.Parity,
              dcb.StopBits );
}

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;
	}

//////////////////////////////////////////////////////////////////////////////////////
///////////// Configuring a communications Resource//////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

    HANDLE h ;
	char *fmsg  = NULL;
    int  error = 0;
    DCB dcb = { 0 };
    BOOL dcbOk ;
    TCHAR *pcCommPort = TEXT("COM1"); // La majorite des systemes ont un port serie COM1


	// Ouverture du port COM1 (c'est votre code tel quel)
	      h = CreateFile(pcCommPort, // Pointer to the name of the port
                        GENERIC_READ | GENERIC_WRITE, // Access read-Write mode
                        0, // Share mode
                        NULL, // Pointer to the security attribute
                        OPEN_EXISTING, // How to open the serial port
                        FILE_ATTRIBUTE_NORMAL, //  normal file
                        0);           // Port attributes)

	if (h == INVALID_HANDLE_VALUE) // Echec de l´ouverture du port serie
	{
	    // Description de l´echec d´ouverture du port de serie
	    error = GetLastError();
        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                FORMAT_MESSAGE_FROM_SYSTEM |
                FORMAT_MESSAGE_IGNORE_INSERTS,
                NULL,
                error,
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                (LPTSTR) &fmsg,
                0, NULL );

  cout << "error: " << GetLastError() << endl << fmsg << endl; // Affichage de l´erreur

 // cout << "Error: Impossible d´ouvrir le port série" << endl;
		return 1;
	}

// Tirez parti de la configuration actuelle en recuperant d´abord
// tous les parametres actuels.

   dcbOk = GetCommState(h, &dcb);
   if (!dcbOk) {
      printf ("GetCommState failed with error %d.\n", GetLastError()); // Manipulez l´erreur
      return (2);
   }

   PrintCommState(dcb);       //  Output to console

    // Fill in some DCB values and set the COM1 state:
    // 115200 bps, 8 data bits, no parity, and two stop bit.

	dcb.BaudRate = CBR_115200; // baud rate
	dcb.ByteSize = 8;          // data size, transmit and receive
	dcb.Parity = NOPARITY;     // parity bit
	dcb.StopBits = TWOSTOPBITS; // stop bit
	// dcb.fOutxCtsFlow = FALSE;	// Pourquoi ça et puis ensuite un test manuel du CTS ?

	dcbOk = SetCommState(h, &dcb);
	if (!dcbOk) {
      printf ("SetCommState failed with error %d.\n", GetLastError()); // Manipulez l´erreur
      return (3);
   }

// Recevez la configuration de pcCommPort("COM1") a nouveau

    dcbOk = GetCommState(h, &dcb);
   if (!dcbOk) {
      printf ("GetCommState failed with error %d.\n", GetLastError()); // Manipulez l´erreur
      return (2);
   }

    PrintCommState(dcb);       //  Output to console


   _tprintf (TEXT("Serial port %s successfully reconfigured.\n"), pcCommPort);
   return (0);

///////////////////////////////////////////////////////////////////////////
//////////////// Configuring Timeouts//////////////////////////////////////
///////////////////////////////////////////////////////////////////////////

// Retrieve the timeout parameters for all read and write operations
// on the port.
COMMTIMEOUTS CommTimeouts;
GetCommTimeouts (h, &CommTimeouts);

// Changer les parametres de structure COMMTIMEOUTS.
CommTimeouts.ReadIntervalTimeout = MAXDWORD;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
CommTimeouts.WriteTotalTimeoutMultiplier = 10;
CommTimeouts.WriteTotalTimeoutConstant = 1000;

// Set the timeout parameters for all read and write operations on the port

//if (!SetCommTimeouts (h, &CommTimeouts))
//{
//
//    char hMainWnd ;
//    int dwError = 0;
//  // Could not set the timeout parameters.
//  MessageBox (hMainWnd, TEXT("Unable to set the timeout parameters"),
//              TEXT("Error"), MB_OK);
//  dwError = GetLastError ();
//  return FALSE;
//}

///////////////////////////////////////////////////////////////////////////
////////// 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;
		char input_x[5];	// une paire de coordonnées
		char input_y[5];
		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 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;

     ///////////////////////////////////////////////////////////////////////////
     /////////////// Writing to the serial port//////////////////////////////////
     //////////////////////////////////////////////////////////////////////////
		// 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.

		DWORD written = 0;

		output_x << x_steps;	// TODO: Ne manque-t-il pas un terminateur ou un cadrage ?
		WriteFile(h,   // Manipulez le port serie "COM1" (Port "COM1" handle)
                  output_x.str().c_str(), // Pointer to the data to write
                  output_x.str().size(),  // Number of bytes to write
                  &written,               // Pointer to the number of bytes written
                  0);                     // Must be zero for windows CE

		output_y << y_steps;	// TODO: Ne manque-t-il pas un terminateur ou un cadrage ?
		WriteFile(h,                      // Port "COM1" handle
                  output_y.str().c_str(), // Pointer to the data to write
                  output_y.str().size(),  // Number of bytes to write
                  &written,               // Pointer to the number of bytes written
                  0);                     // // Must be zero for windows CE

///////////////////////////////////////////////////////////////////////////////////////////////
//////////////////// Reading from the serial port ///////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////



         DWORD dwBytesTransferred = 0;

         output_x >> x1;
         itoa(x1, input_x, 10);
         ReadFile(h,   // Manipulez le port serie "COM1" (Port "COM1" handle)
                  input_x.str().c_str(), // Pointer to the data to write
                  input_x.str().size(),  // Number of bytes to write
                  &dwBytesTransferred,    // Pointer to the number of bytes written
                  0);                     // Must be zero for windows CE

         output_y >> y1 ;
         itoa(y1, input_y, 10);
         ReadFile(h,   // Manipulez le port serie "COM1" (Port "COM1" handle)
                  input_y.str().c_str(), // Pointer to the data to write
                  input_y.str().size(),  // Number of bytes to write
                  &dwBytesTransferred,     // Pointer to the number of bytes written
                  0);                     // Must be zero for windows CE

		// TODO: Et là, il ne faut pas attendre un retour ?

//////////////////////////////////////////////////////////////////////////////
///////////////// Using Communication Events//////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

	}
	CloseHandle(h);
	return 0;
}
Cordialement.
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/08/2012, 16h13   #14
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
Bah, là je suis un peu perplexe...
input_x c'est toi qui l'a rajouté, tu lui as donné le type char[5] et ensuite tu tentes d'accéder à une méthode membre (que tu as copié/collé d'un code accédant à un stringstream). Un char[] n'est pas un objet (class/struct) et n'a donc pas de membres.
Soit tu passes le char[] tel quel à ReadFile (son type est char*) et la taille tu la calcules avec un strlen(), soit tu utilises un stringstream.

Mais le plus bizarre, c'est que tu fais les choses à l'envers, quand tu utilises ReadFile, c'est pour lire une chaîne, pas pour l'écrire.

N'essaie pas de copier/coller mon code sans comprendre, n'hésite pas à me demander comment ça marche, et comment tu peux faire la suite.
Hibernatus34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/08/2012, 17h08   #15
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,

J´ai modifie le code de la maniere suivante:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

 DWORD dwBytesTransferred ;
       
 output_x >> x1;
 itoa(x1, input_x, 10);
 ReadFile(h,   // Manipulez le port serie "COM1" (Port "COM1" handle)
             input_x, // Pointer to the data to read
             1,  // Number of bytes to read
             &dwBytesTransferred,    // Pointer to the number of bytes written
                  0);                     // Must be zero for windows CE

 output_y >> y1 ;
 itoa(y1, input_y, 10);
 ReadFile(h,   // Manipulez le port serie "COM1" (Port "COM1" handle)
             input_y, // Pointer to the data to read
             1,  // Number of bytes to read
             &dwBytesTransferred,     // Pointer to the number of bytes written
                  0);                     // Must be zero for windows CE
La modification du code ci-dessus est compilable. Je l´ai teste. Trouves-tu que j´ai bien suivis tes directives? Si non, je te prierais de m´aider.

Dois-je encore ameliorer quelque chose ?.

Merci
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/08/2012, 17h12   #16
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
Sorry, je ne crois pas avoir suivis tes directives.

Je crois avoir compris ce que tu as essayes de m´expliquer. JE me mets au boulot.

Merci.
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/08/2012, 18h45   #17
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,

c´est encore moi. En fait j´ai a nouveau essaye de suivre tes conseils et j´espere que c´est le cas. J´ai modifie la fonction ReadFile 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
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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233

#include <fstream>
#include <string>
#include <iostream>
#include <sstream>
#include <tchar.h>
#include <Windows.h>
#include <stdio.h>

using namespace std;

void PrintCommState(DCB dcb)
{
    //  Imprimez certaines des valeurs de structure DCB
    _tprintf( TEXT("\nBaudRate = %d, ByteSize = %d, Parity = %d, StopBits = %d\n"),
              dcb.BaudRate,
              dcb.ByteSize,
              dcb.Parity,
              dcb.StopBits );
}

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;
	}

//////////////////////////////////////////////////////////////////////////////////////
///////////// Configuring a communications Resource//////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

    HANDLE h ;
	char *fmsg  = NULL;
    int  error = 0;
    DCB dcb = { 0 };
    BOOL dcbOk ;
    TCHAR *pcCommPort = TEXT("COM1"); // La majorite des systemes ont un port serie COM1


	// Ouverture du port COM1 (c'est votre code tel quel)
	      h = CreateFile(pcCommPort, // Pointer to the name of the port
                        GENERIC_READ | GENERIC_WRITE, // Access read-Write mode
                        0, // Share mode
                        NULL, // Pointer to the security attribute
                        OPEN_EXISTING, // How to open the serial port
                        FILE_ATTRIBUTE_NORMAL, //  normal file
                        0);           // Port attributes)

	if (h == INVALID_HANDLE_VALUE) // Echec de l´ouverture du port serie
	{
	    // Description de l´echec d´ouverture du port de serie
	    error = GetLastError();
        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                FORMAT_MESSAGE_FROM_SYSTEM |
                FORMAT_MESSAGE_IGNORE_INSERTS,
                NULL,
                error,
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                (LPTSTR) &fmsg,
                0, NULL );

  cout << "error: " << GetLastError() << endl << fmsg << endl; // Affichage de l´erreur

 // cout << "Error: Impossible d´ouvrir le port série" << endl;
		return 1;
	}

// Tirez parti de la configuration actuelle en recuperant d´abord
// tous les parametres actuels.

   dcbOk = GetCommState(h, &dcb);
   if (!dcbOk) {
      printf ("GetCommState failed with error %d.\n", GetLastError()); // Manipulez l´erreur
      return (2);
   }

   PrintCommState(dcb);       //  Output to console

    // Fill in some DCB values and set the COM1 state:
    // 115200 bps, 8 data bits, no parity, and two stop bit.

	dcb.BaudRate = CBR_115200; // baud rate
	dcb.ByteSize = 8;          // data size, transmit and receive
	dcb.Parity = NOPARITY;     // parity bit
	dcb.StopBits = TWOSTOPBITS; // stop bit
	// dcb.fOutxCtsFlow = FALSE;	// Pourquoi ça et puis ensuite un test manuel du CTS ?

	dcbOk = SetCommState(h, &dcb);
	if (!dcbOk) {
      printf ("SetCommState failed with error %d.\n", GetLastError()); // Manipulez l´erreur
      return (3);
   }

// Recevez la configuration de pcCommPort("COM1") a nouveau

    dcbOk = GetCommState(h, &dcb);
   if (!dcbOk) {
      printf ("GetCommState failed with error %d.\n", GetLastError()); // Manipulez l´erreur
      return (2);
   }

    PrintCommState(dcb);       //  Output to console


   _tprintf (TEXT("Serial port %s successfully reconfigured.\n"), pcCommPort);
   return (0);

///////////////////////////////////////////////////////////////////////////
//////////////// Configuring Timeouts//////////////////////////////////////
///////////////////////////////////////////////////////////////////////////

// Retrieve the timeout parameters for all read and write operations
// on the port.
COMMTIMEOUTS CommTimeouts;
GetCommTimeouts (h, &CommTimeouts);

// Changer les parametres de structure COMMTIMEOUTS.
CommTimeouts.ReadIntervalTimeout = MAXDWORD;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
CommTimeouts.WriteTotalTimeoutMultiplier = 10;
CommTimeouts.WriteTotalTimeoutConstant = 1000;

// Set the timeout parameters for all read and write operations on the port

//if (!SetCommTimeouts (h, &CommTimeouts))
//{
//
//    char hMainWnd ;
//    int dwError = 0;
//  // Could not set the timeout parameters.
//  MessageBox (hMainWnd, TEXT("Unable to set the timeout parameters"),
//              TEXT("Error"), MB_OK);
//  dwError = GetLastError ();
//  return FALSE;
//}

///////////////////////////////////////////////////////////////////////////
////////// 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;
		char input_x[5];	// une paire de coordonnées
		char input_y[5];
		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 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;

     ///////////////////////////////////////////////////////////////////////////
     /////////////// Writing to the serial port//////////////////////////////////
     //////////////////////////////////////////////////////////////////////////
		// 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.

		DWORD written = 0;

		output_x << x_steps;	// TODO: Ne manque-t-il pas un terminateur ou un cadrage ?
		WriteFile(h,   // Manipulez le port serie "COM1" (Port "COM1" handle)
                  output_x.str().c_str(), // Pointer to the data to write
                  output_x.str().size(),  // Number of bytes to write
                  &written,               // Pointer to the number of bytes written
                  0);                     // Must be zero for windows CE

		output_y << y_steps;	// TODO: Ne manque-t-il pas un terminateur ou un cadrage ?
		WriteFile(h,                      // Port "COM1" handle
                  output_y.str().c_str(), // Pointer to the data to write
                  output_y.str().size(),  // Number of bytes to write
                  &written,               // Pointer to the number of bytes written
                  0);                     // // Must be zero for windows CE

///////////////////////////////////////////////////////////////////////////////////////////////
//////////////////// Reading from the serial port ///////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////



         DWORD dwBytesTransferred ;
        
         output_x >> x1;
          itoa(x1, input_x, 10);

         ReadFile(h,   // Manipulez le port serie "COM1" (Port "COM1" handle)
                  input_x, // Pointer to the data to read
                  strlen(input_x),  // Number of bytes to read
                  &dwBytesTransferred,    // Pointer to the number of bytes to be read
                  0);                     // Must be zero for windows CE

         output_y >> y1 ;
         itoa(y1, input_y, 10);
         
         ReadFile(h,   // Manipulez le port serie "COM1" (Port "COM1" handle)
                  input_y, // Pointer to the data to read
                  strlen(input_y),  // Number of bytes to read
                  &dwBytesTransferred,     // Pointer to the number of bytes to be read
                  0);                     // Must be zero for windows CE

		// TODO: Et là, il ne faut pas attendre un retour ?

//////////////////////////////////////////////////////////////////////////////
///////////////// Using Communication Events//////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

	}
	CloseHandle(h);
	return 0;
}
Du moins j´ai compile le code et je n´ai obtenu aucune faute. Maintenant reste a savoir si le code fonctione. Je vais de ce pas debbuguer le programme. Neanmoins j´attends ton avis.

Dois-je encore ameliorer quelque chose avant de passer au test entre le PC et le microcontrôleur ?

Merci pour ta disponibilite.
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/08/2012, 10h40   #18
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
Non c'est toujours pas bon.
Pourquoi tu écris dans input_x/input_y si c'est pour les passer à ReadFile ?
C'est ReadFile qui va écrire dedans, pas toi.
Toi tu vas lire ce que ReadFile t'a donné.

As-tu testé l'écho ? Je ne sais toujours pas si la communication entre le PC et le µC fonctionne... Si tu lances ton appli et qu'elle ne fait rien, tu regretteras de ne pas avoir testé le minimum vital.

Pour tester l'écho tu peux écrire ceci :
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
 
 
#include <fstream>
#include <string>
#include <iostream>
#include <sstream>
 
#include <Windows.h>
 
using namespace std;
 
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 = 10;
	timeouts.ReadTotalTimeoutMultiplier = 10;
	timeouts.ReadTotalTimeoutConstant = 10;
	timeouts.WriteTotalTimeoutMultiplier = 10;
	timeouts.WriteTotalTimeoutConstant = 10;
	if (!SetCommTimeouts(h, &timeouts))
		return 1;
	// Test de l'écho
	for (int i = 0; i < 10; ++i)
	{
		char sentChar = '0' + i;
		char receivedChar = '#';
		DWORD bytesWritten;
		DWORD bytesRead;
		if (!WriteFile(h, &sentChar, 1, &bytesWritten, 0))
			return 1;
		if (!ReadFile(h, &receivedChar, 1, &bytesRead, 0) || bytesRead != 1)
			cout << sentChar << " : pas de reponse ?" << end;
		else
			cout << sentChar << " = " << receivedChar << endl;
	}
	CloseHandle(h);
	return 0;
}
En espérant ne pas faire d'erreur, car j'ai pas de compilo C++ aujourd'hui, et habituellement j'utilise pas l'API Win32 pour les communications série.

Si le résultat est :
Citation:
1 = 1
2 = 2
3 = 3
...
Alors félicitations, c'est que ton code test.c fonctionne et qu'on s'est pas plantés sur le paramétrage.
(as-tu rajouté le point-virgule manquant dans USART0_Receive ?)
Hibernatus34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/08/2012, 10h40   #19
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,

J´ai deboggue le programme C++ et j´ai obtenu les fautes suivantes:

-
error = 2
fmsg = 0x8157e8 "Das System kann die angegebene Datei nicht finden.\r\n"


La traduction en francais signifie: Le système ne peut pas trouver le fichier donné.

- Error: Impossible d´ouvrir le port série

- J´ai place des breakpoints sur les fonctions ReadFile() et WriteFile() afin de verifier le protocole d´envoi et de reception, helas le curseur saute ces fonctions. Cependant j´ai un autre souci. J´aimerais envoyer une position x sous forme d´un byte au buffer UDR0 (UDR0 ne peut contenir qu´un byte) du microcontrôleur. Mais je ne pense pas que l´instruction effectue cela. Dois-je tout simplement remplacer cette instruction (output_x.str().size()) par le chiffre 1 pour indiquer que je desire envoyer au port serie 1 byte pour une position x et 1 byte pour une position y.

Je te prie de m´aider.

Merci d´avance.

arthurdubois.
arthurdubois est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/08/2012, 11h21   #20
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
As-tu un appareil et une appli pour tester ton port série. Es-tu certain que c'est le COM1 ?
L'autre jour, j'ai eu à faire fonctionner une vieille machine sur le port série, et j'ai fait exprès d'utiliser CreateFile/WriteFile/ReadFile pour tester ce que j'avais vu avec toi. Ca a fonctionné sans problème.

Pour l'envoi de caractères 1 à 1, tu peux faire quelque chose comme ça :
Code :
1
2
3
string s(output_x.str());
for (size_t i = 0; i < s.size(); ++i)
    WriteFile(h, &s[i], 1, &written, NULL);

PS. Peux-tu vérifier ce que tu as dans la base de registres dans HKLM\Hardware\Devicemap\SerialComm ?
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 04h41.


 
 
 
 
Partenaires

Hébergement Web