+ Répondre à la discussion
Page 1 sur 7 12345 ... DernièreDernière
Affichage des résultats 1 à 20 sur 124
  1. #1
    Candidat au titre de Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : mars 2012
    Messages : 110
    Points : 10
    Points
    10

    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 Fichiers attachés

  2. #2
    Membre Expert
    Inscrit en
    août 2010
    Messages
    657
    Détails du profil
    Informations forums :
    Inscription : août 2010
    Messages : 657
    Points : 1 439
    Points
    1 439

    Par défaut

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

  3. #3
    Candidat au titre de Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : mars 2012
    Messages : 110
    Points : 10
    Points
    10

    Par défaut

    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 Fichiers attachés

  4. #4
    Membre Expert
    Inscrit en
    août 2010
    Messages
    657
    Détails du profil
    Informations forums :
    Inscription : août 2010
    Messages : 657
    Points : 1 439
    Points
    1 439

    Par défaut

    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.

  5. #5
    Candidat au titre de Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : mars 2012
    Messages : 110
    Points : 10
    Points
    10

    Par défaut

    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

  6. #6
    Candidat au titre de Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : mars 2012
    Messages : 110
    Points : 10
    Points
    10

    Par défaut

    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 Fichiers attachés

  7. #7
    Membre Expert
    Inscrit en
    août 2010
    Messages
    657
    Détails du profil
    Informations forums :
    Inscription : août 2010
    Messages : 657
    Points : 1 439
    Points
    1 439

    Par défaut

    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[]).

  8. #8
    Candidat au titre de Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : mars 2012
    Messages : 110
    Points : 10
    Points
    10

    Par défaut

    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.

  9. #9
    Membre Expert
    Inscrit en
    août 2010
    Messages
    657
    Détails du profil
    Informations forums :
    Inscription : août 2010
    Messages : 657
    Points : 1 439
    Points
    1 439

    Par défaut

    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 ?

  10. #10
    Candidat au titre de Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : mars 2012
    Messages : 110
    Points : 10
    Points
    10

    Par défaut

    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.

  11. #11
    Candidat au titre de Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : mars 2012
    Messages : 110
    Points : 10
    Points
    10

    Par défaut

    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 Fichiers attachés

  12. #12
    Membre Expert
    Inscrit en
    août 2010
    Messages
    657
    Détails du profil
    Informations forums :
    Inscription : août 2010
    Messages : 657
    Points : 1 439
    Points
    1 439

    Par défaut

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

  13. #13
    Candidat au titre de Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : mars 2012
    Messages : 110
    Points : 10
    Points
    10

    Par défaut

    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.

  14. #14
    Membre Expert
    Inscrit en
    août 2010
    Messages
    657
    Détails du profil
    Informations forums :
    Inscription : août 2010
    Messages : 657
    Points : 1 439
    Points
    1 439

    Par défaut

    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.

  15. #15
    Candidat au titre de Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : mars 2012
    Messages : 110
    Points : 10
    Points
    10

    Par défaut

    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

  16. #16
    Candidat au titre de Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : mars 2012
    Messages : 110
    Points : 10
    Points
    10

    Par défaut

    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.

  17. #17
    Candidat au titre de Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : mars 2012
    Messages : 110
    Points : 10
    Points
    10

    Par défaut

    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.

  18. #18
    Membre Expert
    Inscrit en
    août 2010
    Messages
    657
    Détails du profil
    Informations forums :
    Inscription : août 2010
    Messages : 657
    Points : 1 439
    Points
    1 439

    Par défaut

    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 :
    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 ?)

  19. #19
    Candidat au titre de Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : mars 2012
    Messages : 110
    Points : 10
    Points
    10

    Par défaut

    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.

  20. #20
    Membre Expert
    Inscrit en
    août 2010
    Messages
    657
    Détails du profil
    Informations forums :
    Inscription : août 2010
    Messages : 657
    Points : 1 439
    Points
    1 439

    Par défaut

    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 ?

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 7 12345 ... DernièreDernière

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •