Вводим с компа единицу, получаем на мониторе порта 1-38

Тема в разделе "Arduino & Shields", создана пользователем ЕвгеничЪ, 28 окт 2013.

  1. Доброго дня!
    Начал изучать Ардуино. Пытаюсь пробовать пока по готовым примерам в сети. Нашел несколько примеров как можно управлять с компьютера включением и выключением диода на 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, то все эти значения выводятся строкой.

    В инете нигде не нашел рассмотрения сего явления, похоже, что у большинства все работает с первого раза нормально.
    Может кто нибудь может подсказать в чем проблема?

    Спасибо!
     
  2. NR55RU

    NR55RU Гик

    Воспользуйтесь уроками Джереми Блюма, там в одном из первых уроков как раз будет ваша проблема и он объяснит в чем причина. Там много уроков, ссылку дал на первый.
    Я бы мог объяснить, но это лучше доверить Джереми :)
     
  3. Megakoteyka

    Megakoteyka Оракул Модератор

    Разберитесь, в чем отличие строки от числа. Также см. ASCII.
     
  4. Именно его уроком я и руководствовался. И именно следуя за его шагами я получаю в конце ответа десятку. У него такого эффекта не наблюдается. При использовании -'0', как я уже писал, я получаю в ответе сначала адекватное число, а следом -38.

    Сейчас заменил

    Код (Text):
    while (Serial.available() == 0);
    на

    Код (Text):
    if (Serial.available() > 0)
    вроде бы все заработало, но все же интересно почему до этого у меня не получалось, хотя я вроде старался повторить примеры из видео Блюма.
     
  5. NR55RU

    NR55RU Гик

    Ладно, если коротко.
    Монитор порта передает на ардуин единицу ни как число ОДИН а единицу КАК СИМВОЛ в кодировке ASCII а код единицы там равен ЧИСЛУ 49.
    [​IMG]
    В итоге на Ардуине вы принимаете именно число 49 а не 1.
    Ваша странная десятка это код новой строки. Функция println() как раз в конце и добавляет этот код.
    Вот вам направление, а дальше Мегакотейка дал вам дельный совет.
     
    Последнее редактирование: 28 окт 2013
    Unixon нравится это.
  6. NR55RU

    NR55RU Гик

    Просто что бы направить мысли в нужную сторону, я задам вам вопрос на который не надо отвечать а просто для себя подумать.
    Представьте мы с вами живем в соседних домах и каким то мифическим образом мы с вами можем лишь обмениваться числами пускай от 0 до 255 ..(хотя компьютерам известны тока 0 и 1 но да ладно).
    Не можем говорить голосом и никак а только посылать друг другу числа, как мы тогда смогли общаться ? :)
     
  7. pemalhim

    pemalhim Нуб

    Сам столкнулся с подобным, потребовалось управлять удаленно ардуиной.
    Дело в том, что посылается не единица, символ "1", "2" и т.д. Ардуино считывает код этого символа и посылает его обратно.
    Можно посылать обратный код в другом формате, например:
    Код (Text):
    Serial.println(incomingByte, BIN);
    но при этом принятые данные не изменяться.
    Можно управлять диодом по принимаемому коду:
    Код (Text):
    if (Serial.Read() == 49) {
      digitalWrite(13,HIGH);
    }
    ln - это символ перевода строки, скорее всего он отображается в конце принимаемого пакета.
    И у меня возник вопрос, как можно преобразовать код в символ в Ардуине? (кроме как забивать туда таблицу ASCII)
     
  8. NR55RU, да да, спасибо! это я уловил... т.е. я понимаю, то что я отправляю символ 1, а ардуино его понимает как 49.

    но без ln я все равно получаю в ответе десятки, т.е. 491050105110
     
  9. pemalhim можно и по 49 управлять, но пока волнует вопрос появления десяток :)
     
  10. NR55RU

    NR55RU Гик

    Смотрите что вы делаете, вы возвращаете ВСЕ что принимаете, так.
    А вот вопрос, монитор порта передает вам только код введенного символа или еще и код новой строки ?
    Если он передает и символ и код новой строки, вы примите оба символа и благополучно кидаете их в ответ.
    Соответственно если мне память не изменяет то в Ardouni IDE в мониторе порта есть опция такая как передавать данные в порт с окончанием строки или без и у вас возможно стоит вариант "Новая строка (NL)" ?
     
  11. NR55RU

    NR55RU Гик

    Любой символ хранится как число, в итоге вы можете любое число проверить на соответствие символу:
    Код (Text):
    if(val == 'A')
    Компилятор преобразует символ в его числовой эквивалент и сравнение уже будет идти на уровне чисел.
    Помните что так сравнивать можно только ОДИН символ а не строки :)
     
  12. Unixon

    Unixon Оракул Модератор

    Еще вернее будет заметить, что оно из этого числового эквивалента никогда и не вылазит. Разве что используется для выбора соответствующего глифа в шрифте.
     
  13. Все было именно так! Я только что нашел этот нюанс и побежал сюда делится радостью, но Вы уже тут успели это пояснить.

    Всем спасибо! "Проблема" решена, пошел дальше учиться :)
     
  14. NR55RU

    NR55RU Гик

    Так же обязательно ознакомитесь с документацией по тому же Serial
    Это поможет понять некоторые вещи, например то что Serial.print() передает любые данные как символы, то есть вы на Ардуине получили целочисленное значения 50 к примеру и возвращаете его обратно, важно помнить что данная функция обратно вернет это ни как число 50 а как два символа 5 и 0.
    Именно в этом хитрость того как монитор порта отличает выводимую 10 от символа требующего начать новую строку.
    В общем чтение документации часто бывает полезным :)
     
  15. Хорошо, почитаю :) Спасибо!

    Только на русском поищу :)
     
  16. lerik2703

    lerik2703 Гик