文字列からint問題まで

ロボットアームの制御に使用するコンピューター用のアプリケーションを作成します。モーターではなくダイオードでアプリケーションを実行する最初の試みを行い、スライダーの位置に応じて明るさが変化するかどうかを確認したかったのです。私はQtで、Arduinoにひもを送るアプリケーションを作成しました。Arduinoを読んでintに変換します。問題は、スライダーが0に設定されていても、Arduinoがそれを表示しないことです。また、数字スライダーを突然動かしたときにも、数字があまり一致しないことがよくあります(多くの場合小さすぎます)。戻る。

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()); } } 

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!"); } } 

ここに画像の説明を入力

コメント

  • Serial.readString()には重大な欠陥があるため、回避する必要があります。これを読んでください: majenko.co.uk/blog/reading-serial-arduino
  • そして私は確かに n
  • などの問題をデバッグするときに、送信メッセージに\nを追加するつもりでした。 Serial.println(br);analogWrite()の前に置いて、何が受信されているかを確認します

回答

Majenkoがコメントに書いているように、問題はSerial.readString()にあります。通常、シリアルデータを処理するのに適した方法ではありません。タイムアウト(デフォルトは1秒)が発生するまで、シリアルインターフェースからデータを読み取ります。したがって、スライダーを最後に変更してから1秒後まで読み取りを試み、データ全体を1つの文字列として返します。 String.toInt()は、最初の文字から文字列の読み取りを開始し、数字以外の文字(n、送信します)。ここで停止し、すでに変換された値を返します。

これは、Arduinoに送信されたすべてのデータのうち、最初の値のみが使用されることを意味します。残りは破棄されます。

メッセージ(この場合は数値)を正しく処理する非ブロッキングコードを使用することをお勧めします。これは、着信シリアルデータをバイトごとに読み取ることによって行われます。特別な区切り文字が受信されるまで、それらをバッファに追加します。次に、メッセージが全体として処理されます。その後、次のメッセージを読み取って処理できます。これにより、送信値を見逃すことはありません。

特殊な区切り文字は任意です。有効なデータに含まれていない任意の文字を使用できます。したがって、ここではnという文字を使用しても問題ありません。ただし、ほとんどの場合、改行文字\nが使用されるため、英数字を使用してメッセージを送信することもできます。おそらく、すでに\nを使用するつもりでした。

このシリアルコードの例として、readline() 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("<"); } } 

文字バッファーを変換できますvoid loop()のifステートメントにatoi()が含まれるintに移動し、それを「analogWrite()」に使用します。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です