Je crée des applications pour un ordinateur qui doit être utilisé pour contrôler le bras du robot. Je voulais faire la première tentative dexécuter lapplication non pas sur le moteur, mais sur la diode et vérifier si elle changera sa luminosité en fonction de la position du curseur. Jai écrit une application dans Qt qui envoie des tongs à Arduino, et Arduino je lis et convertis en int. Le problème est que bien que le curseur soit réglé sur 0, lArduino ne le montre pas, souvent les chiffres ne concordent pas trop souvent (souvent trop petits), même lorsque je déplace soudainement le curseur de nombre tout le temps compte vers lavant au lieu de retour.
Code 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()); } }
Code 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!"); } }
Commentaires
Réponse
Comme lécrit Majenko dans son commentaire, votre problème réside dans Serial.readString()
. Ce nest généralement pas un bon moyen de gérer les données série. Il lit les données de linterface série, jusquà ce que le délai (par défaut 1s) se produise. Il essaiera donc de lire jusquà 1 seconde après votre dernier changement de curseur et retournera toutes les données sous la forme dune chaîne. String.toInt()
commencera alors à lire la chaîne à partir du premier caractère et à les convertir en un entier, jusquà ce quil lit un caractère non numérique (signifiant le n
, que vous envoyez). Il sarrête là et renvoie la valeur déjà convertie.
Cela signifie que sur toutes les données envoyées à lArduino, seule la première valeur sera utilisée. Le reste est jeté.
Mieux vaut utiliser un code non bloquant, qui gère correctement les messages (numéros dans votre cas). Cela se fait en lisant les données série entrantes octet par octet en les ajoutant dans un tampon, jusquà ce quun caractère de délimitation spécial soit reçu. Ensuite, le message est traité dans son ensemble. Après cela, le message suivant peut être lu et traité. De cette façon, vous ne manquez aucune des valeurs denvoi.
Le caractère de délimitation spécial est arbitraire; vous pouvez utiliser nimporte quel caractère qui napparaît pas dans les données valides. Donc, utiliser le caractère n
est correct ici. Mais la plupart du temps, le caractère de nouvelle ligne \n
est utilisé, de sorte que vous pouvez également envoyer des messages avec des caractères alphanumériques. Vous vouliez probablement déjà utiliser \n
.
Comme exemple de ce code de série, vous pouvez prendre le readline()
fonction de billet de blog de 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("<"); } }
Vous pouvez convertir le tampon de caractères à un entier avec atoi()
dans linstruction if de void loop()
et utilisez-le pour ´analogWrite () `.
\n
à vos messages sortants, et nonn
…Serial.println(br);
avant leanalogWrite()
pour voir ce qui est reçu