Потеря данных полученных в Android от Arduino по Bluetooth (appinvertor)

alexnf
Offline
Зарегистрирован: 13.03.2015

Отправляю сигналы с ардуино, с разных датчиков, в виде "имя датчика + уровень"

Пробовал вот так:

Serial1.print("pp"); //pp, pl, pc, ppc, plc - имена датчиков
Serial1.println(pplevel); //pplevel-уровень сигнала датчика от 1 до 5

При соединении терминалом получаю последовательность данных

pp1
pp2 и тд

Менял буквы на цифры:

Serial1.print(0); //00, 01, 02 - имена датчиков Serial1.print(0); Serial1.println(pplevel); //pplevel-уровень сигнала датчика от 1 до 5

При соединении терминалом получаю последовательность данных

001
002 и тд

Но при получении данных в приложение, происходит их частичная потеря:
pp
p1
01
02 и тп, в общем некоторых символов не хватает, обычно первых

Вот программа:

alexnf
Offline
Зарегистрирован: 13.03.2015

Может кто подскажет хотя бы, где почитать?

Из всех примеров, что нашел, обычно принимают или один символ (напр состояние кнопки) или по запросу, какой либо параметр. 

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

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

Как вы получаете данные в приложении? Подозреваю, что проблема там.

alexnf
Offline
Зарегистрирован: 13.03.2015

Вроде выкладывал в первом посте!?

Вместо ReceiveTextnumberOfByte - перепробовал все Call что есть - результат тот же.

Либо не верно использую. Я видимо не совсем понимаю работу данной функции, пробовал в Label сразу выводить BytesAvailableToReceive, думал что она покажет количество полученных байт, а она показываю их количество с нарастающим итогом. Те вместо 3 3 3 3, показывает 3 6 9 12 15 - и так до 1200-1500, потом отстанавливается!

Может после каждого получения нужно что-то сбрасывать?

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

Вы проверяете порт по таймеру, а не по событию.

Посмотрите у Осипова. Я повторял его уроки - все работает корректно.

alexnf
Offline
Зарегистрирован: 13.03.2015

Да смотрел вроде, тоже так было... наверное...

А по событию, это как?

Таймер, на сколько я понимаю, это чтобы создать цикл, а потом же идет проверка по событию BytesAvailableToReceive

Или это не то?

Дополнено:

Нашел различия с Осиповым, у него стоит TimerInterval 1000, а у меня 0 - выставляю 100, и все работает при условии что данные поступают с интервалом 1000.

А как мне настроить TimerInterval, Если данные будут поступать не постоянно и с большой периодичностью?

Или как то нужно настроить опознование начала и конца сообщения что бы их разделять?

После передачи каждого отдельного сообщения, передается Serial.println() - можно это как то опознать, как окончание принятого сообщения?

Найти нужно символ /n на сколько я понимаю,
а как его правильно отловить в appinvertore ?

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

Извините - я вам не помощник, не моя тема.

Fessar
Offline
Зарегистрирован: 29.07.2015

Посмотри мой пример https://yadi.sk/d/G-XpeVEXkmpiA

Там ардуина по моему раз в 300 мс посылает последовательность байтов с разделителями вида x0x байты x1x байты ......... x6x. Программа андроида вычленяет всё, что находится между нужными разделителями и вставляет в нужную строку на экране. Количество полезных байтов у меня может быть разным, по этому и использовал разделители, а не разбивал посылку по фиксированным позициям байтов. Со чтением ошибок всё примерно так же, только там байты печатаются в одну строку с пробелами, пробел выставляется тогда, когда в посылке встречается символ w. Делал это летом, так что уже не всё помню.

alexnf
Offline
Зарегистрирован: 13.03.2015

Да, это уже похоже на то что нужно. А не могли бы Вы описать, что делает програма:

Я начну:

Если блютуз клиент подключен:

то

"надпись 1" присваеваем значение переменной с принятым текстом, начиная с первого символа и длиной до последнего символа перед "x0x"

"надпись 3" присваеваем значение переменной с принятым текстом, начиная с текста после "x0x" (через 3 буквы после начала "x0x") и длиной начиная с текста после "x0x" и до текста "x1x"

и тд

Поправьте, если я ошибаюсь.

Если я буду отслеживать сообщения от Serial1.println(,) и до Serial1.println(,) , то мне вместо "х0х" и "х1х" поставить "/n" ?

(по запятым не могу, тк они есть в тексте самого сообщения)

Fessar
Offline
Зарегистрирован: 29.07.2015

Описано верно, насчёт \n, что-то мне сейчас вспоминается, что я так пробовал делать и ничего у меня не вышло. Кажется, программа воспринимала \n не как текст, а именно как символ переноса строки и использовать его в качестве какой-то метки не выйдет. Но может и ошибаюсь, это надо проверять.

alexnf
Offline
Зарегистрирован: 13.03.2015

Вот как то так сделал, но смущает последняя строка расчета длины сообщения, проверить пока не могу. Да и насчет начала не уверен, наверно определение начала строки с \n заменить на 1 нужно:

Fessar
Offline
Зарегистрирован: 29.07.2015

А какая строка должна приходить из ардуины? Из первого сообщения не особо понял.

alexnf
Offline
Зарегистрирован: 13.03.2015

В первом я просто брал тестовые значения, а вообще выглядит вот так:

unsigned long heady;
byte message[8];
........
Serial.print(heady, DEC); //heady - значение из 9 символов
for (int i = 0; i < 8; i++) {
 Serial.print(",");
Serial.print(message[i]);
 }
Serial.println(",");

В терминал получаю типо такого:

12345678,0,34,0,1,44,2,4,5,

87654321,0,33,0,3,0,23,4,5,

45678912,0,1,0,1,0,2,44,5,

Это и есть отдельные сообщения, которые нужно получить. (это сообщения из CAN шины авто)

alexnf
Offline
Зарегистрирован: 13.03.2015

Вроде бы что-то получилось:

Создал из переменной буфер, в который собираю все входящие данные,
а потом от туда их разбираю деля по переходу строки (по количеству символов не мог, тк это количество может быть разным)
Те данные, которые уже вывел, затираю.
TimerInterval стоит на "0".
Потерь нет, или пока не заметил, проверял только на эмуляторе входящих данных, к источнику пока подключится не могу.
Из недостатков, данные в буфер пишу в конец, а читаю с начала, если андроид не успеет перебирать все получаемые сообщения, то они начнут накапливаться в буфере и становиться для моей программы - не актуальными, поэтому если в буфере более 150 символов (это примерно 2 сообщения), то я его обнуляю.
Буду рад, если укажите на ошибки, или может можно как то упростить?

Fessar
Offline
Зарегистрирован: 29.07.2015

Чтобы данные не накапливались, нужно делать обмен типа запрос-ответ. У меня так сделано: раз в 500мс из андроида отправляется запрос на получение данных, ардуина отправляет данные и ждёт следующего запроса. То есть система master-slave.

alexnf
Offline
Зарегистрирован: 13.03.2015

Это данные кан шины авто, в том числе сигналы датчиков парктроника. поступают не постоянно, фильтруются в ардуино, поэтому 500мс не вариант. К тому же с данными поступающими из ардуино, работает так же другая, не моя, программа - поэтому изменить их не могу.

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