Écrire des CHAÎNES de caractères pour le port série en C++ linux
Je sais que cette question est éparpillé partout sur l'internet, mais encore, rien ne m'ont complètement encore là. Je veux écrire des données sur un port série en C++ (linux) pour une Hélice conseil d'administration. Programme fonctionne très bien lors de la prise d'entrée de la console, mais quand j'écris des chaînes de toujours revenir: ERROR - Invalid command
de l'appareil. J'ai essayé de créer tableau de char
avec les valeurs en Hexadécimal puis il a travaillé. voici un code du travail, ci-dessous. Mais comment vais-je être en mesure de fournir une variable de chaîne de commande et l'envoyer sur le port série? peut-être, comment voulez-vous que je le convertir en valeurs hexadécimales si c'est le seul moyen? Merci à tous
remarque: la boucle est d'utiliser la saisie de l'utilisateur de la console. Ce dont j'ai besoin est une manière d'envoyer une variable chaîne de caractères sur le port série.
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
int main(int argc,char** argv){
struct termios tio;
struct termios stdio;
int tty_fd;
fd_set rdset;
unsigned char c='D';
printf("Please start with %s /dev/ttyS1 (for example)\n",argv[0]);
memset(&stdio,0,sizeof(stdio));
stdio.c_iflag=0;
stdio.c_oflag=0;
stdio.c_cflag=0;
stdio.c_lflag=0;
stdio.c_cc[VMIN]=1;
stdio.c_cc[VTIME]=0;
tcsetattr(STDOUT_FILENO,TCSANOW,&stdio);
tcsetattr(STDOUT_FILENO,TCSAFLUSH,&stdio);
fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK); //make the reads non-blocking
memset(&tio,0,sizeof(tio));
tio.c_iflag=0;
tio.c_oflag=0;
tio.c_cflag=CS8|CREAD|CLOCAL; //8n1, see termios.h for more information
tio.c_lflag=0;
tio.c_cc[VMIN]=1;
tio.c_cc[VTIME]=5;
tty_fd=open(argv[1], O_RDWR | O_NONBLOCK);
cfsetospeed(&tio,B115200); //115200 baud
cfsetispeed(&tio,B115200); //115200 baud
tcsetattr(tty_fd,TCSANOW,&tio);
//char str[] = {'V','E','R','\r'};
//the above str[] doesn't work although it's exactly the same as the following
char str[] = {0x56, 0x45, 0x52, 0x0D};
write(tty_fd,str,strlen(str));
if (read(tty_fd,&c,1)>0)
write(STDOUT_FILENO,&c,1);
while (c!='q')
{
if (read(tty_fd,&c,1)>0) write(STDOUT_FILENO,&c,1); //if new data is available on the serial port, print it out
if (read(STDIN_FILENO,&c,1)>0)
if(c!='q')
write(tty_fd,&c,1); //if new data is available on the console, send it to the serial port
}
close(tty_fd);
}
std::string
?J'ai essayé de le faire:
std::string str="VER\r"; write(tty_fd,str.data(),str.size());
il renvoie toujours l'erreur. j'ai essayé plusieurs méthodes, mais seulement ceux hex œuvres. avez-vous une idée? Le code est en C, mais mon programme est fait en C++.Est-ce moi, ou n'avez-vous pas dit nous ce que l'erreur dit réellement?
le port série il suffit de retourner
ERROR - Invalid command
. Donc je suppose que les données atteignent l'appareil, mais pas dans le format valide.un
char str[]
doit être terminée par un octet nul \0
OriginalL'auteur Haikal Pribadi | 2012-02-18
Vous devez vous connecter pour publier un commentaire.
Je suis heureux de résoudre mon propre solution, mais encore déçu de ne pas avoir vu le trivial beaucoup plus tôt.
char
par défaut sontsigned
en c++, ce qui rend la tenue de la plage de -128 à 127. Cependant, nous nous attendons à des valeurs ASCII qui vont de 0 à 255. Donc c'est aussi simple que de le déclarer àunsigned char str[]
et tout le reste devrait fonctionner. Je suis bête, Idiot moi.Encore, Merci à vous tous pour m'aider!!!
OriginalL'auteur Haikal Pribadi
Êtes-vous sûr que vous devriez finir par '\r'? Lors de la saisie de texte à partir de la console de la touche retour entraînera un '\n' (sur Linux) et pas de '\r'
Également la vérification des erreurs est manquant sur la plupart des fonctions (
open()
,fcntl()
, etc.). Peut-être l'une de ces fonctions à l'échec. Pour savoir comment vérifier les erreurs de lire la page de man (par exempleman 2 open
pour laopen()
de commande. En cas deopen()
la page de man explique qu'elle renvoie -1 si il n'a pas pu ouvrir le fichier/port.Après votre modification, vous avez écrit:
qui est faux.
strlen
attend un '\0' terminated string str qui n'est évidemment pas si maintenant il envoie vos données et ce qui reste en mémoire jusqu'à ce qu'il voit un '\0'. Vous devez ajouter0x00
à votrestr
tableau.\r
, je ne pense pas que c'est le problème, parce que j'ai même testé ce code suivant et il renvoie toujours la même erreur.char str[] = {'V', 0x45, 0x52, 0x0D}; write(tty_fd,str,strlen(str));
.. et aussi, j'ai vérifié sur le tableau ASCII qui0x0D
est exactement\r
et pour des fins de test, j'ai essayé
\n
trop, qui n'a pas fonctionné aussi bien.OK, vous avez besoin d'arrêter de regarder le code maintenant. Connectez votre port série à un autre port sur une autre boîte et de l'utilisation d'un terminal d'application de lire ce qui est envoyé dans les deux cas, (qui devrait être le même, mais ne le sont pas).
voir ma réponse mis à jour
merci, mais j'ai résolu mon problème. En ce qui concerne ta solution, j'ai même essayé de codage en dur la valeur exacte (4), qui est suppose de travailler et cela ne fonctionne toujours pas. Mais merci, vraiment. De toute façon, veuillez voir ma mise à jour de question, il a la solution. Je ne peux pas poster comme une solution pour l'instant, la cause je n'ai pas assez de points de réputation.
OriginalL'auteur rve