Creo aplicaciones para una computadora que se utilizará para controlar el brazo robótico. Quería hacer el primer intento de ejecutar la aplicación no en el motor, sino en el diodo y verificar si cambiará su brillo dependiendo de la posición del control deslizante. Escribí una aplicación en Qt que envía tangas a Arduino, y Arduino lo leo y lo convierte a int. El problema es que aunque el control deslizante está configurado en 0, el Arduino no lo muestra, a menudo las cifras no coinciden con demasiada frecuencia (a menudo demasiado pequeñas), también cuando de repente muevo el control deslizante de números todo el tiempo, cuenta hacia el frente en lugar de volver.
Código 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()); } }
Código 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!"); } }
Comentarios
- Serial.readString () tiene muchos defectos y debe evitarse. Lea esto: majenko.co.uk/blog/reading-serial-arduino
- Y estoy seguro pretendías agregar
\n
a tus mensajes salientes, non
… - al depurar un problema como el suyo ponga
Serial.println(br);
antes deanalogWrite()
para ver lo que se está recibiendo
Respuesta
Como escribió Majenko en su comentario, su problema radica en Serial.readString()
. Por lo general, no es una buena forma de manejar datos en serie. Lee datos de la interfaz serial, hasta que se agota el tiempo de espera (predeterminado 1 s). Por lo tanto, intentará leer hasta 1 segundo después de su último cambio del control deslizante y devolverá todos los datos como una sola cadena. String.toInt()
comenzará a leer la cadena del primer carácter y la convertirá en un número entero, hasta que lea un carácter que no sea un dígito (es decir, n
, que envías). Se detiene allí y devuelve el valor ya convertido.
Esto significa que de todos los datos que se enviaron al Arduino, solo se usará el primer valor. El resto se tira a la basura.
Mejor debería usar un código no bloqueante, que maneje los mensajes (números en su caso) correctamente. Esto se hace leyendo los datos seriales entrantes byte a byte, agregándolos a un búfer, hasta que se reciba un carácter delimitador especial. Luego, el mensaje se procesa en su totalidad. Después de eso, el siguiente mensaje puede leerse y procesarse. De esta manera, no se pierde ninguno de los valores enviados.
El carácter delimitador especial es arbitrario; puede utilizar cualquier carácter que no se encuentre en los datos válidos. Entonces, usar el carácter n
está bien aquí. Pero principalmente se usa el carácter de nueva línea \n
, de modo que también puede enviar mensajes con caracteres alfanuméricos. Lo más probable es que ya pretendiera usar \n
.
Como ejemplo de este código de serie, puede tomar el readline()
función de entrada 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("<"); } }
Puede convertir el búfer de caracteres a un int con atoi()
en la instrucción if en void loop()
y utilícelo para ´analogWrite () `.