Помогите найти ошибку в алгоритме
- Войдите на сайт для отправки комментариев
Пт, 09/02/2018 - 14:13
Всем добрый день или вечер. Возникла проблема с написанием скетча для Ардуино. На данный момент я использую Arduino UNO и Bluetooth HC-06. У меня не получается разделить входной поток информации на определенные переменные. Вообще от микроконтроллера требуется что бы он давал возможность выбрать цвет и дальше он принимает время задержки с смартфона. Сейчас с данным скетчем у меня при выборе цвета зажигается нужный цвет но дальше если я посылаю время задержки то светодиод тухнет и не подает признаков жизни. Если кто-нибудь знает как решить данную проблему или видел подобные проекты буду очень благодарен за любую оказанную помощь.
const int rPin = 3; const int gPin = 5; const int bPin = 6; int chosed_color; int val; int color; void setup() { Serial.begin(9600); pinMode( rPin, OUTPUT ); pinMode( gPin, OUTPUT ); pinMode( bPin, OUTPUT ); } void loop() { while(Serial.available()>0) { color = Serial.read(); if(color==1) { chosed_color = rPin; digitalWrite( rPin, HIGH ); digitalWrite(rPin, LOW); return chosed_color; } else if(color==2) { chosed_color = bPin; digitalWrite( bPin, HIGH ); digitalWrite(bPin, LOW); return chosed_color; } else if(color==3) { chosed_color = gPin; digitalWrite( gPin, HIGH ); digitalWrite(gPin, LOW); return chosed_color; } } if(Serial.available()>0) { val = Serial.read(); } digitalWrite( chosed_color, HIGH ); delay(val); digitalWrite(chosed_color, LOW); delay(val); }
Чето непонятен смысл этого всего. Как оно должно все это работать? Насколько я понял, ждать со смартфона сначала цвет, потом ждать задержку, и, если данные все получены, мигнуть указанным светодиодом с указаной задержкой? Так?
Ну и, что вы вкладываете в смысл return chosed_color;? Кому вы возвращаете chosed_color?
Drew20, у вас прием цвета и прием задержки написан одинаково - каким образом микроконтроллер должен их различить? Вам нужно придумать разные команды на изменение цвета и на задержку, например добавив для цвета в начале букву "с" - "с1" - это будет означать "цвет = 1". И аналогично для задержек, например "d250" = "задержка 250мс"
да вы все правильно поняли, но светодиод должен моргать бесконечно, а возврат переменной это уже мои изощрения для решения поставленой задачи. просто уже долго сижу и перепробовал все известные мне способы
Чето непонятен смысл этого всего. Как оно должно все это работать? Насколько я понял, ждать со смартфона сначала цвет, потом ждать задержку, и, если данные все получены, мигнуть указанным светодиодом с указаной задержкой? Так?
Ну и, что вы вкладываете в смысл return chosed_color;? Кому вы возвращаете chosed_color?
да вы все правильно поняли, но светодиод должен моргать бесконечно
ОК, продолжим. Что должен делать светодиод до того, как он получит данные? И второе, в процессе "бесконечного моргания" программа должна все так же ждать данные или приняли один раз и "до свидания"?
return в середине функции loop никого не беспокоит?
return в середине функции loop никого не беспокоит?
Я уже писал об этом. Но это не важно, там вообще код неправильно построен, поэтому надо перепысывать. Пока добиваюсь от ТС полного описания, как должно все работать.
мне необходимо выбирать цвет светодиода и дальше им мигать неопределенное время, так-же светодиод доолжен изменять частоту своего мигания на лету тоесть безпрерывно принимать частоту своего моргания определенным цветом. Я согласен со всеми вами что мой код имеет много ошибок или вообще не правильный, у меня только начальные знания в области програмирования и мой скетч может содержать КУЧУ ошибок. return я вставил только потому что у меня уже иссякли идеи как решить поставленную задачу. Я могу на данный момент отдельно выполнять только такие задачи как, изменение частоты мигания определенного цвета или просто выбрать определенный цвет и все. Если кто знает как мне помочь буду очень благодарен
return в середине функции loop никого не беспокоит?
Я уже писал об этом. Но это не важно, там вообще код неправильно построен, поэтому надо перепысывать. Пока добиваюсь от ТС полного описания, как должно все работать.
Тогда все просто и я бы предложил организовать все так. В сетапе нужно читать цвет светодиода (ведь я правильно понял, что цвет выбирается только один раз?). А уже в лупе читать задержки и мигать выбранным светодиодом.
я вот так попробовал но не получается может опять где-то ошибка???
Тогда все просто и я бы предложил организовать все так. В сетапе нужно читать цвет светодиода (ведь я правильно понял, что цвет выбирается только один раз?). А уже в лупе читать задержки и мигать выбранным светодиодом.
а почему там в блоке while chosed_color==-1?????
Вам надо в сетапе дождаться получения цвета. Поэтому задаем -1 т.к. пина с таким номером быть не может и крутимся в цикле пока пользователь не хзадал цвет и chosed_color не стал отличным от -1. Вообще это все в лупе можно делать, но раз vk007 предлагал в сетапе я и кинул вариант для сетапа.
а почему там в блоке while chosed_color==-1?????
Это значит, что будем крутиться в цикле пока chosed_color не присвоится какое-то значение.
Но я в таком случае chosed_color лучше бы проверял на допустимое значение (т.е. в данном случае 1, 2 или 3).
И кстати, читать лучше через Serial.parseInt() - если данные вводятся в порт вручную, то так сразу получим число, а не коды вводимых цифр.
а можно непрерывно считывать цвета светодиода, тоесть на данный момент у меня получается выбрать цвет помигать им но дальше нужно выключить устройство и только при следующем включении у меня есть возможность изменить цвет
Можно, во втором посте Вам написали как это сделать
а можно непрерывно считывать цвета светодиода
Да, можно, и даже уже ответили как. От себя добавлю. Понятно, что определение цвета делать в таком случае не в сетапе, а уже в лупе. Чтобы было проще можно все передавать одной коммандой. Например, "R250", или "G100", или "B300". Первый символ - цвет, остальное - задержка. Принимаем из serial строку и анализируем ее.
та я то этот пост читал, но мне не понятно что мы должны слать через блютуз и как нам инициализировать его дальше? и как его потом использовать для дальнейшей работы. тоесть мы например получаем с телефона d250 это значит что частота моргания светодиода 250 дальше мы знаем что изменить частоту светодиода можно через delay(???) и куда нужно слать полученную частоту. просто на сериал подается не byte а int и соответственно у нас есть два числа одно отвечает за цвет а второе за частоту. я могу слать данные при нажатии на кнопку к которой привязана определенная функция(android) а не считывать строку
мне не понятно что мы должны слать через блютуз и как нам инициализировать его дальше?
Слать можно все, что угодно и в каком угодно формате. Лишь бы ардуина понимала, что от нее этой командой хотят добиться. А для этого надо в скетче сделать анализ полученных данных.
Вы бы расписали сразу все, что задумали сделать, а то только выудил одно, рассказал, как реализовать, как оказалось, что светодиод надо уже не один раз выбирать, как утверждалось ранее, а постоянно, как и задержку. Сложно подсказывать, когда условия задачи меняются на лету.
upd. В первую очередь определитесь, какие параметры вам надо изменять и возможные их значения или диапазон значений (потому как, например, сначала вы говорили о задержках, а потом вдруг заговорили о частоте). Исходя из этого уже будем выбирать формат передаваемых данных.
я вас понял, короче как результат мы должны изменять безпрерывно цвет и частоту моргания. Например мы нажимаем на экране телефона кнопку с надписью красный и как результат зажигается красный цвет далее мы двигаем ползунок и этим самым меняем частоту мигания светодиодом у которого уже выбран цвет. вдруг нам неожиданно нужно поменять цвет мы нажимаем на другую кнопку например с надписью синий и зажигается синий цвет при этом нет потери частоты. Мы должны на лету менять как частоту так и цвет.
если вдруг опять я непонятно обьяснил спрашивайте, я уже и так понял что намного хуже могу рассказать что нужно чем все вы здесь и спасибо за то что помогаете.
ОК, т.е.: 1) передаем цвет и частоту, я правильно понял? 2) Цвета три - R, G, и B? 3) Гасить светодиоды надо? 4) Какой диапазон частоты нужен? 5) Значение частоты любое или набор фиксированных значений? 6) В один момент времени мигает только один светодиод?
мы передаем один из трех цветов и передаем частоту, да цвета три , гасить не нужно но при включении не нужно зажигать сразу нужно дождаться прихода соответствующего цвета с телефона диапазон частот вообще настроен на телефоне но если это нужно то мигает от 0 до 200 но лично мне легче когда у могу в программе на андроид сам поменять при необходимости крайние значения, значение частот любое
диапазон частот вообще настроен на телефоне но если это нужно то мигает от 0 до 200 но лично мне легче когда у могу в программе на андроид сам поменять при необходимости крайние значения, значение частот любое
1) от 0 до 200 - это в каких попугаях?
2) всему есть свои пределы, с минимумом и максимумом все-таки надо определиться.
2) всему есть свои пределы, с минимумом и максимумом все-таки надо определиться.
после прочтения сообщения выше я бы написал: "Всему есть предел - нельзя же так наплевательски обращаться с предложениями и знаками препинания!"
Каждый программист - в каком-то смысле писатель :) Человек, не умеющий связно выражать мысли - вряд ли сможет написать хорошую программу.
насколько я понял то частота в ардуино измеряется в милисекундах, а предели максимум от 0 до 1000
диапазон частот вообще настроен на телефоне но если это нужно то мигает от 0 до 200 но лично мне легче когда у могу в программе на андроид сам поменять при необходимости крайние значения, значение частот любое
1) от 0 до 200 - это в каких попугаях?
2) всему есть свои пределы, с минимумом и максимумом все-таки надо определиться.
насколько я понял то частота в ардуино измеряется в милисекундах, а предели максимум от 0 до 1000
Ага, т.е. все-таки не частота, а задержка (фактически полупериод)? Частота сигнала и его период - это несколько разные вещи, с точностью до наоборот.
ну эти данные отправляються в функцию delay() так что наверное да это задержка
насколько я понял то частота в ардуино измеряется в милисекундах
Частота измеряется в Герцах.
Тогда я бы предложил такой формат: буквой передаем цвет (возможные варианты комманды R, G и B), а числом - задержку (0 - 1000).
В таком случае для определения отправленной комманды в скетче я бы делал так: в if(Serial.available()>0) первый байт сначала прочитал через Serial.peek() (эта функция читает символ из буфера, но не удаляет его оттуда). Если прочиталась не цифра, а буква ('R', 'G' или 'B'), значит это комманда смены цвета и переключаем активный светодиод. (После этого с помощью Serial.read() надо все-таки вычитать этот символ из буфера (в никуда), чтобы он оттуда удалился). Если же в результате чтения Serial.peek() выдал цифру, значит пришла комманда смены задержки. Принимаем ее с помощью Serial.parseInt() и полученное число используем в delay. Единственный нюанс, комманды надо передавать не числом, а строкой (например, "250" - т.е. три символа подряд: '2', '5' и '0').
ну задержка, я уже знаю эти тонкости, просто тогда немного тупанул
а текущий код никак нельзя изменить?? ну просто сейчас все хорошо только цвет выбирается один на всю сессию работы а нужно безпрерывно, может что то куда-то перенести? из одного блока кода в другой например
Ну как-бы там того скетча кот наплакал, что менять, что переписывать - один хер.
Данные как передаются? Пока через монитор порта или на смартфоне уже есть готовая программа?
а текущий код никак нельзя изменить?? ну просто сейчас все хорошо только цвет выбирается один на всю сессию работы а нужно безпрерывно, может что то куда-то перенести? из одного блока кода в другой например
да ничего у вас не хорошо. Весь код из ошибок. Вы сейчас задержку как отправляете? - в виде int ? - а читаете только один байт. То есть больше 256 вообще передать не можете. Это не говоря о том, что она вообще из сериала не читается. Ваш код не рабочий в принципе. его только выкинуть.
ну почему-же я пробовал отправлять больше 256 и нормально работало, просто нужно немного доделать и будет нормально
Поверьте, в данном случае лучше написать с нуля. Тем более, что там писать почти нечего, и примерную последовательность обработки я уже написал.
ну почему-же я пробовал отправлять больше 256 и нормально работало
совершенно ответственно заявляю. что это ВРАНЬЕ. Вы читаете задержку из порта как
val = Serial.read();
В этом случае у вас читается из порта байт, и в нем НИКАК НЕ МОЖЕТ БЫТЬ больше 256.
я конечно попробую написать так как Вы советуете, но не уверенн что все получится так как было описано
Поверьте, в данном случае лучше написать с нуля. Тем более, что там писать почти нечего, и примерную последовательность обработки я уже написал.
но я посылаю int у меня есть переменная int которой присваеваеться это значение как там байт береться я не пойму
ну почему-же я пробовал отправлять больше 256 и нормально работало
совершенно ответственно заявляю. что это ВРАНЬЕ. Вы читаете задержку из порта как
val = Serial.read();
В этом случае у вас читается из порта байт, и в нем НИКАК НЕ МОЖЕТ БЫТЬ больше 256.
но я посылаю int у меня есть переменная int которой присваеваеться это значение как там байт береться я не пойму
не имеет ни малейшего значения, что вы посылаете. Посылаете вы может и правильно, а вот читаете - нет. Оператор Serial.read() читает из порта ОДИН БАЙТ - понимаете? он не может прочитать ни int ни long - хоть вы ему все собрание сочинений Ленина пошлите разом.
и как мне тогда читать?? int я так понял мы не прочитаем никак?
но я посылаю int у меня есть переменная int которой присваеваеться это значение как там байт береться я не пойму
не имеет ни малейшего значения, что вы посылаете. Посылаете вы может и правильно, а вот читаете - нет. Оператор Serial.read() читает из порта ОДИН БАЙТ - понимаете? он не может прочитать ни int ни long - хоть вы ему все собрание сочинений Ленина пошлите разом.
и как мне тогда читать?? int я так понял мы не прочитаем никак?
командой read за один раз - никак. Можно либо передавать в виде строк, как советует VK007, можно в виде двоичных данных - цепочек байт, но в любом случае данные придется собирать из отдельных байт и анализировать. Нужно знать, где начало сообщения и где конец и какова его длина.
То, что вам выше написал vk007 - это самый упрощенный вариант обмена по сериал, проще просто не бывает.
Вы не ответили, что у вас за программа стоит на смартфоне? Самописная? Если будете делать по моей методике, не забудьте "научить" ее отправлять не числа в виде int, а строки в виде символов. Т.е. символы ('R', 'G' или 'B') для цвета и строки в виде отдельных символов цифр ('0'-'9') для чисел для задержки - "0", "99", "250", ..., "1000". Иначе вся эта затея выеденного яйца не будет стоить, например, если отправить в порт число 82 - как его следует понимать, как цвет (символ 'R') или задержку равную 82?
и еще, прежде чем что-то писать, я бы советовал вам прочитать учебник по Си и справочник по библиотеке Ардуино. Вы сейчас элементарных вещей не знаете и ничего хорошего написать не сможете.
да программа моя, сейчас пытаюсь разделить на две разные функции цвет и задержку
спасибо за совет b707 обязательно прочту мне это пригодится в дальнейших проектах
Если своя, то это ОК, можно напрограмить что хош. Но пока можно обойтись и без смартфона, а лучше экспериментировать в мониторе порта на ПК. Отладите так, потом и за смартфон браться можно будет.
ну я сейчас пробую сделать то что вы сказали но не сильно получается через монитор порта, я так понял что там отправить можно только строку у которой расширение byte и проблема опять с скетчем он вообще не работает, вот я в луп сделал считывание всего что нужно, но оно не читает ничего, походу где-то опять ошибка, мне вот не понятно ваша строка "если прочиталась не цифра, а буква ('R', 'G' или 'B'), значит это комманда смены цвета и переключаем активный светодиод. (После этого с помощью Serial.read() надо все-таки вычитать этот символ из буфера (в никуда), чтобы он оттуда удалился). Если же в результате чтения Serial.peek() выдал цифру, значит пришла комманда смены задержки. " что означает вычитать символ из буфера, что бы он оттуда удалился, и как я потом смогу менять частоту мигания светодиода если он еще не зажегся сначала ведь нужно выбрать цвет а потом уже меня частоту
Drew20, начните все-таки с учебника, и даже не с учебника Си. а "ПК для чайников" - почитайте что такое байты и чем они отличаются от символов.
Ну, право, то, что вы делаете - это браться решать диффуравнения, не выучив таблицу умножения. Я на таком уровне помогать не берусь. Может vk007 согласится, в таком случае от души ему сочувствую, это будет непросто.
Вот вы прочитали color = Serial.peek(); но не делаете анализ того, что прочитали, а сразу его используете для выбора цвета.
А надо проверить, если color == 'R' (или 'G', или 'B') значит это цвет и тогда уже chosed_color = pins[color-1]; а следом Serial.read(); (для удаления этой буквы из буфера).
Если же color == '0' (или '1', или '2', ..., или '9'), т.е. считали цифру, то значит в порт пришло число (т.е. данные для задержки) и читаем его val = Serial.parseInt();
vk007 . да о чем вы???
вы вчитайтесь - он в порт "строку с расширением byte" отправляет :))))))