2017-04-27 2 views
0

Je travaille sur une fonction simple qui est capable de retourner un int dans Qt en utilisant les informations envoyées à un port. J'utilise la classe QSerialPort qui renvoie QBytearray.Qt - Bytearray avec des entrées vides?

Le problème est que je semble (occasionnellement) obtenir des entrées vides dans le tableau renvoyé par QSerialPort.readAll. Cela me rend incapable de convertir le bytearray en int.

La fonctionnalité de base est: Demandez à Arduino d'envoyer de la température ou de l'humidité.

Code Qt:

#include <QCoreApplication> 
#include <QSerialPortInfo> 
#include <QSerialPort> 
#include <iostream> 
#include <string> 
#include <windows.h> 
#include <math.h> 
using namespace std; 


int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 

    QString comPort = "COM6"; 
    QSerialPortInfo ArduinoInfo(comPort); 

    cout << "Manufacturer: " << ArduinoInfo.manufacturer().toStdString() << endl; 
    cout << "Product Identifier: " << ArduinoInfo.productIdentifier() << endl; 
    cout << "Vendor Identifier: " << ArduinoInfo.vendorIdentifier() << endl; 

    QSerialPort Arduino(ArduinoInfo); 

    Arduino.setBaudRate(QSerialPort::Baud9600); 
    Arduino.open(QSerialPort::ReadWrite); 

    Sleep(1000); 

    if(Arduino.isDataTerminalReady()) 
     cout << "Great Sucess" << endl; 

    char sending = 'H'; 


    cout << sending << endl; 

    Arduino.write(&sending, 1); 

    //int maxSize = Arduino.bytesAvailable(); 

    while(!Arduino.waitForReadyRead()){} 
    Sleep(100); 

    QByteArray rawDataArry = Arduino.readAll(); 
    cout << "Shit has been read." << endl; 


    // Form here on its just write functions, used for debug 

    cout << "rawData:" << endl; 
    for(int i=0; i < rawDataArry.size(); i++) 
     cout << "[" << i << "] "<< rawDataArry[i] << endl; 

    cout << "All data:" << endl; 
    for(char s:rawDataArry){ 
     cout << s; 
    } 
    cout << endl; 

    cout << "Converted data:" << endl; 
    bool ok; 
    int returnVar = rawDataArry.toInt(&ok, 10); 
    cout << returnVar << endl; 
    cout << "Convertion Status:" << ok; 

    Arduino.close(); 

    return a.exec(); 
} 

Le code Arduino est super simple.

#include <dht.h> 

dht DHT; 

#define PIN_7 7 

void setup() { 
    Serial.begin(9600); 
} 

void loop() 
{ 
    String impString; 

    while(Serial.available() != 1); 
    impString = Serial.readString(); 

    DHT.read11(PIN_7); 

    if(impString == "T") 
    { 
    int temp = DHT.temperature; 
    Serial.println(temp); 
    } 
    else if(impString == "H") 
    { 
    int humid = DHT.humidity; 
    Serial.println(humid); 
    } 

    emptyReceiveBuf(); 
    delay(100); 
} 

void emptyReceiveBuf() 
{ 
    int x; 
    delay(200); // vent lige 200 ms paa at alt er kommet over 

    while (0 < Serial.available()) 
    { 
    x = Serial.read(); 
    } 
} 

moniteur terminal affiche:

enter image description here

+0

S'il vous plaît [modifier] votre code pour le réduire à [mcve] de votre problème. Votre code actuel comprend beaucoup de choses qui sont périphériques à votre problème - un échantillon minimal ressemble normalement à un bon test unitaire: effectuer une seule tâche, avec des valeurs d'entrée spécifiées pour la reproductibilité. –

+0

Vous pourriez trouver la méthode 'QByteArray :: toHex()' utile, btw. – hyde

Répondre

0

dirait rawDataArry.size() est de retour 4, ce qui signifie qu'il y a 4 octets dans le tableau. Cependant, lorsque vous appelez rawDataArry[i], il retourne un caractère. Toutes les valeurs char ne peuvent pas être représentées comme un caractère ASCII. C'est pourquoi les 2 derniers octets apparaissent vides. Au lieu de cela, vous devriez essayer de convertir chaque caractère en une valeur qui montre la représentation décimale/hexadécimale de l'octet au lieu de la représentation ASCII.

Sinon, vous pouvez convertir ces 4 octets droit à un int et faire avec elle:

//Big Endian 
quint32 myValue(0); 
for(int i=0; i<4; i++) 
    myValue = myValue + (quint8(rawDataArry.at(i)) << (3-i)*8); 
//myValue should now have your integer value 
+0

Merci pour l'entrée! - J'ai pris conscience du fait que QByteArray avait un membre capable de supprimer toutes les entrées et les espaces vides. Il a fini par fonctionner très bien! –

0

Je fini par utiliser un membre de QByteArray pour nettoyer les widespaces dans le tableau!

Il ressemble à ceci:

bool ok; 
int returnVal; 

do 
{ 
    Arduino.write(&imputChar, 1); // Arduino input Char 

    Arduino.waitForReadyRead(); 

    QByteArray rawDataArry(Arduino.readAll()); // Empties buffer into rawDataArry 
    QByteArray dataArray(rawDataArry.simplified()); // Removes all widespaces! 

    returnVal = dataArray.toInt(&ok, 10); // Retuns ByteConvertion - &OK is true if convertion has completed - Widespaces will ruin the conversion 

    qDebug() << "Converted data:"; 
    qDebug() << returnVal; 
    qDebug() << "Convertion Status:" << ok; 
    }while(ok != 1); 

    return(returnVal);