如何正确地通过蓝牙从 Android 向 Arduino 连续发送消息
Posted
技术标签:
【中文标题】如何正确地通过蓝牙从 Android 向 Arduino 连续发送消息【英文标题】:How to proper send messages via bluetooth from Android to Arduino continuously 【发布时间】:2021-11-12 11:57:22 【问题描述】:我的目标是借助我的 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 接收端代码。onTouchEvent
在 UI 线程上,而 BT 输出流是阻塞写入,让我相信它不在发送端 - 所以我会对接收端感兴趣。 (请注意,由于输出流写入阻塞,您最终可能会在 Android UI 端遇到问题 - 但我假设现在这不是问题。)
嘿。我不认为接收端的问题。接收方只接收我发送给它的任何字符/字节,并制作一条消息/字符串。当输入为空或符号为“/”时,它会在显示器上打印一条消息并清除此字符串。无论如何,我将代码放在原始消息下。你可以看看。谢谢。
Buuut...也许你是对的。也许是接收方。由于某种原因,我把这个延迟(5)。
现在我觉得我需要……匹配一个传输和接收的速度……也许吧。但不知道具体是什么。
else
部分中的逻辑(我将其解释为“没有可用的,所以打印我目前所拥有的”)是错误的。它会打印您到目前为止所拥有的内容,但随后会清除该消息。更多的字符进来(还不是'/'),然后打印它(从 (0,0) 开始)并显示它 - 这只是最后收到的字符。我建议在“else”部分中注释掉serialMessage = "";
,以保留累积的信息。 (可能不是唯一的问题,但请尝试一下)。
【参考方案1】:
是的。它溢出了串行。 我分两步解决这个问题。 首先,我将 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();
【讨论】:
以上是关于如何正确地通过蓝牙从 Android 向 Arduino 连续发送消息的主要内容,如果未能解决你的问题,请参考以下文章
如何在后台的两个 android 活动之间交换数据以通过蓝牙发送数据?