Aller au contenu


Photo
- - - - -

Programme interface PC > ROBOT


  • Veuillez vous connecter pour répondre
26 réponses à ce sujet

#1 bypbop

bypbop

    Habitué

  • Membres
  • PipPip
  • 273 messages
  • Gender:Male
  • Location:Lille

Posté 22 août 2012 - 02:06

Bonjour je viens de terminer la première partie de mon robot : code arduino et gestion des moteurs et je voudrais maintenant faire un petit programme me permettant d'utiliser directement mon pc pour diriger mon robot.

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 Black Templar

Black Templar

    Membre

  • Membres
  • PipPipPipPipPip
  • 1 430 messages
  • Gender:Male
  • Location:Lille

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 julkien

julkien

    Pilier du forum

  • Membres
  • PipPipPipPipPip
  • 1 032 messages
  • Gender:Male

Posté 22 août 2012 - 07:07

salut

moi sous vb j'utilise Imports System.IO.Ports

tu devrais retrouver la meme chose sous visual c++



#4 Black Templar

Black Templar

    Membre

  • Membres
  • PipPipPipPipPip
  • 1 430 messages
  • Gender:Male
  • Location:Lille

Posté 22 août 2012 - 12:53

Et pour windows avec gcc : http://www.robot-maker.com/forum/topic/5777-port-serie-c/page__view__findpost__p__35924

Mon site internet : http://ferdinandpiette.com/


#5 bypbop

bypbop

    Habitué

  • Membres
  • PipPip
  • 273 messages
  • Gender:Male
  • Location:Lille

Posté 22 août 2012 - 08:22

Merci à tous je regarde tous ca et je vous tiens au courant ...

Cordialement,
bypbop

#6 Evotique

Evotique

    Membre

  • Membres
  • 27 messages
  • Gender:Male

Posté 24 août 2012 - 10:14

Tu peux utiliser directement le C++
#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 Black Templar

Black Templar

    Membre

  • Membres
  • PipPipPipPipPip
  • 1 430 messages
  • Gender:Male
  • Location:Lille

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 Evotique

Evotique

    Membre

  • Membres
  • 27 messages
  • Gender:Male

Posté 25 août 2012 - 02:25

Sous Windows :
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 bypbop

bypbop

    Habitué

  • Membres
  • PipPip
  • 273 messages
  • Gender:Male
  • Location:Lille

Posté 25 août 2012 - 04:46

Bonjour à tous,

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 R1D1

R1D1

    Modérateur et Membre passionné

  • Modérateur
  • PipPipPipPipPip
  • 1 211 messages
  • Gender:Male
  • Location:Autriche

Posté 25 août 2012 - 05:11

L'erreur est explicite : la fonction write( const char * ) n'existe pas. Une petite recherche t'apprend que le prototype de la fonction est write(const char *, streamsize n).

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 ...
R1D1 - Calculo Sed Ergo Sum -- en ce moment, M.A.R.C.E.L.
Avatar tiré du site bottlebot

#11 Black Templar

Black Templar

    Membre

  • Membres
  • PipPipPipPipPip
  • 1 430 messages
  • Gender:Male
  • Location:Lille

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 Evotique

Evotique

    Membre

  • Membres
  • 27 messages
  • Gender:Male

Posté 25 août 2012 - 06:06

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

Logiquement ça devrait fonctionner.

#13 bypbop

bypbop

    Habitué

  • Membres
  • PipPip
  • 273 messages
  • Gender:Male
  • Location:Lille

Posté 25 août 2012 - 08:08

Ok je comprends mieux maintenant merci à tous ;-) dur dur les debut en C++
Cordialement,
bypbop

#14 Evotique

Evotique

    Membre

  • Membres
  • 27 messages
  • Gender:Male

Posté 25 août 2012 - 09:34

Tu peux regarder du côté de python, c'est simple et rapide ( beaucoup moins que le C++ au niveau de l'ordinateur mais à "vue d'oeil" c'est aussi rapide )

#15 bypbop

bypbop

    Habitué

  • Membres
  • PipPip
  • 273 messages
  • Gender:Male
  • Location:Lille

Posté 09 septembre 2012 - 07:33

Bonjour à tous,

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 bypbop

bypbop

    Habitué

  • Membres
  • PipPip
  • 273 messages
  • Gender:Male
  • Location:Lille

Posté 10 septembre 2012 - 12:59

Re j'ai trouvé une bibliothèque SDL mais je ne sais pas si je peux l'utiliser en mode console ...

Cordialement,
bypbop

#17 Black Templar

Black Templar

    Membre

  • Membres
  • PipPipPipPipPip
  • 1 430 messages
  • Gender:Male
  • Location:Lille

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 bypbop

bypbop

    Habitué

  • Membres
  • PipPip
  • 273 messages
  • Gender:Male
  • Location:Lille

Posté 11 septembre 2012 - 09:10

Merci Black Templar,
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 Black Templar

Black Templar

    Membre

  • Membres
  • PipPipPipPipPip
  • 1 430 messages
  • Gender:Male
  • Location:Lille

Posté 14 septembre 2012 - 08:41

Ps : à quoi sert le 0x80 ?

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

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

Oui, car ça a détecté que la touche était bien enfoncé.

Mon site internet : http://ferdinandpiette.com/


#20 bypbop

bypbop

    Habitué

  • Membres
  • PipPip
  • 273 messages
  • Gender:Male
  • Location:Lille

Posté 14 septembre 2012 - 09:16

Merci bcp je comprends mieux donc le premier bits de la fonction donne si la touche est enfoncée ou pas ...

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




0 utilisateur(s) li(sen)t ce sujet

0 members, 0 guests, 0 anonymous users