Счетчик, работающий в потоке, управляемый сигналами Arduino, пропускает первые несколько чисел - PullRequest
1 голос
/ 12 июня 2019

Я установил соединение Bluetooth между Arduino (модуль Bluetooth HC-05) и моим приложением для Android.

Каждый раз, когда Arduino отправляет сигнал (это всего лишь число 72), мое приложение для Android читает этосигнал (как байты в InputStream) и устанавливает переменную "counter" в counter = counter - 1 .

Я создал поток, который делает это.

Проблема в том, что :

Если, например, установить счетчик на 30 и запустить поток, первые 3-4 вычитания из 30 происходят за миллисекунды (они не синхронизируются с сигналами Arduino).Но начиная с 26 и далее все отлично синхронизируется и работает, как и ожидалось.

Я пробовал другой Thread.sleep() раз.Большее время сна усугубляет проблему (в миллисекундах происходит больше вычитаний).Меньшее время сна лучше, но все равно не решайте мою проблему.

Почему поток не синхронизирован для первых 3-6 вычитаний и синхронизирован для всех остальных?

Некоторые (возможно) полезная информация:

Есть 4 кнопки.«Connect», «Disconnect», «Start» и «Stop».

  1. «Connect»: установите соединение через гнездо Bluetooth с HC-05.
  2. «Disconnect»: Закрывает это соединение.
  3. «Start»: запускает поток, который прослушивает InputStream данные из HC-05.
  4. «Stop»: останавливает этот поток.

Мой код (Код темы).Если кому-то нужна какая-либо другая часть кода, пожалуйста, попросите ее:

//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)
    })

1 Ответ

1 голос
/ 12 июня 2019

Я думаю, что проблема на стороне Arduino. Я считаю, что на стороне Arduino есть настройка типа OutputStream. Исходя из моего опыта, во время кодирования в Arduino мне пришлось сохранить буфер, который работает как OutputStream. Когда соединение устанавливается, буфер на стороне Arduino заполняется некоторыми импульсами, которые сохраняются в буфере. Как только соединение устанавливается, боковой буфер Arduino отправляет сразу все элементы, хранящиеся в буфере, и, следовательно, вы получаете первые 3-6 сигналов в миллисекундах.

Этого легко избежать, используя обходной путь с обеих сторон. Arduino может очистить данные, хранящиеся в буфере, уже после установления соединения.

Если вы не хотите изменять код стороны Arduino, сделайте то же самое на стороне Android. Просто прочитайте все элементы из начального InputStream и через некоторое время запустите исходный Thread, когда начальный буфер в Arduino будет очищен.

// 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, чтобы определить, когда начинать отправка пакетов данных. Таким образом, Arduino начинает отправлять данные сразу после открытия InputStream в Android. Следовательно, нет поток «непереданных» байтов.

...