Eu crio aplicativos para um computador que será usado para controlar o braço do robô. Queria fazer a primeira tentativa de executar o aplicativo não no motor, mas no diodo e verificar se ele mudará o brilho dependendo da posição do controle deslizante. Eu escrevi um aplicativo em Qt que envia thongs para o Arduino, e o Arduino eu leio e converte para int. O problema é que embora o controle deslizante esteja definido como 0, o Arduino não mostra isso, muitas vezes os números não concordam com muita frequência (muitas vezes muito pequenos), também quando eu movo o controle deslizante de número o tempo todo, conte para a frente em vez de de volta.
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!"); } }
Comentários
Resposta
Como Majenko escreveu em seu comentário, seu problema está em Serial.readString()
. Geralmente não é uma boa maneira de lidar com dados seriais. Ele lê os dados da interface Serial, até que ocorra o tempo limite (padrão 1s). Portanto, ele tentará ler até 1 segundo após a última alteração do controle deslizante e retornar todos os dados como uma string. String.toInt()
começará a ler a string a partir do primeiro caractere e os converterá em um número inteiro, até que leia um caractere diferente de dígitos (significando o n
Isso significa que de todos os dados que foram enviados para o Arduino, apenas o primeiro valor será utilizado. O resto é jogado fora.
Melhor você deve usar um código sem bloqueio, que trate as mensagens (números no seu caso) corretamente. Isso é feito lendo os dados seriais de entrada byte a byte, adicionando-os em um buffer, até que um caractere delimitador especial seja recebido. Em seguida, a mensagem é processada como um todo. Depois disso, a próxima mensagem pode ser lida e processada. Dessa forma, você não perde nenhum dos valores de envio.
O caractere delimitador especial é arbitrário; você pode usar qualquer caractere, que não ocorre nos dados válidos. Portanto, usar o caractere n
está ok aqui. Mas principalmente o caractere de nova linha \n
é usado, de modo que você também pode enviar mensagens com caracteres alfanuméricos. Provavelmente você já pretendia usar \n
.
Como um exemplo deste código de série, você pode pegar o readline()
função da postagem do blog do Majenko “s :
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("<"); } }
Você pode converter o buffer de caracteres para um int com atoi()
na instrução if em void loop()
e use-o para ´analogWrite () `.
\n
às mensagens enviadas, nãon
…Serial.println(br);
antes deanalogWrite()
para ver o que está sendo recebido