android - 由 Arduino 信号驱动的线程中运行的计数器会跳过前几个数字
问题描述
我已经在 Arduino(HC-05 蓝牙模块)和我的 Android 应用程序之间建立了蓝牙连接。
每次 Arduino 发送信号(信号只是数字 72)时,我的 Android 应用程序都会读取此信号(作为 an 中的字节InputStream
)并将“计数器”变量设置为counter = counter - 1。
我创建了一个执行此操作的线程。
问题是:
例如,如果我将计数器设置为 30 并启动线程,则 30 的前 3-4 次减法以毫秒为单位发生(它们不与 Arduino 信号同步)。但是从 26 开始,一切都完美同步并按预期工作。
我尝试了不同的Thread.sleep()
时间。更长的睡眠时间会使问题变得更糟(更多的减法在毫秒内发生)。睡眠时间越短越好,但仍然不能解决我的问题。
为什么前 3-6 个减法的线程不同步,而其他所有减法的线程都同步?
一些(也许)有用的信息:
有 4 个按钮。“连接”、“断开”、“开始”和“停止”。
- “连接”:通过 BluetoothSocket 与 HC-05 建立连接。
- “断开连接”:关闭此连接。
- “开始”:启动
InputStream
从 HC-05 监听数据的线程。 - “停止”:停止该线程。
我的代码(线程代码)。如果有人需要代码的任何其他部分,请索取:
//CONNECT
arduinoSocket?.connect()
Toast.makeText(this, "Επιχειρείται σύνδεση με τον Mετρητή...", Toast.LENGTH_LONG).show()
if (!arduinoSocket!!.isConnected) {
startbutton.isEnabled = false
stopbutton.isEnabled = false
Toast.makeText(this, "Σύνδεση απέτυχε.", Toast.LENGTH_SHORT).show()
}
else {
val t = Thread(Runnable {
while(t_control == 1) {
if (arduinoSocket.inputStream.read() == 72) {
counter -= 1
runOnUiThread {
ant_met.text = counter.toString()
}
}
}
Thread.sleep(50)
})
解决方案
我认为问题出在Arduino方面。OutputStream
我相信在 Arduino 方面也有一个类型设置。根据我的经验,在 Arduino 中编码时,我必须保留一个用作OutputStream
. 建立连接时,Arduino 端的缓冲区充满了一些存储在缓冲区中的脉冲。建立连接后,Arduino 端缓冲区会立即发送存储在缓冲区中的所有元素,因此您将在毫秒内获得前 3-6 个信号。
在任一侧使用一些解决方法可以很容易地避免这种情况。建立连接后,Arduino 可能已经清除存储在缓冲区中的数据。
如果您不想更改 Arduino 端代码,请在 Android 端执行类似的操作。只需从初始读取所有元素,然后在清除 Arduino 中的初始缓冲区InputStream
时启动您的原始元素。Thread
// Clear the initial buffer
val t_init_control = 1
val t = Thread(Runnable {
while(t_init_control == 1) {
arduinoSocket.inputStream.read()
}
})
Timer().schedule(object : TimerTask() {
override fun run() {
// Stop the init thread
t_init_control = 0
startNewThreadHere()
}
}, 2000)
// This is the original thread where you want to keep the track of the pulse from Arduino
fun startNewThreadHere() {
val t = Thread(Runnable {
while(t_control == 1) {
if (arduinoSocket.inputStream.read() == 72) {
counter -= 1
runOnUiThread {
ant_met.text = counter.toString()
}
}
}
})
}
这只是解释这个想法的伪代码。希望有帮助!
更新
这是后来解决问题的方法。我引用了这个答案的评论部分。
我
Boolean
向 Arduino 发送了一个,以确定何时开始发送数据包。这样,ArduinoInputStream
在 Android 中打开后立即开始发送数据。因此,没有“未传输”字节的泛滥。
推荐阅读
- python - 如何在最后以数字打印范围内的星星?
- kotlin - 如果已经通过构造函数初始化,委托类可以忽略 get/set 中传递的“this”对象吗
- maven - 需要在 Visual Studio 中构建 c++ 项目的 pom.xml 格式
- java - 我想在我的android底部导航栏中垂直居中文本
- javascript - 类/功能组件,内部方法
- c - 如何在C语言中找到约瑟夫斯问题中的消除顺序?
- c++ - 为什么gmock中指向SetArgPointee的void *指针会导致错误
- oracle - 合并 2 个查询并在列中返回一个结果
- python - 如何有效地更新熊猫数据框中的列名?
- amazon-web-services - 从 Visual Studio 2019 上传 AWS Lambda 函数失败