IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Communication s�rie avec Arduino


Sujet :

C++

  1. #1
    Expert confirm�
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par d�faut Communication s�rie avec Arduino
    Bonjour,

    j'essaye de r�aliser un programme C++ qui me permet d'envoyer des commandes (cha�nes de caract�res) et de lire les r�ponses d'un Arduino Mega2560. Autant avec la console Arduino, le syst�me est tr�s r�actif : j'envoie la commande et l'Arduino r�pond dans la foul�e (environ 1 � 2ms). Autant avec mon programme C++, le syst�me devient tr�s lent : j'ai pratiquement 1s entre l'envoi des donn�es et la r�ponse !
    Je pense que l'un des soucis est dans le contr�le des flux (DSR, DTR, RTS, CTS), je ne dois pas les g�rer correctement.

    Savez-vous comment je peux acc�l�rer la communication entre mon PC et mon Arduino ? Quels sont les flags que je dois activer ou d�sactiver ?

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    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
     
    // ArduinoCom.cpp : Ce fichier contient la fonction 'main'. L'exécution du programme commence et se termine à cet endroit.
    //
     
    #include <iostream>
    #include <string>
    #include <windows.h>
    #include <chrono>
     
    using namespace std;
    using namespace chrono;
     
    class ArduinoCom
    {
    	public:
    		ArduinoCom() {};
    		~ArduinoCom() {};
     
    		int initArduino(string comPort)
    		{
    			bool fSuccess = true;
    			wstring ws;
    			ws = wstring(comPort.begin(), comPort.end());
     
    			hCom = CreateFile(ws.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
     
    			if (hCom == INVALID_HANDLE_VALUE)
    			{
    				return -1;
    			}
     
    			comParams.DCBlength = sizeof(comParams);
    			GetCommState(hCom, &comParams);
    			comParams.BaudRate = 1200;
    			comParams.ByteSize = 8;
    			comParams.Parity = NOPARITY;
    			comParams.StopBits = ONESTOPBIT;
     
    			/*
    			comParams.fOutxCtsFlow = false;
    			comParams.fRtsControl = RTS_CONTROL_DISABLE;
     
    			comParams.fOutxDsrFlow = false;
    			comParams.fDtrControl = DTR_CONTROL_DISABLE;
     
    			comParams.fBinary = true;
    			comParams.fDsrSensitivity = false;
    			comParams.fTXContinueOnXoff = true;
    			comParams.fOutX = true;
    			comParams.fInX = true;
    			*/
    			fSuccess = SetCommState(hCom, &comParams);
     
    			CloseHandle(hCom);
    			return 0;
    		}
     
     
    		int openArduino(string comPort, DWORD baudRate)
    		{
    			bool fSuccess = true;
    			wstring ws;
    			ws = wstring(comPort.begin(), comPort.end());
     
    			hCom = CreateFile(ws.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
     
    			if (hCom == INVALID_HANDLE_VALUE)
    			{
    				return -1;
    			}
     
    			comParams.DCBlength = sizeof(comParams);
    			GetCommState(hCom, &comParams);
    			comParams.BaudRate = baudRate;
    			comParams.ByteSize = 8;
    			comParams.Parity = NOPARITY;
    			comParams.StopBits = ONESTOPBIT;
     
    			comParams.fOutxCtsFlow = true;
    			comParams.fRtsControl = RTS_CONTROL_ENABLE;
     
    			comParams.fOutxDsrFlow = true;
    			comParams.fDtrControl = DTR_CONTROL_ENABLE;
     
    			comParams.fBinary = true;
    			comParams.fDsrSensitivity = true;
    			comParams.fTXContinueOnXoff = true;
    			comParams.fOutX = true;
    			comParams.fInX = true;
     
     
    			fSuccess = SetCommState(hCom, &comParams);
     
    			Sleep(1500);
     
    			if (!fSuccess)
    				return -1;
    			return 0;
    		}
     
    		int writeArduino(string cmd)
    		{
    			bool fSuccess;
    			const char *buf;
    			DWORD nbw;
     
    			buf = cmd.c_str();
    			fSuccess = WriteFile(hCom, buf, strlen(buf), &nbw, NULL);
    			//FlushFileBuffers(hCom);
     
    			return fSuccess;
    		}
     
    		int readArduino(string &resp, char endChar)
    		{
    			char buf;
    			bool fSuccess;
    			DWORD nbr;
     
    			while (true)
    			{
    				fSuccess = ReadFile(hCom, &buf, 1, &nbr, NULL);
    				cout << buf;
    				if (buf == endChar)
    					break;
    			}
    			//resp = buf;
    			return fSuccess;
    		}
     
    		int closeArduino()
    		{
    			if (hCom == INVALID_HANDLE_VALUE)
    				return -1;
     
    			CloseHandle(hCom);
    			return 0;
    		}
     
    	private:
    		HANDLE hCom;
    		DCB comParams = { 0 };
    };
     
     
     
    int main()
    {
    	ArduinoCom *ac = new ArduinoCom();
    	string msg = "-";
     
    	cout << "init " << ac->initArduino("COM7") << "\n";
    	Sleep(1000);
     
    	cout << "open " << ac->openArduino("COM7", 115200) << "\n";
     
    	auto start = high_resolution_clock::now();
     
    	cout << "Top écriture ";
    	cout << "write " << ac->writeArduino("BrLed,Pulse,31,2500\\n") << "\n";
     
    	cout << "Top lecture ";
    	ac->readArduino(msg, '\n');
    	cout << msg << "\n";
     
    	auto stop = high_resolution_clock::now();
     
    	auto duration = duration_cast<milliseconds>(stop - start);
    	cout << duration.count() << endl;
     
     
    	cout << "close " << ac->closeArduino();
    	free(ac);
     
    	system("pause");
        //std::cout << "Hello World!\n";
    }

  2. #2
    Expert confirm�
    Homme Profil pro
    Ing�nieur d�veloppement mat�riel �lectronique
    Inscrit en
    D�cembre 2015
    Messages
    1 599
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 62
    Localisation : France, Bouches du Rh�ne (Provence Alpes C�te d'Azur)

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement mat�riel �lectronique
    Secteur : High Tech - �lectronique et micro-�lectronique

    Informations forums :
    Inscription : D�cembre 2015
    Messages : 1 599
    Par d�faut
    Bonjour,

    Ligne 160, pourquoi un double \\? Je pense que ta carte Arduino attend une fin de ligne qui doit surement �tre un caract�re \n ou \r mais certainement pas un \ suivi d'un n.

  3. #3
    Expert confirm�
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par d�faut
    Effectivement la carte attend un "\n" mais j'�chappe le "\" en le doublant pour qu'il ne soit pas interpr�t� par ma fonction write(). Mais j'avoue que tu me fais douter. J'essaierai d'enlever le "\\".

  4. #4
    R�dacteur/Mod�rateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 38
    Localisation : Canada

    Informations professionnelles :
    Activit� : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par d�faut
    Ta lib std supporte cette syntaxe ?
    string comPort, ...
    wstring ws = wstring(comPort.begin(), comPort.end());
    Parce que convertir un std::string en std::wstring de cette fa�on, j'ai jamais vu, et �a me parait donc un peu cavalier.
    �a passait par le header codecvt et (w)string_convert, d�pr�ci� en C++17. Il faut utiliser les API plateformes pour le faire maintenant. mbstowcs sous Windows.
    Pensez � consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation r�seau ?
    Aucune aide via MP ne sera dispens�e. Merci d'utiliser les forums pr�vus � cet effet.

  5. #5
    Expert confirm�
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par d�faut
    Citation Envoy� par Bousk Voir le message
    Ta lib std supporte cette syntaxe ?
    Mon Visual Studio, oui. J'avoue avoir r�cup�r� cette syntaxe sur divers forums.

  6. #6
    Expert confirm�
    Homme Profil pro
    Ing�nieur d�veloppement mat�riel �lectronique
    Inscrit en
    D�cembre 2015
    Messages
    1 599
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 62
    Localisation : France, Bouches du Rh�ne (Provence Alpes C�te d'Azur)

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement mat�riel �lectronique
    Secteur : High Tech - �lectronique et micro-�lectronique

    Informations forums :
    Inscription : D�cembre 2015
    Messages : 1 599
    Par d�faut
    Citation Envoy� par Bousk Voir le message
    Ta lib std supporte cette syntaxe ?

    Parce que convertir un std::string en std::wstring de cette fa�on, j'ai jamais vu, et �a me parait donc un peu cavalier.
    �a passait par le header codecvt et (w)string_convert, d�pr�ci� en C++17. Il faut utiliser les API plateformes pour le faire maintenant. mbstowcs sous Windows.
    Bien vu, en interne �a va provoquer l'�quivalent de wchar_t x = y; avec y de type const char&, ce qui doit �tre accept� par la STD. Ce qui est correct pour de l'ASCII 7 bits mais si la chaine contient autre chose, �a ne peut que faire n'importe quoi, et je pense qu'il n'y aura m�me pas un warning.
    Il faudrait donc passer par mbstowcs_s(), mais dans le cas pr�sent �a peut fonctionner sans.

  7. #7
    Expert confirm�
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par d�faut
    Bon, un des probl�mes �tait justement cet encodage des caract�res. Je me suis m�lang� les pinceaux entre les wchar_t, char, wstring et string.

  8. #8
    Invit�
    Invit�(e)
    Par d�faut
    Citation Envoy� par Auteur Voir le message
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    	ArduinoCom *ac = new ArduinoCom();
     
    	...
     
    	free(ac);
    malloc()/calloc()/realloc() du C correspond free().
    new du C++ doit correspondre delete.
    Ou encore mieux ici : une simple variable locale .

    Dans la fonction writeArduino(), strlen(buf) => cmd.size().
    Dans la fonction readArduino(), tu b�n�ficierais probablement de lire plus d'un caract�re � la fois.

  9. #9
    Expert confirm�
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par d�faut
    C'est bien vrai : new et delete.
    D�cid�ment

    Dans la fonction readArduino(), tu b�n�ficierais probablement de lire plus d'un caract�re � la fois.
    je ne sais pas combien de caract�res mon Arduino va me renvoyer.

  10. #10
    Invit�
    Invit�(e)
    Par d�faut
    Je te demande pas de pr�voir le nombre final, juste d'avoir un buffer de lecture l�g�rement plus grand .
    Et dans cette optique ton nbr dont tu passes l'adresse contiendra le nombre d'�l�ments effectivement lus.

  11. #11
    Expert confirm�
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par d�faut
    ah... si �a peut m'�viter une boucle.

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. Utiliser Processing avec Arduino, communication s�rie.
    Par jeanclaude83 dans le forum Arduino
    R�ponses: 43
    Dernier message: 03/10/2021, 17h23
  2. [Embarqu�] Communication avec le port s�rie vers Arduino
    Par YannGTT dans le forum Plateformes
    R�ponses: 0
    Dernier message: 05/04/2020, 04h45
  3. R�ponses: 3
    Dernier message: 06/04/2014, 20h01
  4. Communication s�rie avec QtSerialPort
    Par JusteUneIdee dans le forum D�buter
    R�ponses: 1
    Dernier message: 08/07/2013, 12h42
  5. Bug communication serie avec arduino (busy)
    Par Invit� dans le forum MATLAB
    R�ponses: 2
    Dernier message: 09/07/2012, 09h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo