2016-04-28 2 views
3

J'écris un programme C++ en utilisant Qt qui lit les données de la ligne série. Le "producteur" des données est une carte Arduino UNO.Qt ne pas recevoir de données série de arduino

Le code Arduino est très simple. Actuellement, il génère simplement un nombre aléatoire et l'envoie sur la ligne série. Voici le code:

long randNumber; 

void setup() { 
    Serial.begin(9600); 
    randomSeed(analogRead(0)); 
} 

void loop() { 
    randNumber = random(300); 
    Serial.write(randNumber); 
    delay(10); 
} 

Je l'ai utilisé « moniteur série » de l'Arduino pour vérifier que les données sont à venir sur la ligne série. Sur le côté Qt des choses, j'ai un thread de travail qui est censé lire les données série et mettre à jour un tracé sur l'interface utilisateur en conséquence. Le thread de travail est définitivement en cours d'exécution, et ce code est en cours d'exécution (j'ai vérifié). J'ai seulement un périphérique dans ma "liste des ports" qui apparaît, et c'est l'Arduino, donc actuellement je me connecte directement. Voici le code:

void doWork() 
{ 
    QList<QSerialPortInfo> port_list = QSerialPortInfo::availablePorts(); 
    QSerialPort serialPort; 
    serialPort.setPort(port_list[0]); 
    serialPort.setBaudRate(QSerialPort::Baud9600); 

    if (!serialPort.open(QIODevice::ReadWrite)) 
    { 
     cout << QObject::tr("Failed to open port COM3, error: %1").arg(serialPort.errorString()).toStdString() << endl; 
    } 

    while(!abort_thread) 
    { 
     int bytes_available = serialPort.bytesAvailable(); 
     if (bytes_available >= 4) 
     { 
      QByteArray byte_array = serialPort.read(4); 
      int data = byte_array.toInt(); 
      emit signalDataReady(data); 
     } 
    } 

    serialPort.close(); 
} 

Malheureusement, il n'y a jamais d'octets disponibles. Il ouvre le port série avec succès, mais aucun octet ne passe. Qu'est-ce que je fais mal ici? Des idées? Merci!

+0

Vous semblez avoir vérifié à peu près toutes les erreurs que je pouvais penser, mais êtes-vous * absolument sûr * que vous avez seulement un port sur votre ordinateur? Avez-vous imprimé la longueur de 'port_list' ou avez-vous utilisé autre chose pour vérifier? Je demande juste parce que beaucoup d'ordinateurs ont tendance à avoir des ports série supplémentaires même s'ils n'ont pas d'interface physique. –

+0

Je présume que Qt fonctionne sur un PC connecté à votre carte Arduino? - ou est-ce que Qt fonctionne aussi sur un autre forum Arduino? Quoi qu'il en soit, quelques petites choses à essayer: D'abord, dans votre fonction de thread doWork(), vous allez probablement maximiser votre processeur car vous n'avez aucun point de commutation. Essayez d'ajouter 'QThread :: msleep (10);' pour ajouter une pause, ralentir votre interrogation et permettre à d'autres processus d'avoir du temps CPU (pas sûr que ça va le réparer, mais ...). Vous aurez besoin de '#include ' dans votre fichier. –

+0

Deuxième chose ... ok c'est plus un coup de couteau dans le noir que le premier, mais j'ouvre toujours mon QSerialPorts en mettant setPortName() ... fonctionne toujours pour moi. Vous pouvez donc essayer 'serialPort.setPortName (port_list [0] .portName());' au lieu de 'serialPort.setPort (port_list [0]);' –

Répondre

1

Vous avez oublié d'ajouter waitForReadyRead() avant bytesAvailable().

+0

En y regardant de plus près, cela réglerait probablement le problème. Il n'y a probablement pas de boucle d'événement dans votre thread, et je ne me souviens pas comment 'QSerialPort' se comporte sans un, mais les docs déclarent que cette méthode est utile" lors des opérations d'E/S dans un thread non-GUI ". En tout cas, il est bon de bloquer plutôt que d'attendre. –

+0

Après avoir regardé toutes les suggestions faites ici, on dirait que c'est celui qui l'a fait! Merci! Ce qui est intéressant, c'est que je dois le faire chaque fois avant d'appeler bytesAvailable(), et pas seulement une fois après la connexion à l'Arduino. – David

0

De https://www.arduino.cc/en/Serial/Write:

Serial.write (val)

val: une valeur à envoyer un seul octet

Si vous écrivez un numéro Arduino envoie un seul octet, si vous voulez envoyer un long, vous devez le décomposer en tableau et envoyer le tableau (ou obtenir un pointeur sur l'adresse du long et envoyer chacun des octets).

Comme votre code Qt s'attend à lire quatre octets, if n'est jamais exécuté.

+0

C'est probablement une erreur, mais parce que le code Arduino est exécuté dans une boucle, il finira par envoyer 4 octets et plus, ce qui n'explique pas pourquoi aucune donnée n'est reçue par le programme Qt. –

+0

Eh bien, la boucle n'est pas affichée sur le code, je ne peux pas imaginer les détails du code non posté: D (oui, il y a une fonction loop(), mais je ne vois pas vraiment une boucle comme la fonction entre et sort). – Gusman

+0

Pour une raison quelconque, les développeurs Arduino/Wiring ont jugé bon de protéger les programmeurs contre l'écriture de boucles afin qu'ils fournissent une fonction main() qui appelle setup() et continue à appeler loop() dans une boucle pour eux. Allez comprendre. –