Последовательный порт и преобразование данных.
- Войдите на сайт для отправки комментариев
Здравствуйте.
Помогите пожалуйста решить такую задачку:
Через последовательный порт вводится число от 1 до 9, нужно мигнуть светодиодом на 13 пине соответствующее количество раз, от 1 до 9.
Вроде бы элементарщина, но никак не могу разобраться с типами данных. Как можно полученный через последовательный порт символ использовать далее в программе в качестве переменной типа int?
набросал вот такой скетч:
int x=0;
void setup()
{
Serial.begin(9600);
pinMode(13, OUTPUT);
}
void loop()
{
if (Serial.available() > 0)
{
x = Serial.read();
//Serial.println(x); - если выводить обратно полученный символ - видно что это его десятичный ASCII код
//Serial.println(x, BYTE); - если вывести в виде байта - вроде бы то, что нам нужно...
//x=byte(x);
}
if (x>9) x=9;
if (x<1) x=1;
for (int i = 0; i<=(x-1); i++)
{
digitalWrite(13, HIGH);
delay(200);
digitalWrite(13,LOW);
delay(200);
}
delay(1000);
}
в общем пробовал далее использовать конструкции типа x=byte(x) или x=int(byte(x)) - все равно в переменной остается десятичный код или что-то такое - светодиод при попытке ввода в любом случае будет мигать 9 раз, значит в переменной x находится что то явно больше 9;
Что же нужно сделать, чтобы введенная через порт цифра попала в переменную именно в том виде в котором это позволило бы выполнить условие задачи?
Во первых как поступают данные на ардуино? Тоесть передаётся например цифра 9 один раз или постоянно, перерывы?
Дальше я в коде заметил только если х меньше 1 то х=1, если х больше 9 то равно х=9
А где же тогда проверка сколько раз моргаь? Получается только 9 или 1 раз может моргать.
Нужно вводить задержки или в считывании или в передаче данных в ардуино.
Почему бы не поставить в цикле i=0, i==x,i++
Во первых как поступают данные на ардуино? Тоесть передаётся например цифра 9 один раз или постоянно, перерывы?
На этот счет в условии ничего не сказано, следовательно цифры от 1 до 9 вводятся n раз с произвольными промежутками времени между попытками ввода.
Дальше я в коде заметил только если х меньше 1 то х=1, если х больше 9 то равно х=9
А где же тогда проверка сколько раз моргаь? Получается только 9 или 1 раз может моргать.
если 1<x<9 то в переменной x сохранится ее значение. Следовательно x может принимать любые значения от 1 до 9.
Нужно вводить задержки или в считывании или в передаче данных в ардуино.
Не могли бы вы пояснить что вы имеете ввиду и каким образом это относится к моей проблеме?
Почему бы не поставить в цикле i=0, i==x,i++
в моем скетче цикл "мигания" выглядит как for (int i = 0; i<=(x-1); i++){...} это означает, что он выполнится x раз. Ну, если бы мне удалось успешно записать в x какую либо цифру из порта. Если перед циклом произвести присваивание переменной x некоего значения вручную и сделать перезаливку скетча - все работает как надо.
Ваш пример цикла неработоспособен, поскольку результат операции сравниения i==x вернет истину только в случае если x==0. В этом случае цикл выполнится 1 раз. В случае если ((x>0) || (x<0)) цикл вообще не выполнится ни разу.
Про задержки которые delay().
Например если перевести данные с ком порта в обычный цифровой вид и ограничить диапазон переменной Х от 0 до 255
Далее внести это значение в analogWrite(LED,X) То Светодиод подсоединённый к порту LED будет гореть постоянно, ввиду того что данные поступают очень быстро, и просто вместо разных значений яркости мы не увидим мерцаний(конечно если данные поступают разные и хаотично). Но если после каждого считывания ставить паузу хотябы 30 мс то уже будут заметны изменения данных на светодиоде.
Может конечно я в конец недели торможу, но вот эта проверка не подходит
if (x>9) x=9;
if (x<1) x=1;
Должно быть так
if (x>0) {
if(x<=9){
делаем что-то
}
}
Получается что если х больше 0 и если меньше либо равно 9 то делаем что-то
а вообще можно и так попробовать if(1<x<9) - IDE не ругается
На крайний случай кстате можно выводить среднее число за определенный промежуток времени, и дальше уже играться
Про задержки которые delay().Например если перевести данные с ком порта в обычный цифровой вид и ограничить диапазон переменной Х от 0 до 255
Далее внести это значение в analogWrite(LED,X) То Светодиод подсоединённый к порту LED будет гореть постоянно, ввиду того что данные поступают очень быстро, и просто вместо разных значений яркости мы не увидим мерцаний(конечно если данные поступают разные и хаотично). Но если после каждого считывания ставить паузу хотябы 30 мс то уже будут заметны изменения данных на светодиоде.
Задача то в том, чтобы мигнуть несколько раз, а не в том, чтобы менять яркость свечения. Хотя если бы вы привели фрагмент кода, в котором данные из порта попадают в переменную, которая устанавливает яркость свечения - это тоже было бы решением проблемы, с которой я столкнулся.
Кстати я еще даже еще незадумывался на вопросом, как считывать двух и трехзначные числа из порта в переменную... Декларировать строку длинной не менее буффера последовательного порта и посимвольно записывать туда считываемые символы? А затем преобразовывать строку в число? Надо будет попробовать.
Может конечно я в конец недели торможу, но вот эта проверка не подходит
if (x>9) x=9;
if (x<1) x=1;
Ну и почему же она не подходит? особенно если учесть, что результатом работы программы должна быть серия "мигов" - от 1 до 9?
Если уж вас так смущает эта часть, можно ее вообще выкинуть, это никак не повлияет на результат, за исключением того момента, что в переменной может находится значение, не обладающее свойством достоверности для данной задачи. Иначе говоря, вместо серии "мигов" от 1 до 9, может вообще не быть "мигов" - если в переменной оказалось нулевое или отрицательное значение или же серия "мигов" будет очень длинной - несколько сотен раз. Это непринципиально, поскольку в условии про контроль вводимых данных или отсеивание заведомо неправильных значений ничего сказано не было. Поставил проверку чисто машинально наверное.
Должно быть так
if (x>0) {
if(x<=9){
делаем что-то
}
}
Получается что если х больше 0 и если меньше либо равно 9 то делаем что-то
а вообще можно и так попробовать if(1<x<9) - IDE не ругается
Если вас заинтриговала задача, может быть попробуете ее решить самостоятельно, благо даже переписать ее с нуля займет 5 минут времени и выложите сюда свой метод решения или скетч? Я бы с радостью на него посмотрел, потому что сам уже вроде бы перебрал все возможные варианты решения, но успеха так и не достиг.
На крайний случай кстате можно выводить среднее число за определенный промежуток времени, и дальше уже играться
Вводятся циферки все вручную. То есть мы же не работает с потоком цифр, которые выдает скажем какая то программа или датчик, нет необходимости ничего усреднять.
С удовольствием (люблю решать задачи), но плату ардуины забыл на работе. Могу лишь набить код но проверить не смогу(
Для начала вот откройте в Arduino IDE - Examples - Comunication - Dimmer
Там простое присвоение про которое я говорил. НО ТАМ РАСЧИТАНО НА ПОДАЧУ СИГНАЛА ОТНОСИТЕЛЬНО ПОСТОЯННОГО, тоесть если он опять же сильно будет изменяться то на глаз просто будет не разглядеть изменений. Тоесть например посылаем триста раз например значение 100, и светодиод будет на половину яркости светится и это будет видно
Еще приведу пример. Из своего опыта:
Подаю выпрямленный и усиленный сигнал музыкального характера, изменения там бешенного темпа. Дальше я решил выводить моментальные значения эти на экранчик свой, и что вместо букв вижу черные фигурки. Тоесть цифры меняются на столько быстро что дисплей не успевает их отображать. Поставил delay(35) И о боги, видно все как скачет, но появился негативный момент пропуска значений, но для меня это совсем не критично))
Так и со светодиодом и резкими изменениями.
Если упростить задачу?
Например в течении 4х секунд подавать одно число (например 7), то ардуино считав его проморгает за 3 секунды семь раз и сделает перерыв еще на секунду, тоесть можно легко посчитать, количество морганий
Еще вариант 9 светодиодов, получится что то типа светодиодной линейки, и не надо мигать. Будет как уровень в магнитофонах) Но опять же надо ставить задержки8)
Меня уже совсем далеко унесло, верните меня;) Пошел прогуляться, я понял, у вас и так большие задержки под конец вашего кода, тоесть ардуино считывает значения с ком порта раз в 2 секунды грубо говоря
Рассмотрим следующий пример:
Вопрос то как раз в том - почему не работает преобразование типа в этом случае? в обучалке, да и на arduino.cc ни про какие ограничения не написано... А ведь вроде везде пишут, что "Язык программирования устройств Ардуино основан на C/C++"...
Может быть я что-то не так понимаю?
тут где-то рядом ответ
Извините! пока умнее не придумал((((
int x=0; int p=0; void setup() { Serial.begin(9600); pinMode(13, OUTPUT); } void loop() { if (Serial.available() > 0) { x = Serial.read(); if (x=='1') p=1; if (x=='2') p=2; if (x=='3') p=3; if (x=='4') p=4; if (x=='5') p=5; if (x=='6') p=6; if (x=='7') p=7; if (x=='8') p=8; if (x=='9') p=9; } for (int i = 1; i<=p; i++) { digitalWrite(13, HIGH); delay(100); digitalWrite(13,LOW); delay(100); } p=0; } !!!!!!!!!!!!!!!!!!!!!! ОООО уменьшил !!!!!!!!!!!!!!!!!! int p=0; void setup() { Serial.begin(9600); pinMode(13, OUTPUT); } void loop() { if (Serial.available() > 0) { p = Serial.read()-48; } for (int i = 1; i<=p; i++) { digitalWrite(13, HIGH); delay(100); digitalWrite(13,LOW); delay(100); } p=0; }!!!!!!!!!!!!!!!!!!!!!! ОООО уменьшил !!!!!!!!!!!!!!!!!! { p = Serial.read()-48; }
Спасибо, как раз то что нужно!
Всё основано на Таблица кодировки символов ASCII. По usb передается номер символа.
Таблица
В первом варианте как раз проверяется на символы.
Всё основано на Таблица кодировки символов ASCII. По usb передается номер символа.
Таблица
В первом варианте как раз проверяется на символы.
Ну это все понятно, просто я почему то подумал, что для этого дела уже должна существовать готовая функция или что это можно сделать просто преобразовав тип =)
Каюсь, затупил.
Я сам не гуру в программировании. Просто сам так делал. Возможно существуют и другие средства и методы для нормального преобразования типов.
Всем привет! Вопрос к спецам, мастерю ситему которая присматривает за домом: отопление, датчик газа, вентиляция и т.д. Прога вращается на штатном компьютере общаясь по USB с переферией через ATMEGу. Нужен надежный протокол общения, если можно то покажите примеры.
Всем привет! Вопрос к спецам, мастерю ситему которая присматривает за домом: отопление, датчик газа, вентиляция и т.д. Прога вращается на штатном компьютере общаясь по USB с переферией через ATMEGу. Нужен надежный протокол общения, если можно то покажите примеры.
Если через USB, то практически безальтернативно - эмуляция COM-порта. Стандартный объект Serial.
Подскажите, пожалуйста, можно ли как-то отбрасывать "паразитные" данные. Посылаю через com порт символ, обратно возвращается его код, однако ардуино отрабатывает 3 раза (подключил 4 сдвиговых регистра и наблюдаю за перемещением сигнала по лампочкам). Опытным путем вычислил, что передаются символы с кодом: 80 и 176. Есть ли какие-то ограничения на прием данных?
Рассмотрим следующий пример:
Вопрос то как раз в том - почему не работает преобразование типа в этом случае? в обучалке, да и на arduino.cc ни про какие ограничения не написано... А ведь вроде везде пишут, что "Язык программирования устройств Ардуино основан на C/C++"...
Может быть я что-то не так понимаю?
int('1') - вовсе не преобразование сивола 1 в число 1. Это преобразвание типа байт в тип int безо всекого изменения содержимого. Результатом будет целое число равное коду символьной единицы.