Mélange port série, C++ et boost::asio - C++ - Programmation
Marsh Posté le 01-05-2009 à 18:54:08
boost::asio fourni une base propre pr la gestion de ce genre d epériphérique. J'ai posté un bout de code C++ pr l'attaque du port série.
Marsh Posté le 08-05-2009 à 00:26:01
D'abord un grand merci
J'aurai mis le temps mais j'ai réussis à utiliser boost::asio pour communiquer avec mon microcontrolleur par le port série, en utilisant le code que tu a posté fin 2008.
J'ai quand même quelques questions (qu'il vaut peut etre mieux que je pose sur ton topic ?)
Le microcontroleur à qui j'envoi des valeurs ne voit pas passer les codes ascii des lettres que j'envoie mais des valeurs déacalées.
Exemple, si j'envoi
Aa'\n'
le microC voit 193 225 138 au lieu de 65 97 10 13.
Par contre si le microC envoie 193 225 138 asio l'interprète bien comme "Aa\n" dans la console.
D'où peut venir ce décalage ?
Pour le fonctionnement en général, j'ai du mal à saisir quand s'effectuent les lecture/écriture.
Le programme attend que j'aie rentrée une chaine (cin.get(ch)), la met dans ch et envoie ch au port série (c.write(ch)).
Mais ch est déclaré comme simple char donc comment il peut transmettre toute la chaine ?
Marsh Posté le 08-05-2009 à 05:46:05
cin >> ch mange un caractére et rend la main sans bufferisation. Tu boucle la dessus tant que la conenction ets up. la chaine est donc passé char par char.
j'ai peu d'xp avec les mC je pourrais pas t'aider plus :€
Marsh Posté le 08-05-2009 à 11:48:35
C'est ce que j'aurais pensé, mais j'ai une lumière qui s'allume quand des données passent sur le port série, et elle ne s'allume pas quand j'appuie sur une touche quelconque mais seulement quand j'appuie sur entrée (ce qui a aussi pour effet d'envoyer un 138, au lieu d'un 10 ou 13).
Je vais investiguer
Bon sinon c'était plus pour comprendre le programme vu qu'en vrai je vais juste envoyer des séries d'entiers calculées par un autre programme, j'aurai pas besoin de l'i/o de la console.
Edit : à ce propos, le c.write(ch) n'aceppte donc q'un char à la fois. Il y aurait pas un truc pour envoyer un tableau de valeurs d'un coup ? J'ai pas encore benché le ce code mais il faut vraiment que je gratte des millisecondes sur les appels de fonction.
Ce qui m'interesserait plus ce serait de savoir si je peux ouvrir le port en partageant, pour faire la lecture dans un programme et l'écriture dans un autre. Je vais déjà aller voir la doc pour ca
Edit 2 :
J'ai testé ce code
Code :
|
et ca donne quelquechose comme :
Code :
|
Meme résultat avec cin >> ch
Ca me parait surprenant mais bon. A noter que ca donne bien les valeurs ascii.
Edit 4 ( ) :
Y avait ca dans le code
Code :
|
Que j'ai enlevé. Mais je veux quand meme bien qu'on m'explique comment un char peut stocker la chaine retournée.
Ce qui me gène plus c'est le décalage de qui donne +128 aux valeurs ascii dans le programme asio.
J'ai testé aussi, si le port COM recoit 193 (65+128), ca affiche "A"
S'il recoit 65, il affiche "A^" (où ^ est en fait un triangle fermé).
Edit 3 : Ou alors c'est un problème de bit de parité qui perturbe tout
Marsh Posté le 08-05-2009 à 16:55:09
Heu, je soupconne que passer stopbits à 2 pourrait aider, j'ai trouver ca http://think-async.com/Asio/boost_ [...] _bits.html, mais je vois pas du tout quoi écrire dans le code, C plus plus caÿ dur
Juste pour etre sûr, c'est ce code là que j'ai repris
http://forum.hardware.fr/forum2.ph [...] w=0&nojs=0
Marsh Posté le 09-05-2009 à 00:38:06
Dagnir a écrit : |
char != unsigned char
De rien
Marsh Posté le 09-05-2009 à 01:18:28
J'y ai pensé ( ), mais la fonction write d'asio prend un char donc de ce coté c'est fixé.
De l'autre coté si je met les données dans un unsigned char 'A' me donne 193, si je met dans un char ca me donne -65. Donc je suis toujours bloqué, sauf si je retranche 128 systématiquement à tout ce que lit le microC, mais ca fait pas vraiment propre.
J'ai regardé avec le debugger, la valeur que prend ch avant d'etre envoyé par c.write(ch) c'est bien le code ASCII de ce que je tape dans la console donc c'est pas un problème de cout/cin.
Je crois que mon microC prend deux bits de stop exclusivement alors que la valeur par défaut en général c'est 1, ca pourrait expliquer un bit de poids fort toujours à 1. Mais j'aarrive pas à trouver de tutoriel/exemple qui montre comment le changé.
J'ai tenté de mettre
Code :
|
en début de main mais il me dit "one : undeclared identifier". J'avoue que j'ai un peu de peine avec le C++, j'ai encore du mal à comprendre comment certaines lignes peuvent fonctionner.
Marsh Posté le 09-05-2009 à 01:50:23
C'est quoi comme micro ? Quel compilateur/libc ?
Tu utilises un "OS" ou tu joues directement avec les registres de l'uart ?
Marsh Posté le 09-05-2009 à 01:51:38
on s'en tape un peu. Monsieur a juste à apprendre à appeler une méthode sur un objet, ASIo fera le reste
Marsh Posté le 09-05-2009 à 01:59:19
Je ne pense pas qu'asio tourne sur les PIC 8 bits, que je soupçonne le monsieur d'utiliser
Marsh Posté le 09-05-2009 à 02:07:16
Le problème ne se situe plus que probablement pas côté pc
Marsh Posté le 11-05-2009 à 13:14:26
Bon, après tatonnement j'ai trouvé une syntaxe qui a l'air de marcher.
J'ai rajouté
Code :
|
dans la classe minicom_client
Apparemment c'était plus le character size qui posait problème, il devait pas être à 8 par défaut.
Marsh Posté le 01-05-2009 à 18:41:58
Bonjour
J'ai un problème un peu compliqué vu que ca mélange l'accès au port série sous Windows, du C, et tout ca avec Matlab. Je ne sais d'ailleurs pas trop dans quelle catégorie poster
Je vais donc essayer d'etre le plus clair possible.
Contexte :
Le but c'est de piloter un robot à partir d'un ordinateur embarqué (EeePC).
L'ordinateur communique avec un microcontroleur qui gère les moteurs (pour lire le déplacement du robot et envoyer des consignes) via un port série (COM3).
On utilise Matlab pour faire tout ca parceque c'est pratique pour développer/debugger.
Le problème :
Les fonctions de lecture/ecriture sur port série de Matlab sont trop longues. On a peu de données à transmettre mais les appels aux fonctions de lecture/écriture sont fréquent. L'idéal serait de pouvoir lire et écrire toutes les 5ms, actuellement la durée d'execution des fonctions empeche de descendre sous les 10ms par cycle lecture/écriture.
J'ai d'abord réécrit les fonctions de lecture/écriture en C avec les fonctions WriteFile et ReadFile d'après une source trouvée et à l'aide de la MSDN (Outre les fonctions "mex" propres à Matlab c'est du C normal) :
J'ai énormément gagné en vitesse d'écriture (~1ms pour executer la fonction), par contre en lecture ca a explosé, dans les 14ms en moyenne pour lire.
Je me suis dit que je pourrais passer sur un Windows CE (qui est "temps réel" ) pour gagner en rapidité mais je ne pense pas que je vais gagner grand chose.
Question :
Qu'est-ce que je peux faire pour réduire le temps de lecture ?
Aussi, la lecture a un comportement étrange, une fois que tout le buffer a été lu, ca me renvoit quand même des valeurs plus ou moins aléatoires
Et question pour les connaisseurs :
Le fichier C est compilé par Matlab qui en fait un fichier binaire serialrw.mex. Pour l'utiliser j'écrit quelque chose comme ca dans la commande de Matlab :
Mais comment il se passe le handle du port COM entre les appels
Message édité par Dagnir le 08-05-2009 à 13:13:52
---------------
Nous vous souhaitons de beaux rêves, c'est le cinéma gratuit.