Von Strings zu int problem

Ich erstelle Anwendungen für einen Computer, mit dem der Roboterarm gesteuert werden soll. Ich wollte den ersten Versuch unternehmen, die Anwendung nicht auf dem Motor, sondern auf der Diode auszuführen, und prüfen, ob sich die Helligkeit je nach Position des Schiebereglers ändert. Ich habe eine Anwendung in Qt geschrieben, die Riemen an Arduino sendet, und Arduino habe ich gelesen und in int konvertiert. Das Problem ist, dass, obwohl der Schieberegler auf 0 gesetzt ist, der Arduino ihn nicht anzeigt, die Zahlen oft nicht zu oft übereinstimmen (oft zu klein), auch wenn ich den Zahlenregler plötzlich die ganze Zeit nach vorne anstatt nach vorne bewege zurück.

Arduino-Code:

String br; void setup() { Serial.begin(9600); pinMode(9, OUTPUT); } void loop() { while (Serial.available()>0) { br = Serial.readString(); analogWrite(9, br.toInt()); Serial.println(br.toInt()); } } 

Qt-Code:

void MainWindow::on_horizontalSliderGrip_sliderMoved(int position) { this->sendMessageToDevice(QString::number(position) + "n"); qDebug() << "Grip: " << QString::number(position); } void MainWindow::sendMessageToDevice(QString message) { if(this->device->isOpen() && this->device->isWritable()) { //this->addToLogs("Sending information to the device " + message); this->device->write(message.toStdString().c_str()); } else { this->addToLogs("I can not send a message. The port is not open!"); } } 

Geben Sie hier die Bildbeschreibung ein.

Kommentare

  • Serial.readString () ist stark fehlerhaft und sollte vermieden werden. Lesen Sie dies: majenko.co.uk/blog/reading-serial-arduino
  • Und ich bin sicher Sie wollten \n zu Ihren ausgehenden Nachrichten hinzufügen, nicht n
  • , wenn Sie ein Problem wie z Ihre setzen Serial.println(br); vor die analogWrite(), um zu sehen, was empfangen wird

Antwort

Wie Majenko in seinem Kommentar schrieb, liegt Ihr Problem bei Serial.readString(). Es ist im Allgemeinen keine gute Möglichkeit, mit seriellen Daten umzugehen. Es liest Daten von der seriellen Schnittstelle, bis das Zeitlimit (Standard 1s) auftritt. Es wird also versucht, bis 1 Sekunde nach Ihrer letzten Änderung des Schiebereglers zu lesen und die gesamten Daten als eine Zeichenfolge zurückzugeben. String.toInt() beginnt dann, die Zeichenfolge vom ersten Zeichen an zu lesen und in eine Ganzzahl umzuwandeln, bis ein nicht-stelliges Zeichen gelesen wird (dh n, das du sendest). Es stoppt dort und gibt den bereits konvertierten Wert zurück.

Dies bedeutet, dass von allen Daten, die an das Arduino gesendet wurden, nur der erste Wert verwendet wird. Der Rest wird weggeworfen.

Besser, Sie sollten einen nicht blockierenden Code verwenden, der die Nachrichten (in Ihrem Fall die Zahlen) korrekt verarbeitet. Dies erfolgt durch Lesen der eingehenden seriellen Daten Byte für Byte. Hinzufügen in einen Puffer, bis ein spezielles Trennzeichen empfangen wird. Dann wird die Nachricht als Ganzes verarbeitet. Danach kann die nächste Nachricht gelesen und verarbeitet werden. Auf diese Weise verpassen Sie keinen der Sendewerte.

Das Sondertrennzeichen ist beliebig. Sie können jedes Zeichen verwenden, das in den gültigen Daten nicht vorkommt. Die Verwendung des Zeichens n ist hier also in Ordnung. Meistens wird jedoch das Zeilenumbruchzeichen \n verwendet, sodass Sie auch Nachrichten mit alphanumerischen Zeichen senden können. Höchstwahrscheinlich wollten Sie bereits \n verwenden.

Als Beispiel für diesen Seriencode können Sie die readline() Funktion aus Majenkos Blogpost :

char buf[80]; int readline(int readch, char *buffer, int len) { static int pos = 0; int rpos; if (readch > 0) { switch (readch) { case "\r": // Ignore CR break; case "\n": // Return on new-line rpos = pos; pos = 0; // Reset position index ready for next time return rpos; default: if (pos < len-1) { buffer[pos++] = readch; buffer[pos] = 0; } } } return 0; } void setup() { Serial.begin(115200); } void loop() { if (readline(Serial.read(), buf, 80) > 0) { Serial.print("You entered: >"); Serial.print(buf); Serial.println("<"); } } 

Sie können den Zeichenpuffer konvertieren zu einem int mit atoi() in der if-Anweisung in void loop() und verwenden Sie es für ´analogWrite () `.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.