Доброго дня! Начал изучать Ардуино. Пытаюсь пробовать пока по готовым примерам в сети. Нашел несколько примеров как можно управлять с компьютера включением и выключением диода на 13 контакте. Т.е. что бы при вводе в мониторе порта единицы диод включался, а при вводе нуля он выключался. Решил для начала просто посмотреть, что будет выводить ардуино после ввода. Код такой: Код (Text): int val=0; void setup() { Serial.begin(9600); } void loop () { while (Serial.available() == 0); val = Serial.read(); Serial.println (val); } Заливаем код и открываем монитор порта. При вводе единицы в ответ я получаю: 49 10 при вводе двойки: 50 10 при вводе тройки: 51 10 при вводе 123: 49 50 51 10 Никак не могу разгадать что за 10 присутствует в каждом ответе. Если использовать строку Код (Text): val = Serial.read();-'0' вместо Код (Text): val = Serial.read(); то получаем еще более интересные ответы: для единицы 1 -38 для двойки 2-38 для тройки 3-38 Если не использовать окончание ln при выводе serial.print, то все эти значения выводятся строкой. В инете нигде не нашел рассмотрения сего явления, похоже, что у большинства все работает с первого раза нормально. Может кто нибудь может подсказать в чем проблема? Спасибо!
Воспользуйтесь уроками Джереми Блюма, там в одном из первых уроков как раз будет ваша проблема и он объяснит в чем причина. Там много уроков, ссылку дал на первый. Я бы мог объяснить, но это лучше доверить Джереми
Именно его уроком я и руководствовался. И именно следуя за его шагами я получаю в конце ответа десятку. У него такого эффекта не наблюдается. При использовании -'0', как я уже писал, я получаю в ответе сначала адекватное число, а следом -38. Сейчас заменил Код (Text): while (Serial.available() == 0); на Код (Text): if (Serial.available() > 0) вроде бы все заработало, но все же интересно почему до этого у меня не получалось, хотя я вроде старался повторить примеры из видео Блюма.
Ладно, если коротко. Монитор порта передает на ардуин единицу ни как число ОДИН а единицу КАК СИМВОЛ в кодировке ASCII а код единицы там равен ЧИСЛУ 49. В итоге на Ардуине вы принимаете именно число 49 а не 1. Ваша странная десятка это код новой строки. Функция println() как раз в конце и добавляет этот код. Вот вам направление, а дальше Мегакотейка дал вам дельный совет.
Просто что бы направить мысли в нужную сторону, я задам вам вопрос на который не надо отвечать а просто для себя подумать. Представьте мы с вами живем в соседних домах и каким то мифическим образом мы с вами можем лишь обмениваться числами пускай от 0 до 255 ..(хотя компьютерам известны тока 0 и 1 но да ладно). Не можем говорить голосом и никак а только посылать друг другу числа, как мы тогда смогли общаться ?
Сам столкнулся с подобным, потребовалось управлять удаленно ардуиной. Дело в том, что посылается не единица, символ "1", "2" и т.д. Ардуино считывает код этого символа и посылает его обратно. Можно посылать обратный код в другом формате, например: Код (Text): Serial.println(incomingByte, BIN); но при этом принятые данные не изменяться. Можно управлять диодом по принимаемому коду: Код (Text): if (Serial.Read() == 49) { digitalWrite(13,HIGH); } ln - это символ перевода строки, скорее всего он отображается в конце принимаемого пакета. И у меня возник вопрос, как можно преобразовать код в символ в Ардуине? (кроме как забивать туда таблицу ASCII)
NR55RU, да да, спасибо! это я уловил... т.е. я понимаю, то что я отправляю символ 1, а ардуино его понимает как 49. но без ln я все равно получаю в ответе десятки, т.е. 491050105110
Смотрите что вы делаете, вы возвращаете ВСЕ что принимаете, так. А вот вопрос, монитор порта передает вам только код введенного символа или еще и код новой строки ? Если он передает и символ и код новой строки, вы примите оба символа и благополучно кидаете их в ответ. Соответственно если мне память не изменяет то в Ardouni IDE в мониторе порта есть опция такая как передавать данные в порт с окончанием строки или без и у вас возможно стоит вариант "Новая строка (NL)" ?
Любой символ хранится как число, в итоге вы можете любое число проверить на соответствие символу: Код (Text): if(val == 'A') Компилятор преобразует символ в его числовой эквивалент и сравнение уже будет идти на уровне чисел. Помните что так сравнивать можно только ОДИН символ а не строки
Еще вернее будет заметить, что оно из этого числового эквивалента никогда и не вылазит. Разве что используется для выбора соответствующего глифа в шрифте.
Все было именно так! Я только что нашел этот нюанс и побежал сюда делится радостью, но Вы уже тут успели это пояснить. Всем спасибо! "Проблема" решена, пошел дальше учиться
Так же обязательно ознакомитесь с документацией по тому же Serial Это поможет понять некоторые вещи, например то что Serial.print() передает любые данные как символы, то есть вы на Ардуине получили целочисленное значения 50 к примеру и возвращаете его обратно, важно помнить что данная функция обратно вернет это ни как число 50 а как два символа 5 и 0. Именно в этом хитрость того как монитор порта отличает выводимую 10 от символа требующего начать новую строку. В общем чтение документации часто бывает полезным