Управление PWM с ПК
- Войдите на сайт для отправки комментариев
Вс, 21/10/2012 - 10:03
Здравствуйте! Прошу помощи, али совета.
Задумка следующая: отправлять на ардуино величину (0-255), на которую что-то будет включаться. Пока, на стадии тестирования, работаю со светодиодиком и управляющие команды через "монитор порта".
Проблема: при отправке нескольких символов в одном "письме", ардуино воспринимает каждый символ отдельно.
int ledPin = 9; //испытуемый int val = 0; //тут храним команду void setup() { Serial.begin(9600); pinMode(ledPin, OUTPUT); } void loop() { while(Serial.available() == 0); //ждем, пока не поступит сигнал if (Serial.available() > 0 && Serial.available() < 255) { /*Если есть сигнал, он больше нуля и меньше 255, считываем его в переменную и выводим ее обратно для проверки, а так же зажигаем на эту величину светодиод*/ val = Serial.read() - '0'; Serial.println(val); analogWrite(ledPin, val); } //Иначе говорим об ошибке else Serial.println("Error"); }
В итоге светодиод еле-еле что-то выдает, а на максимум не зажечь, т.к. 255 воспринимается как 2, потом 5, потом еще раз 5 (во всяком случае я так понял).
Вопрос: как считывать сообщение как одно целое?
конечно, может не в тему, но вдруг пригодиться. вот мой пример включения определенного реле (код урезан, постарался оставить только нужные вещи для понимания чего я делал). В кратце: код сделан по запросу - если в мониторе - "Z" просим ввести число(таких чисел может быть столько сколько разрядов в числе необходимом для ввода), после ввода числа/чмсел переприсваиваем переменные и в следующей функции переприсваиваем номеру реле входящий символ из монитора порта, включаем реле по его номеру введенному в мониторе в итоге. Ну вот как то так. На применение именно этого алгоритма не настаиваю,но у меня при моих 10 реле все это работает, по аналогии можно сделать ввод чисел (например 12, 155, 1009 и др)
Почитайте вот в эту сторону.
Serial.parseInt()
Спасибо ich. Пока искал примеры указанной функции, нашел решение проблемы :D Может кому пригодится - http://arduino.ru/forum/programmirovanie/perevod-prinyatogo-simvola-s-com-porta-v-chislo
Там в примере задается командная буква и время, которое светодиод должен светить. Я немного модернизировал:
Сыренько еще, конечно, но однако работает. В монитор пишем командную букву "f" (или "r") и число (0-255), задавая яркость светодиода.
Только вот parseInt() медленная, а точнее она ждет прежде чем вернуть значение.
Можно все сложить в String и воспользоваться методом toInt - смотрите стандартный пример StringToInt
Представленный вариант как раз-таки отлично подходит для поставленной мной задачи. Возник попутный вопрос: когда поступившая команда выполнена, как прервать программу и вернуться к циклу ожидания сигнала? return?
Ну и раз уж начал: как я понимаю, цикл с Serial.Available полностью тормозит программу и пока команда из сериал порта не поступит - ничего не произойдет. Т.е., допустим, сигнал с датчика может не поступить вовремя (а если обработку датчиков сделать в конце и первый абзац глаголит истину, то сигнала с датчика я и вовсе не получу никогда). Тут с прерываниями надо что-то делать? (просто уже много прочитал про прерывания на ардуино, но так и не понял что это. Вернее примерно понял, но как это реализовать для конкретной задачи - не ясно)
цикл с Serial.Available полностью тормозит программу только в случае, если Вы примените что-нибудь в стиле parseInt. Если просто будете читать символы в буфер - то ничего не тормозит, потому что выполняется только при наличии необработаных символов в буфере приема. Изучите внимательнее пример. Снаружи цикла с Serial.Available можно делать все что угодно.
Вот это все равно подтормаживает
но эта задержка не просто так сделана, а сделана для того, что бы байты успевали приходть в буфер и цикл выполнялся пока не пришло все сообщение. Еесли известна длинна сообщения, то можно избавиться и от этой задержки
где 10 - длинна сообщения, но тут есть ограничение - размер буфера.
Нет, видимо я не так выразился. Будем опираться на код из сообщения №3. При включении, ардуино начинает выполнять программу. Как я понимаю, программа доходит до 12 строки и "останавливается", пока не будет начата передача команд. Т.о., пока я не введу что-нибудь в порт, дальше ничего не происходит, программа крутится в цикле while. Так?
Далее, допустим, у меня много различных команд, но я не хочу пролистывать весь "loop", после выполнения, скажем, первого условия. Возможно ли принудительно на определенном моменте остановить работу раздела "void loop" и вернуться к его началу (к строчке 10)?
Идем далее. Если условие, поставленное в предыдущем абзаце реализуемо, то при определенном стечении обстоятельств можно самих себя завести в тупик)) Если после всех условий на выполнение команд разместить обработку данных с датчиков, то данные команды в принципе выполняться никогда не будут, т.к. пока команды нет - программа вертится в 12 строчке, а когда команда есть, она выполняется и возвращает процесс в начало в строку 10. Допустим, датчик всего 1 и, если я правильно понял смысл "прерываний в ардуино", я могу в "void setup" задать команду-прерывание, которая автоматически, никак не влияя на ход выполнения основной программы, будет с определенным интервалом опрашивать датчик и быстренько отправлять данные в сериал порт.
Извиняюсь за фантазии, просто хочется знать, правильно ли я понимаю логику работы МК.
2 maksim: это полезная информация, спасибо!
Нет, видимо я не так выразился. Будем опираться на код из сообщения №3. При включении, ардуино начинает выполнять программу. Как я понимаю, программа доходит до 12 строки и "останавливается", пока не будет начата передача команд. Т.о., пока я не введу что-нибудь в порт, дальше ничего не происходит, программа крутится в цикле while. Так?
Нет, не так этот цикл будет выполняться только если в буфере что-нибудь есть, если ничего нет то программа "пройдет мимо" всего тела цикла не заходя в него (с 12 по 52 строки). Если есть 1 байт и в течении 2 миллисекунд ничего в буфер не пришло, то вся программа "остановаится" на 2 миллисекунды, если в буфер пришло 2 байта, то программа "остановится" на 4 миллисекунды и т.д.
По поводу остального почитайте Программирование про прерывания и условные операторы, есть еще такая штука как прерывание по таймеру, можете воспользоваться готовой библиотекой, здесь где-то недавно обсужналось.
Читайте про условные переходы и рисуйте алгоритмы