
Programme interface PC > ROBOT
#1
Posté 22 août 2012 - 02:06
Etant relier à mon pc via un port com (XBEE)
Je voulais savoir si qq'un avait deja communiquer sur le port COM en C++ par ex ...
J'aimerais dans un premier temps utiliser les fleches de direction par exemple pour envoyer une commande à mon robot ...
Cordialement,
bypbop
#2
Posté 22 août 2012 - 06:19
Je voulais savoir si qq'un avait deja communiquer sur le port COM en C++ par ex ...
Oui, sous Linux, tu peux utiliser LibSerial qui marche très bien
Mon site internet : http://ferdinandpiette.com/
#3
Posté 22 août 2012 - 07:07
moi sous vb j'utilise Imports System.IO.Ports
tu devrais retrouver la meme chose sous visual c++
#4
Posté 22 août 2012 - 12:53
Mon site internet : http://ferdinandpiette.com/
#5
Posté 22 août 2012 - 08:22
Cordialement,
bypbop
#6
Posté 24 août 2012 - 10:14
#include <iostream> #include <fstream> using namespace std; int main() { ofstream monFlux("COM3"); // Sous Windows, remplacer COM3 selon vos besoins ofstream monFlux("/dev/ttyACM0"); // Sous Linux, remplacer ACM0 selon vos besoins monFlux.write("Ici, donnees a envoyees"); // Pour écrire / envoyer monFlux.read(); // Pour lire }
#7
Posté 24 août 2012 - 09:46
Tu peux utiliser directement le C++
Bien cette méthode.
Par contre, comment tu fais pour configurer ta connexion ? (baudrate, etc. ?)
J'ai jamais trouvé avec les bib native à C++ :/
Mon site internet : http://ferdinandpiette.com/
#8
Posté 25 août 2012 - 02:25
Démarrer puis clique droit sur Ordinateur > Gérer
Dans Gérer choisis Gestion des Périphérique > Ports ( COM et LPT )
Choisis ton port ( chez moi 19 mais ça peut être 3 comme 58 ) > Propriétés
Dans Propriétes tu vas dans Paramètres du port et tu te fais plaisir !
Sous Linux je n'ai pas besoin de configurer, j'ai l'impression que c'est "automatique".
#9
Posté 25 août 2012 - 04:46
Alors je viens d'essayer la methode à Evotique ( plus simple pour moi ;-) )
J'utilise Codeblocks je crée un application console et j'ai une erreur lors de la compilation
#include <iostream> #include <fstream> using namespace std; int main() { ofstream monFlux("COM5"); // Sous Windows, remplacer COM3 selon vos besoins //ofstream monFlux("/dev/ttyACM0"); // Sous Linux, remplacer ACM0 selon vos besoins monFlux.write("test"); // Pour écrire / envoyer //monFlux.read(); // Pour lire monFlux.close(); }
C:\Documents and Settings\Administrateur\Bureau\Workspace\CodeBlocks\Testcom\main.cpp||In function 'int main()':| C:\Documents and Settings\Administrateur\Bureau\Workspace\CodeBlocks\Testcom\main.cpp|13|error: no matching function for call to 'std::basic_ofstream<char, std::char_traits<char> >::write(const char [5])'| c:\program files\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.4.1\include\c++\bits\ostream.tcc|182|note: candidates are: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::write(const _CharT*, std::streamsize) [with _CharT = char, _Traits = std::char_traits<char>]| ||=== Build finished: 1 errors, 0 warnings ===|
Cela vous dis qqchose ?
Cordialement,
bypbop
#10
Posté 25 août 2012 - 05:11
Il faut donc passer en argument la taille des données que tu veux écrire dans le flux. C'est ce que te dit la ligne candidates are ...
#11
Posté 25 août 2012 - 06:04
Cela vous dis qqchose ?
Tu devrais peut-être lire ce tuto sur la lecture et l'écriture dans un flux ?
http://www.siteduzero.com/tutoriel-3-420466-lire-et-ecrire-des-fichiers.html
@Evotique : Cool ! Je ne savais pas qu'on pouvait faire comme ça.
Mais connais-tu un moyen de le faire en C++ avec gcc sous windows ?
Parce qu'avec window.h, on peut configurer le port COM avec les fonctions SetupCoom, SetCommTimeouts et SetCommState, mais pour ça il faut passer en paramètre le handler du fichier généré avec la fonction CreateFileA ...
Donc on ne peut pas utiliser les flux pour lire et écrire dans le fichier...
EDIT : Je viens d'avoir une idée !!
Je peux très bien ouvrir un port avec CreateFileA, le configurer et le réouvrir avec un flux ? (en espérant qu'il garde en mémoire la dernière configuration ?)
A tester !

Mon site internet : http://ferdinandpiette.com/
#12
Posté 25 août 2012 - 06:06
Logiquement ça devrait fonctionner.EDIT : Je viens d'avoir une idée !!
Je peux très bien ouvrir un port avec CreateFileA, le configurer et le réouvrir avec un flux ? (en espérant qu'il garde en mémoire la dernière configuration ?)
A tester !
#13
Posté 25 août 2012 - 08:08
Cordialement,
bypbop
#14
Posté 25 août 2012 - 09:34
#15
Posté 09 septembre 2012 - 07:33
Alors je viens de modifier mon programme j'ai finalement opté pour le C car je comprenais mieux la connexion au port COM en C
J'ai fait un petit programme en mode console j'arrive au moment ou je dois effectuer la selection des touches pour envoyer mon info au robot.
J'arrive a isoler les fleches de direction mais je voudrais appuyer et que des que je relache la fleche de direction envoyer la commande STOP par ex :
Avez vous une idée ?
#include <stdio.h> #include <stdlib.h> #include <conio.h> #include <windows.h> /*============================================================================= Définition de constantes =============================================================================*/ #define RX_SIZE 4096 /* taille tampon d'entrée */ #define TX_SIZE 4096 /* taille tampon de sortie */ #define MAX_WAIT_READ 5000 /* temps max d'attente pour lecture (en ms) */ /*============================================================================= Variables globales. =============================================================================*/ /* Handle du port COM ouvert */ HANDLE g_hCOM = NULL; /* Délais d'attente sur le port COM */ COMMTIMEOUTS g_cto = { MAX_WAIT_READ, /* ReadIntervalTimeOut */ 0, /* ReadTotalTimeOutMultiplier */ MAX_WAIT_READ, /* ReadTotalTimeOutConstant */ 0, /* WriteTotalTimeOutMultiplier */ 0 /* WriteTotalTimeOutConstant */ }; /* Configuration du port COM */ DCB g_dcb = { sizeof(DCB), /* DCBlength */ 57600, /* BaudRate */ TRUE, /* fBinary */ FALSE, /* fParity */ FALSE, /* fOutxCtsFlow */ FALSE, /* fOutxDsrFlow */ DTR_CONTROL_ENABLE, /* fDtrControl */ FALSE, /* fDsrSensitivity */ FALSE, /* fTXContinueOnXoff */ FALSE, /* fOutX */ FALSE, /* fInX */ FALSE, /* fErrorChar */ FALSE, /* fNull */ RTS_CONTROL_ENABLE, /* fRtsControl */ FALSE, /* fAbortOnError */ 0, /* fDummy2 */ 0, /* wReserved */ 0x100, /* XonLim */ 0x100, /* XoffLim */ 8, /* ByteSize */ NOPARITY, /* Parity */ ONESTOPBIT, /* StopBits */ 0x11, /* XonChar */ 0x13, /* XoffChar */ '?', /* ErrorChar */ 0x1A, /* EofChar */ 0x10 /* EvtChar */ }; /*============================================================================= Fonctions du module. =============================================================================*/ BOOL OpenCOM (int nCOM); BOOL CloseCOM (); BOOL ReadCOM (void* buffer, int nBytesToRead, int* pBytesRead); BOOL WriteCOM (void* buffer, int nBytesToWrite, int* pBytesWritten); int main() { printf("KBOT Bienvenue :\n\r"); /* variables locales */ char buffer[256]; int nCOM, nTouche, nBytesWritten, nBytesRead; /* demande du numéro du port COM */ printf("Entrez le numero du port COM : "); scanf("%d", &nCOM); /* tentative d'ouverture */ printf("Ouverture et configuration du port COM%d...\r\n", nCOM); if(!OpenCOM(nCOM)) return -1; printf("Connexion au COM%d OK \r\n"); do{ //scanf("%d", &nTouche); nTouche = getch(); if(WriteCOM("test", strlen(buffer), &nBytesWritten)) printf("%d octet(s) envoye(s).\r\n", nBytesWritten); else printf("Erreur lors de l'envoi.\r\n"); } while(nTouche != 5); CloseCOM(); return 0; } BOOL OpenCOM(int nId) { /* variables locales */ char szCOM[16]; /* construction du nom du port, tentative d'ouverture */ sprintf(szCOM, "COM%d", nId); g_hCOM = CreateFile(szCOM, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL); if(g_hCOM == INVALID_HANDLE_VALUE) { printf("Erreur lors de l'ouverture du port COM%d", nId); return FALSE; } /* affectation taille des tampons d'émission et de réception */ SetupComm(g_hCOM, RX_SIZE, TX_SIZE); /* configuration du port COM */ if(!SetCommTimeouts(g_hCOM, &g_cto) || !SetCommState(g_hCOM, &g_dcb)) { printf("Erreur lors de la configuration du port COM%d", nId); CloseHandle(g_hCOM); return FALSE; } /* on vide les tampons d'émission et de réception, mise à 1 DTR */ PurgeComm(g_hCOM, PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_RXABORT); EscapeCommFunction(g_hCOM, SETDTR); return TRUE; } BOOL CloseCOM() { /* fermeture du port COM */ CloseHandle(g_hCOM); return TRUE; } /****************************************************************************** ReadCOM : lecture de données sur le port COM. entrée : buffer : buffer où mettre les données lues. nBytesToRead : nombre max d'octets à lire. pBytesRead : variable qui va recevoir le nombre d'octets lus. retour : vrai si l'opération a réussi, faux sinon. ------------------------------------------------------------------------------- Remarques : - la constante MAX_WAIT_READ utilisée dans la structure COMMTIMEOUTS permet de limiter le temps d'attente si aucun caractères n'est présent dans le tampon d'entrée. - la fonction peut donc retourner vrai sans avoir lu de données. ******************************************************************************/ BOOL ReadCOM(void* buffer, int nBytesToRead, int* pBytesRead) { return ReadFile(g_hCOM, buffer, nBytesToRead, pBytesRead, NULL); } /****************************************************************************** WriteCOM : envoi de données sur le port COM. entrée : buffer : buffer avec les données à envoyer. nBytesToWrite : nombre d'octets à envoyer. pBytesWritten : variable qui va recevoir le nombre d'octets envoyés. retour : vrai si l'opération a réussi, faux sinon. ******************************************************************************/ BOOL WriteCOM(void* buffer, int nBytesToWrite, int* pBytesWritten) { /* écriture sur le port */ return WriteFile(g_hCOM, buffer, nBytesToWrite, pBytesWritten, NULL); }
Cordialement,
bypbop
#16
Posté 10 septembre 2012 - 12:59
Cordialement,
bypbop
#17
Posté 11 septembre 2012 - 08:02
Re j'ai trouvé une bibliothèque SDL mais je ne sais pas si je peux l'utiliser en mode console ...
Hello !
Non, si tu ne peux récupérer l’appui sur une touche avec SDL que si ta fenêtre SDL à le focus.
Donc si tu n'ouvres pas de fenêtre, tu n'auras rien du tout.
Vu que tu utilise windows, autant regarder du côté de l'api windows

Tu as la fonction GetKeyState( qui te permet de faire ce que tu veux (je m'en étais servi il y a longtemps pour faire un petit keylogger qui analyse tout ce qui se passe au niveau de l'entrée clavier de mon PC. ça marchait plutôt bien)
Mon site internet : http://ferdinandpiette.com/
#18
Posté 11 septembre 2012 - 09:10
if (GetKeyState(VK_UP)& 0x80) { printf("haut"); } if (GetKeyState(VK_DOWN)& 0x80) { printf("bas"); } if (GetKeyState(VK_LEFT)& 0x80) { printf("gauche"); } if (GetKeyState(VK_RIGHT)& 0x80) { printf("droite"); }
Je viens de faire ceci donc jusque la j identifie la touche mais cela m affiche plein de fois bas , haut , gauche , droite pour seulement un appui sur la touche ...
Ps : à quoi sert le 0x80 ?
Cordialement,
bypbop
#19
Posté 14 septembre 2012 - 08:41
C'est un masque. La fonction getKeyState te retourne un entier. Seul le premier bit de cet entier t'indique si la touche est enfoncée ou non.Ps : à quoi sert le 0x80 ?
0x80, c'est de l'hexadécimal. En binaire, ça fait 10000000.
En gros, tu fais un ET logique entre ce masque et la valeur de retour de la fonction pour isoler le premier bit.
Exemple, la fonction te retourne 156, en binaire, ça te fait 10011100.
Tu fais un ET entre 10011100 et 10000000. ça veut dire que si tu as 2 bits égaux à 1, le résultat vaut 1, sinon 0
10011100 &
10000000 =
10000000
Ici, la touche est bien enfoncée.
Autre exemple avec 121 comme valeur de retour de la fonction. En binaire : 01111001
01111001 &
10000000 =
00000000
Ici, la touche n'est pas enfoncée.
Oui, car ça a détecté que la touche était bien enfoncé.Je viens de faire ceci donc jusque la j identifie la touche mais cela m affiche plein de fois bas , haut , gauche , droite pour seulement un appui sur la touche ...
Mon site internet : http://ferdinandpiette.com/
#20
Posté 14 septembre 2012 - 09:16
Tes explications me montrent mes grosses lacunes en binaire et hexa je n'ai vraiment pas l'habitude de l'utiliser ... A BOSSER ....
donc en faisant ca :
if (GetKeyState(VK_UP)& 0x80) { printf("haut"); } else { printf("haut relaché"); }
par contre petit soucis : qd j'appuie sur la touche haut cela m'affiche 100 fois je pense que c'est normal la boucle ce repete et tt de suite haut relaché en boucle dès que je lache ....
Comme je veux envoyer une seule info pour avancer et dès que je relache cela envoie un STOP cela pose problème ...
As tu une Idée ?
Peut etre passer par une variable intermédiare qui passe à 0 ou à 1
Cordialement,
bypbop
1 utilisateur(s) li(sen)t ce sujet
0 members, 1 guests, 0 anonymous users