android - 如何正确地通过蓝牙从 Android 向 Arduino 连续发送消息
问题描述
我的目标是借助我的 android 手机通过 BT 控制一些 arduino 设备。当我触摸屏幕并四处移动手指时,android 应用程序会根据我的手指位置生成一些数据,形成字符串消息,然后尝试通过 BT 发送。
问题是,当应用程序尝试发送此命令的多次迭代时。
例如命令为:String command = "[code]command(data)/";
当我在屏幕上点击一个时间时,应用程序编写一次命令并通过 BT 发送它,它在另一边(arduino)看起来不错。但是当我握住并移动手指时,应用程序试图每“帧”重写命令,并且还试图每“帧”发送这个命令(我的意思是,每时每刻,很多次)。然后我看到类似:“[code]co[cod[co[c[mma(da]coode[c[co".
感觉是......它获取一个字符数组并将其与另一个混合,发送时......或在停止发送之前开始发送另一条消息。
这是在触摸事件中获取一些值的代码:
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initPosX = x;
break;
case MotionEvent.ACTION_MOVE:
// some code that make counts and convert values...
// prepare string as a command.
String command = "[code]command(" + value + ")/";
Log.d("command", command);
// send data via BT
sendData(command);
break;
case MotionEvent.ACTION_UP:
//code
break;
default:
break;
}
我也有BT设置代码,一切都很好。
这是主要部分。发送字符串的代码:
protected void sendData(String message) {
byte[] msgBuffer = message.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
//some exception code
}
}
outStream = btSocket.getOutputStream();
所以...我真的不知道为什么会这样。我浪费了一整天的时间来搜索有关的东西。如果有人能给我胶水,下一步该在哪里挖,将不胜感激。谢谢。
更新: Arduino侧代码:
if (Serial.available() > 0) {
char c = Serial.read(); // read char from BT
serialMessage.concat(c); // add this char to string.
delay(5);
if (c == '/') {
lcd.setCursor(0,0);
lcd.print(serialMessage); // print message on a display.
command = serialMessage;
serialMessage = "";
}
}
else {
if (serialMessage != "") {
lcd.setCursor(0,0);
lcd.print(serialMessage); // print message on a display.
serialMessage = "";
}
//command = serialMessage;
}
更新 2: 这是一个真正的串行输入,当我点击一次时
[code]command(0.0)/
当我左右移动手指时
[code]command(0.0)/
[code]command(0.0)/
[code]command(0.0)/
[code]command(0.23)/
[code]cm()dm()[c]a.[em1[(/
em1[em1[]a.cca.[e)[dm(/
dm(/
em1[em1[co0ood)dmd4ood8oon2ccn0cca0/
ccn.[]a-)dm(6oon.[]a1[]od0o0[c]a1[]a1[em-/
em-)dm()dm(0odcn.cca0a.[]a.[em0/
em0)dm()dm()dm(/
em1/
em1[]a1[]a.ccn0oon7ccn4c]a.ccn.[em-)dm()oodod0ccn.ccn.[]m-/
d0ooood0ccn.ccn.[]a1[]a-/
em-/
em(5ood7c]a0/
em-)ood0[em0)dm()dm(3od)dm(/
dm(/
em1[em1[]a.c]a)dodm()ood2ccn./
ed9[]a1[]a-/
em-/
em()dm()dmd0od0ooood0oon.codecn1[]a0/
[dm(5ccn.cd0ccn1ccn.[]d4ooood7ocn3
更新3: 毫不拖延地点击:
[
code]c
ommand(0.0)/
[code]command(0.0)/
[
code]c
ommand(0.0)/
[code]command(0.0)/
[
code]c
ommand(0.0)/
[code]command(0.0)/
更新 4:
[code]command(0.0)/
[code]command(0.0)/
[code]command(0.0)/
[code]command(0.0)/
[code]command(0.0)/
[code]command(0.01)/
[code]command(0.07)/
[code]command(0.15)/
[code]command(0.23)/
[code]command(0.29)/
[code]command(0.33)/
[code]command(0.37)/
[code]command(0.41)/
[co(0.44)/
[code]commandmmand(0.51)/
[code]code]command(0.6)/
[cod0.63)/
[cod0.65)/
[code]command(0.66)67)/
[code]command(0.68)/
2)/
解决方案
是的。它溢出了串行。我分两步解决这个问题。首先,我将 arduino 端的字符读取延迟从 5 减少到 1。其次,我每秒仅发送 10 次消息/命令。有一个代码可以做到这一点:
public void send(String string) {
if ((System.currentTimeMillis() - lastTimeSend) > 100) {
byte[] bytes = string.getBytes();
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
lastTimeSend = System.currentTimeMillis();
}
}
推荐阅读
- angular - 在 Angular 中的所有组件之间共享服务
- html - 为什么内联块 div 在悬停时会改变位置?
- oop - 我应该如何在 UML 图中设置变量和嵌套数据?
- go - 锁定文件以更新一段数据或所有文件内容
- apache-spark - 如何在 jupyter notebook 中将 spark 数据帧写入 avro 文件格式?
- laravel - 访问 laravel 请求变量的更好做法是什么
- css - 相同的 css svg 内容 url 的高度比 svg 标签高 4px?
- python - 如何使用 Python 3 读取流?(不带请求模块)
- c# - 如何有效地处理从 Listview 的数据模板中生成的事件
- ruby-on-rails - Rails:当我们需要在循环内查询关联时,如何删除 n+1 查询?