2013-08-02 1 views
4

J'écris une application Qt pour communiquer avec un autre ordinateur via un port série. J'ai 2 vrais problèmes. Je peux envoyer et recevoir des données correctement, mais parfois le port série «mange» une partie de mon entrée. Par exemple, si je vous envoie:Communication Qt Port série

cd /application/bin 

parfois (pas toujours), il ne recevra:.

cd /applica 

(Comme il est un terminal, il fait écho à l'entrée arrière Aussi mon message me dit que je suis clairement au mauvais endroit.)

2. en outre, parfois la fente Qt qui se déclenche quand il y a des données disponibles ne se déclenche pas, même si je sais qu'il ya des données que je peux recevoir. Si j'envoie un autre \r\n sur le port, la fente se déclenchera. Par exemple parfois je vais ls quelque chose, et le nom de la commande sera relu du port, mais le contenu du dossier reste là dans les limbes jusqu'à ce que je frappe à nouveau. Ensuite, je reçois la liste du répertoire et deux invites.

Voici mon code:

void Logic::onReadyRead(){   
     QByteArray incomingData; 
     incomingData = port->readAll(); 
     QString s(incomingData); 
     emit dataAvailable(s);// this is a Qt slot if you don't know what it is. 
     qDebug() << "in:"<< s.toLatin1();  
} 

void Logic::writeToTerminal(QString string) 
{ 
    string.append("\r\n"); 
    port->write((char*)string.data(), string.length()); 
    if (port->bytesToWrite() > 0){ 
     port->flush(); 
    } 
    qDebug() << "out:" << string.toLatin1(); 
} 
+0

Je viens de réaliser qu'il ne soit pas clair, ce sont des questions non liées. Shell me dira qu'il ne peut pas aller à '/ applica' car aucun répertoire n'existe. – Muricula

+0

Vous devrez mettre en mémoire tampon les données lues sur le port jusqu'à ce que vous rencontriez le , ce qui peut nécessiter plusieurs lectures depuis le port . – Pete

Répondre

2

J'ai trouvé la solution, et je pense qu'il était une erreur d'encodage, mais je ne suis pas sûr. Au lieu d'envoyer un QString sur le port série, l'envoi d'un QByteArray a résolu les deux problèmes. J'ai changé la méthode writeToTerminal():

void Logic::writeToTerminal(QString string) 
{ 
    string.append("\r"); 
    QByteArray ba = string.toAscii(); 
    port->write(ba); 
} 
0

De this forum, il semble que parfois pas toutes les données est envoyé, et tout ce qui n'est envoyé a un « \ 0 » y est annexé. Donc, si

cd/applica « \ 0 » fut expulsé, le port->readAll() arrêterait là, parce qu'il pense qu'il a tout lu.

Une réponse proposée sur ce forum était de lire ligne par ligne, que votre code presque fait. Je pense donc que dans votre cas, vous pouvez changer votre code:

void Logic::onReadyRead(){   
    QByteArray incomingData; 
    if(port->canReadLine()) { 
     incomingData = port->readLine(); 
     QString s(incomingData); 
     emit dataAvailable(s);// this is a Qt slot if you don't know what it is. 
     qDebug() << "in:"<< s.toLatin1(); 
    }  
} 

void Logic::writeToTerminal(QString string) 
{ 
    string.append("\r\n"); 
    port->write((char*)string.data(), string.length()); 
    if (port->bytesToWrite() > 0){ 
     port->flush(); 
    } 
    qDebug() << "out:" << string.toLatin1(); 
} 
+1

Je suggère de ne pas convertir aveuglément de QByteArray à QString et vice versa sans spécifier l'encodage. Par exemple. lors de l'écriture: 'QByteArray data = s.toUtf8(); // convertit explicitement en UTF-8'; Et vérifier les valeurs de retour: 'const qint64 écrit = port-> écrire (data.constData(), data.length());' –

+0

@maditya, j'avais essayé de lire ligne par ligne mais il n'a pas résolu mon problème. Cela a fonctionné un peu moins bien que 'port-> readAll()' Merci quand même – Muricula