Serial через терминал работает, а через bluetooth нет...
- Войдите на сайт для отправки комментариев
Сб, 02/06/2012 - 10:04
День добрый!
Пробую связать arduino uno с компом, и такой странный глюк.
Вот тестовый скетч:
void setup(void) { Serial.begin(9600); } int inSize=0; // Переменная которая будет содержать размер буфера char str[128]; // Так как типа string тут нет, будем использовать массив символов void loop(void) { inSize=0; // Сбрасываем переменную memset(str, '\0', 128); // Очищаем массив if (Serial.available() > 0) { delay(200); // Ждем, для того, чтобы пришли все данные inSize = Serial.available(); // Получаем длину строки и записываем ее в переменую for (int i = 0; i < inSize; i++) { str[i] = Serial.read(); // Читаем каждый символ, и пишем его в массив } // Сравнять массив с строкой будем используя функцию strcmp if (strcmp(str, "gett1") == 0) { Serial.println("command gett1 ok"); } else if (strcmp(str, "gett2") == 0) { Serial.println("command gett2 ok"); } else if (strcmp(str, "geth1") == 0) { Serial.println("command geth1 ok"); } else { Serial.print("Error command! "); for (int i = 0; i < inSize; i++) { Serial.print(str[i]); } Serial.println(); } } }
Например, посылая команду "gett1" через терминал, я получаю нормальный ответ "command gett1 ok", но отсылая её-же через блютус, получаю ответ "Error command! gett1", то-есть я вижу в конце переданную команду, значит она нормально принялась, но почему-то не распознана.
В чем тут может быть дело?
Блютус модуль обычный, на BC417, работает нормально, простые команды типа цифр передаются и распознаются нормально - а со строковыми такой косяк непонятный...
Возможно в delay(200);
Может не успевает прийти вся строка целиком. А может наоборот - успевает о блюпупа не хватает размера приемного буффера что-бы вместить всю строку целиком.
Попробуйте выкинуть delay, и, вместо него перед строкой 19 (внутри цикла, перед вычитыванием) добавить
Даже если это "Не поможет", IMHO в любом случае так надежней будет чем "магические задержки".
И еще, убедитесь, что когда вы отсылаете строку с компа, вы случайно не добавляете к ней что-то типа \r, \n и т.п.
И еще, там где вы делаете вывод ошибки. Выведите не каждый принятый символ, а его код в виде HEX. Я там же выведите покодово ту строку с которой стравниваете (предварительно положите ее в переменную, сравнение тоже делаейте с переменной).
В таком случае в "найди разницу" - будет легче играть. Например буква c. Русская и латинская. Выглядит одинаково, на клаве в одном месте (запросто перепутать), а пока кодами не выведешь - фиг догадаешься почему одинаковые "на глаз" строки не хотят нормально совпадать ;)
leshak, спасибо! Действительно, с hex выводом стало видно, что через блютус добавлялись символы 0xD 0xA - по умолчанию в Termite, через который я с блютусом работал, было включено "Append CR+LF" - убрал - теперь нормально работает)
А вы попроубйте сей "недуг" в "подвиг" определить :)
Вы в терминалах длинну строки (inSize) руками вводите? Если да, то можно от этого отказатся. Включить добавление CR и определять конец строки по нему (читать в str[i], пока принятый байт не будет равен \r)
Нет, почему же руками?
Длину строки получаю так - 16-я строка:
а с добавлением в конец \r надо подумать, как лучше сделать - вообще мне надо получать и отправлять данные с датчиков температуры и влажности, в виде: "команда (set/get)", имя датчика (t1... t5, h1...h3) и значение в диапазоне (-10...+100).
Получается что длина "команда+имя" всегда одинакова, а всё что далее будет значением датчика - получается \r и не нужно.
Нет, почему же руками?
Длину строки получаю так - 16-я строка:
Как вы ее получаете - это и по коду видно :), вопрос был в том "как вы ее послаете". Если руками - то можно перейти на "маркер конца строки".
а с добавлением в конец \r надо подумать, как лучше сделать - вообще мне надо получать и отправлять данные с датчиков температуры и влажности, в виде: "команда (set/get)", имя датчика (t1... t5, h1...h3) и значение в диапазоне (-10...+100).
Получается что длина "команда+имя" всегда одинакова, а всё что далее будет значением датчика - получается \r и не нужно.
Да. Если длинна команды всегда одна и та же - это упрощает. Можно ее просто зашить в код.
Я бы еще добавил какой-то маркер перед командой. Например звездочку (или три). Что-бы ардуина четко могла знать когда "команда начала передаватся". Могут же быть помехи, часть байтов - может потерятся.....
Поэтому, в идеале, должно быть
На часть пунктов, конечно можно забить, в зависимости от того "как ведет себя канал".
Нет, почему же руками?
Длину строки получаю так - 16-я строка:
Так вы получаете количество символов, находящихся в приемном буфере на момент исполнения этой команды. А если пришли еще не все пересылаемые символы? А если произошла помеха и один из сиволов не был принят правильно и, соответственно, не загрузился вбуфер? А если ... еще с десяток причин?
Нет, почему же руками?
Длину строки получаю так - 16-я строка:
Так вы получаете количество символов, находящихся в приемном буфере на момент исполнения этой команды.
А и вправду. Проглядел. Что-то подумал, что первым байтом, со стороны компа, посылается длина строки. Поэтому и спрошал "руками посылаете или нет". А так - да, конечно. Будет работать правильно при удачном положении звезд.