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!"); } }
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 pedign
… - amikor olyan hibakeresés során pl. a tiéd a
Serial.println(br);
-t aanalogWrite()
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.