ich versuche gerade die gesendete Daten vom Arduino in meiner Software (mit Qt geschrieben) zu verarbeiten und diese in eine Datenbank zu schreiben (MySQL).
Nun zu meinem kleinen Testprogramm:
Gelöst habe ich es (nicht schön zumindest und auch nicht ganz richtig):
while(1)
{
if(serial.bytesAvailable() > 0 ||serial.waitForReadyRead(10))
{
QByteArray reading;
reading = serial.readAll();
serial.write(reading);
qDebug() << reading.size();
QMutex mutex;
mutex.lock();
if(this->Stop)
{
break;
}
mutex.unlock();
if(reading.size() == 4) //das ist nur solange richtig wenn es über 10 Grad ist
emit serialReading(reading);
//this->msleep(1000);
}
}
Wie kann ich in der Software sagen ließ mir nur die ersten 4 Byte´s ein? Oder schickt mir Arduino nicht 4 Byte sondern was anderes?
Hoffe mir kann vielleicht einer helfen?
Wenn du das so machst, schickst du einen C String. Also ASCII
Um einen Float Wert Binär zu schicken musst du glaube ich das machen:
Serial.write((byte*)&temperatur, 4);
Also die Adresse des Floats nehmen und auf einen Zeiger auf Byte casten. Damit werden die 4 Bytes praktisch als Array angesprochen- Dann write() statt print() nehmen und die Länge in Bytes als 2. Parameter angeben.
Serenifly:
Wenn du das so machst, schickst du einen C String. Also ASCII
Um einen Float Wert Binär zu schicken musst du glaube ich das machen:
Serial.write((byte*)&temperatur, 4);
Also die Adresse des Floats nehmen und auf einen Zeiger auf Byte casten. Damit werden die 4 Bytes praktisch als Array angesprochen- Dann write() statt print() nehmen und die Länge in Bytes als 2. Parameter angeben.
Ich werde das mal ausprobieren. Die "4" nach "&temperatur" gibt mir die Byte größe an? Sehe ich das richtig?
Nimm openHAB und diesen Sketch:
http://www.mikrocontroller.net/articles/Evaluations-Platine_f%C3%BCr_Heimautomatisierung
Ganz unten sind die Dateien.
Soll nicht böse gemeint sein aber bleibe lieber bei Qt da ich mich soweit schon zurecht finde. Nur mit Serial Verbindungen habe ich noch nichts gemacht. Ist schon neu für mich.
Hast du mal getestet ob in deinem Array die richtige Wert stehen? Also mal Debugger oder über das Array iterieren und alle 4 Bytes ausgeben. Du kannst auch einfach mal einen festen Float Wert nehmen, diesen als Byte Array ansprechen und ausgeben. Dann kannst du vergleichen.
Dein Problem kann das hier sein:
serial.bytesAvailable() > 0
Die serielle Schnittstelle ist sehr langsam. Bei 9600 Bytes dauert ein Zeichen ca. 1ms!! Wenn du also abfragst ob ein Byte da ist, sind die restlichen noch unterwegs.
Wenn du 4 Bytes erwartest, solltest du auch warten bis 4 Bytes da sind und noch schon nach dem ersten Byte alles einlesen.
Lass mir jetzt mal probehalber immer 32.2 schicken als festen Wert um zu schauen was dabei heraus kommt.
Welche Baudrate kann ich noch nehmen?
Werde mal die if Abfrage nochmal überarbeiten.
Mit der Baudrate sollte eigentlich alles übliche gehen. Auf dem PC gehen meistens sogar Baudraten über 115200 wie 250000. Wobei das bei dir nicht nötig ist.
Das Problem geht dabei aber so oder so nicht weg. Selbst wenn ein Zeichen nur ein paar Dutzend µs braucht, ist das für einen Prozessor eine lange Zeit.
Mit Qt im speziellen kenne ich mich nicht aus. Daher kann ich nicht sagen was die Qt Funktionen im Detail machen.
char *data = reading.data();
Das sollte unsigned char sein. Char lässt negative Zahlen zu. Wobei das hier nicht unbedingt einen Fehler verursacht.
Wenn man die 4 Bytes von 27.8 für sich ausgibt sollte folgendes rauskommen:
102
102
222
65
Um den Inhalt von Arrays bequem byte-weise auszugeben kannst du das machen:
void printArray(void* data, unsigned int size)
{
unsigned char* ptr = (unsigned char*)data;
for(unsigned int i = 0; i < size; i++)
qDebug() << (int)ptr[i] << " ";
}
Sowas sollte zum Einlesen auch gehen:
unsigned char data[4];
data[0] = serial.readByte(); ///weiß nicht ob es das so gibt, aber ein Byte lesen sollte irgendwie möglich sein
data[1] = serial.readByte();
data[2] = serial.readByte();
data[3] = serial.readByte();
float f = *(float*)data;
Negative Zahlen für float natürlich. Aber nicht für die eingelesenen Bytes. Aber wie gesagt, macht das hier glaube ich keinen Unterschied. Funktionen wie read() verwenden da auch char* statt unsigned char*
Sicherer ist es dann auch wenn du bei serial.bytesAvailable() auf >= 4 abfragst, statt auf == 4
Das ist aber auch nur die maximale Anzahl. Wenn weniger da ist, liest er auch weniger. Und ein paar Posts weiter oben hat reading.size() anscheinend nicht immer 4 geliefert obwohl du gewartet hast bis 4 Bytes da waren. Das ist etwas seltsam