A karakterláncoktól az int problémáig

Olyan számítógéphez hozok létre alkalmazásokat, amelyeket a robotkar vezérléséhez kell használni. Meg akartam tenni az első kísérletet arra, hogy az alkalmazást ne a motoron, hanem a diódán futtassam, és ellenőrizzem, hogy a csúszka helyzetétől függően megváltoztatja-e a fényerejét. Qt-ben írtam egy alkalmazást, amely tangákat küld az Arduino-nak, az Arduino-t pedig elolvastam és átalakítottam int-be. A probléma az, hogy bár a csúszka 0-ra van állítva, az Arduino nem mutatja, gyakran a számok nem egyeznek túl gyakran (gyakran túl kicsi), akkor is, amikor hirtelen a számcsúszkát mozgatom folyamatosan az elülső rész helyett vissza.

Arduino kód:

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 kód:

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!"); } } 

ide írja be a kép leírását

megjegyzések

  • A Serial.readString () mélyen hibás, ezért kerülni kell. Olvassa el ezt: majenko.co.uk/blog/reading-serial-arduino
  • És biztos vagyok \n -et akartad hozzáadni a kimenő üzenetekhez, nem pedig n
  • amikor olyan hibakeresés során pl. a tiéd a Serial.println(br); -t a analogWrite() elé helyezte, hogy lássa, mi érkezik

Válasz

Amint Majenko megjegyzésében megírta, a problémád Serial.readString() -nel van. Általában nem jó módszer a soros adatok kezelésére. Az adatokat a soros interfészről olvassa fel, amíg az időkorlát (alapértelmezett 1 s) meg nem történik. Tehát a csúszka legutóbbi változtatása után 1 másodpercig próbál olvasni, és az egész adatot egy karakterláncként adja vissza. A String.toInt() ekkor elkezdi olvasni a karakterláncot az első karaktertől, és egész számúra konvertálja őket, amíg nem számjegyű karaktert (azaz a n, amit elküld). Itt áll meg, és visszaadja a már konvertált értéket.

Ez azt jelenti, hogy az Arduino-nak küldött összes adat közül csak az első értéket használjuk. A többit eldobják.

Jobb, ha nem blokkoló kódot használ, amely helyesen kezeli az üzeneteket (esetünkben a számokat). Ez úgy történik, hogy a bejövő soros adat byte-ot olvassa el, pufferbe adva őket, amíg egy speciális elválasztó karakter nem érkezik. Ezután az üzenet teljes egészében feldolgozásra kerül. Ezt követően a következő üzenet olvasható és feldolgozható. Így nem hagyja ki az egyik küldési értéket sem.

A speciális határoló karakter tetszőleges; bármilyen karaktert használhat, amely nem szerepel az érvényes adatokban. Tehát a n karakter használata itt rendben van. De leginkább az új vonalas karaktert használják: \n, így alfanumerikus karakterekkel is küldhet üzeneteket. Valószínűleg már az \n használatát kívánta használni.

Ennek a soros kódnak a példájaként a readline() function Majenko blogbejegyzéséből :

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("<"); } } 

Konvertálhatja a karakterpuffert egy int-re, ahol atoi() található az if utasításban a void loop() fájlban, és használja az “analogWrite ()” kifejezésre.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük