Creo applicazioni per un computer che deve essere utilizzato per controllare il braccio del robot. Volevo fare il primo tentativo di eseguire lapplicazione non sul motore, ma sul diodo e controllare se cambierà la sua luminosità a seconda della posizione del cursore. Ho scritto unapplicazione in Qt che invia le cinghie ad Arduino e Arduino lho letto e lo converte in int. Il problema è che sebbene lo slider sia impostato a 0, lArduino non lo mostra, spesso le cifre non sono troppo spesso (spesso troppo piccole), anche quando sposto bruscamente lo slider del numero tutto il tempo count verso la parte anteriore invece che indietro.
Codice Arduino:
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()); } }
Codice Qt:
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!"); } }
Commenti
Risposta
Come ha scritto Majenko nel suo commento, il tuo problema risiede con Serial.readString()
. In genere non è un buon modo per gestire i dati seriali. Legge i dati dallinterfaccia seriale, fino a quando non si verifica il timeout (predefinito 1s). Quindi proverà a leggere fino a 1 secondo dopo lultima modifica del dispositivo di scorrimento e restituirà tutti i dati come una stringa. String.toInt()
inizierà quindi a leggere la stringa dal primo carattere e la convertirà in un numero intero, fino a quando non legge un carattere non numerico (ovvero n
, che invii). Si ferma qui e restituisce il valore già convertito.
Ciò significa che di tutti i dati che sono stati inviati ad Arduino, verrà utilizzato solo il primo valore. Il resto viene gettato via.
È meglio usare un codice non bloccante, che gestisca correttamente i messaggi (numeri nel tuo caso). Questo viene fatto leggendo i dati seriali in arrivo byte per byte, aggiungendoli in un buffer, finché non viene ricevuto uno speciale carattere delimitatore. Quindi il messaggio viene elaborato nel suo insieme. Dopodiché, il messaggio successivo può essere letto ed elaborato. In questo modo non perderai nessuno dei valori di invio.
Il carattere delimitatore speciale è arbitrario; puoi usare qualsiasi carattere, che non si trova nei dati validi. Quindi usare il carattere n
va bene qui. Ma principalmente viene utilizzato il carattere di nuova riga \n
, in modo da poter inviare anche messaggi con caratteri alfanumerici. Molto probabilmente intendevi già utilizzare \n
.
Come esempio di questo codice seriale, puoi utilizzare readline()
funzione dal post del blog di Majenko :
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("<"); } }
Puoi convertire il buffer dei caratteri a un int con atoi()
nellistruzione if in void loop()
e usalo per ´analogWrite () `.
\n
ai tuoi messaggi in uscita, nonn
…Serial.println(br);
prima dianalogWrite()
per vedere cosa viene ricevuto