Причем тут это? Обычно эта фраза употребляется когда человек задает вопросы, не описав детали задачи, забыва что другие форумчане не видят того что у него перед глазами. И все нужно описывать. Вроде эту болезнь топик-стартер уже, более-менее, преодолел.
В стартовом посте уже было подобное видео. Так что существование подобных проекто - изначально не являлось тайной. Только, как я понял, хочется именно "самому написать". Все таки "скопироватьч чужой" и "самому пройти" - дают разные результат с точки зрения полученных умений.
Я вот, например, сейчас пишу свою Stepper библиотеку. Знаю ли я о существовании Stepper library и AccelStepper? Да, знаю. Будет ли моя "лучше"? Не факт. Скорее всего просто "не хуже" и "очень похожа". Возможно я в итоге ее выкину и воспользуюсь общеизвестными. Но вот мое понимание работы степперов - уже существенно поднялось.
Про телепатов я прав, потому что приведенный кусок кода не дает возможности понять, почему у тс некорректная запись в массив. UPD: Безусловно в нем есть ошибка, но это не значит, что её нет в другом месте.
Приведенная мной ссылка дает возможность посмотреть исходники готового проекта и примерно быть готовым к таким объемам кода.
Да, так и есть , но яне знаю что меня приводит в больший ужас: переменные (которые могут быть подписанны в одном месте) или мноого букв означающих переменную)))))
Простите, но это настолько детские "отмазки", что даже обсуждать не хочется.
Я не буду вас долго убеждать. У вас будет два выхода: либо освоить клавиатру, либо, через какое-то время - бросите програмирование.
В вашем стиле очевидно просматриваются "отголоски математического образования" :) Можно выписать "прицеп-формулу" и в конце написать "где x,y,z - это...."
Но, на програмерских форумах, большинство не будет вникать в ваш код. Он труден для понимания. Быстрым вглядом - не понятен. Значит вы существенно снижаете вероятность что кто-то будет вам помогать. Бросили беглый вгляд, не понятно, ну и не будем хмурить мозг - пойдем дальше.
И еще 100-причин есть изначально старатся вырабатывать правильный стиль.
Lihtelf пишет:
int[] pass = {1,2,1,2,1,2,0}; - искомый пароль
Непонятно зачем нам тут int, разве 0,1,2 не влезут в byte?
Да и зачем нам тут вообще аж три числа? IMHO 0,1 - вполне хватило-бы. К тому же если нас когда-нибудь клюнет петух "оптимизации", то можно будет перейти к битам. И хранить по восемь "точек, тире" в одном байте.
Lihtelf пишет:
int[] input = new int[7]; - пароль который будет введен
Пока что не могу понять как будет производится запись пароля в массив.
А зачем нам вообще его записывать? Идем по массиву pass. На каждом шаге сравниваем текущие эелемент тем что ввели только что. Если совпало - переходим к следующему элементу pass и сравниваем там. Если не совпало - сбрасываемся опять к нулевому элементу. Если дошли до конца pass - значит весь код введен верно.
То есть нам достаточно помнить только один ввод пользователя. Что-то "стукнул" только что. Иначе у нас еще вылезут проблемы - как определять "конец ввода" и т.п.
Lihtelf пишет:
Столкнулся с той же проблемой, при переходе на другую ячейку, значение предыдущей стирается.
Вы столкнулись с проблемой "игнорирую что мне советуют".
Безусловно, принимать все советы бездумно - не стоит. Но если вы считаете что ваш опыта/понимания хватает для того что-бы выбирать "какой совет стоит попробовать, а какой - нет". То и будте готовы разбиратся с последствиями выбора :)
Вспомните:
Lihtelf пишет:
Отрицптельные интервалы мне никак не мешают)) ведь они не подходят под условие if
И подумайте какие еще последсвия, кроме отрицательных интервалов, имеет ваш подход (я ведь не прост так говорил "перенесите", ведь это очевидное место будущих проблем, не должно быть кода которые выполняется по своему желание, а не по нашей потребности).
Вообщем, может, все-таки, стоит прислушаться к совету вначале "дожать" вычисление интервалов, потом "опознавание" сделать качественно и только потом переходить к массивам? Как видите - недоделки (даже больше "не до конца разобрался") предыдущих этапов, все-равно вылазят боком, при дальнейшем усложнении скетча.
И подумайте какие еще последсвия, кроме отрицательных интервалов, имеет ваш подход (я ведь не прост так говорил "перенесите", ведь это очевидное место будущих проблем, не должно быть кода которые выполняется по своему желание, а не по нашей потребности).
Вообщем, может, все-таки, стоит прислушаться к совету вначале "дожать" вычисление интервалов, потом "опознавание" сделать качественно и только потом переходить к массивам? Как видите - недоделки (даже больше "не до конца разобрался") предыдущих этапов, все-равно вылазят боком, при дальнейшем усложнении скетча.
Не пойму, что там дожимать, скажите прямо, я просто вижу ,что это работает и перехожу дальше. Не надо воспринимать то, что я написал как "отказ" от советов,я просто не очень понимаю в чем проблема и подсознательно перехожу дальше. Прямо скажите в чем проблема!))
С переменными попытаюсь исправится, несмотра на то , что мне это только усложняет дело:)
Сейчас попробую:
leshak пишет:
На каждом шаге сравниваем текущие эелемент тем что ввели только что. Если совпало - переходим к следующему элементу pass и сравниваем там. Если не совпало - сбрасываемся опять к нулевому элементу. Если дошли до конца pass - значит весь код введен верно.
Почему не 0,1? В моем случае 0=1,1=2, а 0 это все остальные сигналы которые не относятся к моему сигналу. Ведь если дан "неправильный сигнал" то по вашей системе он будет расценен как 0, а это короткий сигнал.(поправьте если неправ)
Строки 17,18,19 выполняются постоянно. А вам достаточно один раз вычислять. И одни раз выводить. В момент отпускание кнопки. То есть все это нужно перенести внутрь второго if-а, после строки 15-ть вставить.
То есть вас есть кусок кода, который должен вызыватся при определенном событии (отпускание кнопки), а он у вас вызывается раз за разом (рисует, меняет переменные и т.п.) что, естесвенно, приводит к негативным последствиям. Одни из последсвий (получение бессмысленных интервалов и "информационный шум" - я вам указал), вы споткнулись на другом - меняются переменные когда мы не ждем.
Но первопричина, которую вы не устранили - общая: действия которые должны выполнятся на события, выполняются "когда прийдется". Словами бы как бы вы описали алгоритм? "Когда отпускается кнопка, вычисляем интервал его удержания, выводим его, если он больше чего-то, то..., если меньше, то...". А в коде все происходит не так. Мы как "белка в колесе" пытаемся что-то вычислить (при этом плюем на то, есть у нас корректные данные для вычисления или нет), что-то выводим (не заботясь о том, нужно это сейчас или нет) и т.п.
Lihtelf пишет:
Не надо воспринимать то, что я написал как "отказ" от советов,я просто не очень понимаю в чем проблема и подсознательно перехожу дальше.
Получив совет у вас всегда есть три варинта действий (естественно после попытки осознать его):
1. Выполнить (хотя-бы посмотреть что из этого выйдет, попытатся понять "а в чем разница", посмотреть на результат совета).
2. Задать вопрос, попросить объяснить.
3. Проигнорировать.
Вы выбрали (3) :(
Мне вообще все-равно (не нужно воспринимать это что я пытаюсь "обидится"). Я наблюдал такое десятки раз. :) Более того, такое даже является "типичным". Так что я отношусь к этому спокойно.
Почему не 0,1? В моем случае 0=1,1=2, а 0 это все остальные сигналы которые не относятся к моему сигналу.
А зачем на это записывать в "эталонный пароль"? Вам когда в банки выдавали бумажку с пин-кодом карты, на ней же было написанно, что-то вида PIN:"1234", а не PIN:"1234*", где * - всякие неправильные цифры.
В том то и дело, вот вы говорите 1234, допустим там не 1234 , а 1230. Любую другую цифру кроме 0,1,2,3 он будет воспринимать как 0 => при вводе 1235 = 1230
Да. Принципиально другой подход. Еще раз. Нам тут не нужно запомнить что ввел пользователь.
Представте что это игра. Есть длинный коридор . Перегороженный дверьми. Разбитый на комнаты. Каждая дверь имеет две кнопки 0 и 1. Что-бы пройти в следующую комнату нужно нажать правильную кнопку (у каждой двери своя). Игрок должен знать "какая кнопка правильная". Если он нажал правильную - дверь открывается, он проходит в следующую комнату и оказывается перед следующей дверью. Если нажал не верную - игрока убивают, и он начинает игру заново. С первой комнаты. Опять оказывается перед первой дверью. Так же его можно "убивать" (отбрасывать к началу), если он вообще "не попал по кнопке" или "слишком долго думал".
Если он прошел все команты (смог открыть последнюю дверь) - его встречает принцесса (и теща в нагрузку).
В нашем случае:
"проходение коридора" - ввод пароля,
"двери" - элементы массива "пароль" (как видите дверей с кнопками "2,3 или 4" - у нас просто нет).
"получение приза" - ну соственно какое-то действие которое вы задумали при введение правильного пароля. Например - зажечь светодиод.
"убивание пользователя" - текущим проверяемым элементом массива, опять становится нулевой элемент
"переход в следующую комнату" - увеличиваем переменную- "текущий индекс массива пароль" на еденицу.
(как видите дверей с кнопками "2,3 или 4" - у нас просто нет)
И снова "2,3,4" у нас есть. Смотрите есть короткое нажатие (=0) и длинное(=1), но есть и ооочень длинное (допустим 3 секунды) оно будет расцениваться как "0"! А это уже портит весь пароль))
В том то и дело, вот вы говорите 1234, допустим там не 1234 , а 1230. Любую другую цифру кроме 0,1,2,3 он будет воспринимать как 0 => при вводе 1235 = 1230
Я правильно все понял?
Не совсем. Вы правы что в том, что пользвоатель может вводить что-то вообще "непонятное". То есть пользователь у нас может ввести 0,1, * - где * - непонятно что (не смогли мы понять длинно он стукнул или коротко).
То есть ввод пользователя действительно может выглядить 101*101*, но вот в эталоном-то пароле нам * зачем?
Если "пароль у нас "10101010" и пользователь на четвертной цифре ввел "что-то отличное от нуля", то какая разница ошибся он введя еденицу, ввел непонятно что, или вообще впал к кому и перестал что-то вводить? Главное что он не ввел ожидаемый 0. Все - введеный пароль не верен. "Иди лесом".
Соотвественно когда мы "кодируем пароль в коде" - нам нет нужды в текст самого пароля записывать какие-то "неправильные символы". Бумажка-пароль с которой будет сверятся охранник - должна содержать только "правильные" символы, в правильной последовтельно. И больше ничего. Любое несовпадение с этой бумажкой рассценивается как "пароль введен неверно".
n=p, сюда затесалось по ошибке. Оно, таки должно быть в конце loop(), вне if(). Оно ведь относится не "к дейсвтиям при отпускании кнопки", а к "обнаружению факта отпускания кнопки".
Ну и, какой-то print(i), вставить-бы туда (внутрь if-а), что-бы видеть какой же мы интервал высчитали.
Кстати, неплохо еще при нажатии кнопки - обнулять i. А то у нас выходит - кнопку нажали, и пока мы держим ее нажатой - переменная i, содержит неверное значение от предыдущего отпускания.
Кстати, если бы я делал, то вооще не давал возможности пользователю ввести что-то кроме "короткое и длинное". И все проблемы с терьей цифрой - отпадут.
То есть у меня было-бы
меньше XXX - вообще считаем что нажатия небыло (дребезг кнопки и т.п.). Никаких действий вообще не предпринимаем.
от XXX до YYY - короткое нажания
больше YYY - длинное (нет ограничения "сверху", зачем?)
И еще, дополнительно, вычислял еще один интервал "а сколько времени прошло с последнего нажимания кнопки". То есть не "от нажатия до отпускания", а "от нажатия до текущего момента". Если он слишком большой, значит слишком долго ничего не нажимали вообще. Ввод пароля прекратился, и значит "нужно опять начинать все с начала". Убить пользоватля и ждать ввода первой цифры. Вот этот интервал - уже нужно будет вычислять при каждом проходе draw()/loop(). Это типичная реализация timeout.
Кстати, если бы я делал, то вооще не давал возможности пользователю ввести что-то кроме "короткое и длинное". И все проблемы с терьей цифрой - отпадут.
То есть у меня было-бы
меньше XXX - вообще считаем что нажатия небыло (дребезг кнопки и т.п.). Никаких действий вообще не предпринимаем.
от XXX до YYY - короткое нажания
больше YYY - длинное (нет ограничения "сверху", зачем?)
Все дело в том что это не кнопка, а кровать!))) и я могу касаться ее ногой ночью)))) и это будет расцениваться как длинный сигнал, хотя это особо мне не должно мешать.
leshak пишет:
И еще, дополнительно, вычислял еще один интервал "а сколько времени прошло с последнего нажимания кнопки". То есть не "от нажатия до отпускания", а "от нажатия до текущего момента". Если он слишком большой, значит слишком долго ничего не нажимали вообще. Ввод пароля прекратился, и значит "нужно опять начинать все с начала". Убить пользоватля и ждать ввода первой цифры. Вот этот интервал - уже нужно будет вычислять при каждом проходе draw()/loop(). Это типичная реализация timeout.
Эта идея приходила мне в голову, в дальнейшем будет 100% использована
Все дело в том что это не кнопка, а кровать!))) и я могу касаться ее ногой ночью)))) и это будет расцениваться как длинный сигнал, хотя это особо мне не должно мешать.
И что с того? Ну сделали вы случайно ногой одно длинное нажатие. Это ж не не "код отстучали". Не примет этот код и ничего не произойдет. К тому же, даже если вы ограничити "длинное нажатие не более чем YYYY", то где гарантия что ногой ночью не "впишитесь в этот интервал"?
То есть вероятность случайно ввести "длинное нажатие", "короткое нажатие" - у вас будет в любом случае. Для того и "пароль" что-бы это не приводило к катострофичесим последствиям.
Кстати, неплохо еще при нажатии кнопки - обнулять i. А то у нас выходит - кнопку нажали, и пока мы держим ее нажатой - переменная i, содержит неверное значение от предыдущего отпускания.
При определении типа нажатия, лучше использовать конструкцию if(){} else if () {} - тогда условия станут попроще.
Так же пора привыкать следить не только за именами переменных, но и за форматированием кода. За оттупами. То что вложено в фигурные скобки - отодвигать вправо. Что-бы было видно какие {} к чему относятся.
В ArduinoIDE можно автоматом это "подравнять", нажить CTRL-T, но я предпочитаю - руками.
Кстати, неплохо еще при нажатии кнопки - обнулять i. А то у нас выходит - кнопку нажали, и пока мы держим ее нажатой - переменная i, содержит неверное значение от предыдущего отпускания.
Единственная проблема, надо найти замену "х== " и чтобы при неправильном вводе обнулялся door.
Честно говоря, я вообще не понимаю что вы хотели тут сделать. Почему door у нас все время 1? Мы же должны дальше идти. Или у вас door - это не номер текущей двери? Тогда что?
И не обижайтесь, но вот реально эти j,x - взрывают мозг.
Вот смотрю этот кусок кода, ну что такое x?
а j? То что пользователь ввел?
Вот pass[] - уже можно догадатся приблизительно.
Ну так давайте и назовем
door - номер текущей двери
pressType - что распознанный ввод пользователя (0,1 или 2).
тогда:
if(pass[door]==pressType){ // пользователь угадал что нужно нажать для текущей двери
door++; // перехоим к следующей
if(door==КОЛИЧЕСТВО_ДВЕРЕЙ){ // мы прошли все двери, код введен правильно
println("Sucess!!!! You are winner!!!!"); // сообщили что код введен правильно
door=0; // и опять готовы слушать код с начала
}
} else { // пользователь не угудал что нажуно нажать
println("faile, invalid code, try again...."); // сообщили об этом
door=0; // и вернулись к первой двери
}
При определении типа нажатия, лучше использовать конструкцию if(){} else if () {} - тогда условия станут попроще.
Так же пора привыкать следить не только за именами переменных, но и за форматированием кода. За оттупами. То что вложено в фигурные скобки - отодвигать вправо. Что-бы было видно какие {} к чему относятся.
В ArduinoIDE можно автоматом это "подравнять", нажить CTRL-T, но я предпочитаю - руками.
Про else if я не знал, спасибо, знал бы применил именно это. Но стоит ли сейчас это испралять?( не поймите неправильно, но уже мозги кипят)))
У меня door это состояние двери, то есть, если door = 1 , то дверь открыта и нам разрешено перейти к следующему шагу.
Х - это количество нажатий, а точнее каким по счету является данное нажатие, при неправильном "пароле" оно обнуляется(то есть оно отвечает за ячейку в пароле)
Извините сразу както выпал из этой темы, не следил, хотя она очень интересная
Может я не прав , но я бы попробавал сделать так, решая задачу секретного кода
Насколько я понял Вы решили задачу определения временного растояния между нажатиями и у вас есть набор состояний единичка и временное растояние до следующего, за исключением последнего.
Я бы сделал скетч на основе Этого кода, который просто записывает эти расстояния в массив, преобразуя расстояния в музыкальные паузы
иТОго имели бы список пауз ограниченных по количеству ( точка , тире частный случай из этого ряда) как вариант 1/4,1/8 ,1/16/,1/32
музыкальные паузы - только для того чтобы ограничить варианты и уйти от временных числовых параметров.
Желательно этим же скетчем привести записанный массив к массиву из стандартных пауз по длительности.
То есть определить самую длинную паузу, взять ее за 1/4 например, остальные будут короче, 1/16 и тд. То есть решить проблему масштаба по длительности.
Далее имея пару тройку таких записей стуков как образцов для подражания, в аналогичном скетче пытаемся родить свой стук - похожий на какой либо из "библиотечных".
Перед нами задача сравнения только что набитого стука с "записанными ранее" , типичная задача по распознаванию образов, которая достаточно успешно решается подбором измеряемых параметров и вычислением корней из суммы квадратов ошибки параметров, подробнее можно поднять теорию распознования, там миллион методов
варианты параметров
1)количество стуков ( в штуках)
2) расстояние между первым и вторым стуком ( в паузах)
3) расстояние между первым и последним стуком
4) расстояние между вторым и третьим стуком ...
5) расстояние между первым и третьим стуком ... и тд
6) расстояние между самым длиным и последним ...
их можно придумать много
чем больше параметров тем многомернее вектор измерения библиотечных массивов, с только что записанным
сравнивать их необходимо так чтобы на выходе сравнивающей функции было значение скажем от 0 до 1 ( или от 1 - до десяти)
смысл в общем заключается в вычислении расстояния в многомерном пространстве параметров между эталоном и записью, суть которого в формуле sqrt( e1^2+e2^2 +e3^2 ...e5^2) минимальное значение будет указывать на максимальную близость с библиотечным образом стука
Извините что без кода )) это мысли вслух, я думаю что ардуино не та среда разработки чтобы отлаживать сам механизм распознования, но на Сях того же борланда почему нет, да хоть на Бэйсике, и потом все перенести на дуину.
Это я понял , главную задачу Вы решили, просто если так оставить, то ждет небольшое разочарование в виде - Я почти так стучу код, а "оно" не понимает. Можно даже и точку тире попробовать сравнить не в лоб, а с помощью методов распознования, скажем лишний первый сигнал в "алгоритме открывания дверей" губительно скажется на результате, несмотря на то что в целом "мелодия" правильная.
Ну тут есть еще одно различие.
Не знаю помешает ли это мне, но если идти стуками, то измерятся должен интервал между нажатиями, а не длинна нажатия,как у меня.
Ну тут есть еще одно различие.
Не знаю помешает ли это мне, но если идти стуками, то измерятся должен интервал между нажатиями, а не длинна нажатия,как у меня.
Дык а в чем принципиальная разница? отнимаем "момент нажатия от момента отпускания", а в другом "от отпускания до нажатия".
Ну тут есть еще одно различие.
Не знаю помешает ли это мне, но если идти стуками, то измерятся должен интервал между нажатиями, а не длинна нажатия,как у меня.
В Ваш код не вникал, сейчас посмотрю, меня смущает ваш processing и мышка, я не работал с этим.
Ну скажем если фронты подъема в 1 мерять - то это растояние между нажатиями , как я понимаю
Плюс я так и не понял как записать "ввод" в массив.(Намек на то , чтобы объяснили :))
Опять, а в чем принципиальная разница от того что уже написанно?
Посмотрите как мы проверяем совпадает-ли введение с паролем?
if(pass[door]==pressType
Если мы всесто pass[] взмем другой массив, скажем userInputs[] и вместо сравнивания будем делаем присваивание его элементов то в итоге он будет содержать "что там юзер настучал"
userInputs[door]==pressType;
door++; // что-бы следующий ввод сохранялся в новую ячекку
Ну и, само собой, нужно следить что-бы door не стала больше чем размер массива userInputs. Вдруг у пользователя эпелептический припадок и он трое суток беспрерывно "стучит". Мы не сможем "запомнить все". Только "то что влезет в массив".
Вообщем почитайте какой-нибудь учебник по C/C++ про массивы и for и т.п. Явно этого не хватает (хотя-бы из попыток писать pass[1],pass[2],pass[3] и т.п.)
в посте #47 великолепный выход из цикла, все остальные сигналы
38if(i<30||i>250&&i<280||i>420){ // все остальные сигналы
Спасибо))
leshak, вставил ваш код.
int[] pass = { 1, 2, 1, 2, 1, 2 };
int MaximumDoors = 6;
if (pass[door]==pressType) { // пользователь угадал что нужно нажать для текущей двери
door++; // перехоим к следующей
if (door==MaximumDoors) { // мы прошли все двери, код введен правильно
println("Sucess!!!! You are winner!!!!"); // сообщили что код введен правильно
door=0; // и опять готовы слушать код с начала
}
}
else { // пользователь не угудал что нажуно нажать
println("faile, invalid code, try again...."); // сообщили об этом
door=0; // и вернулись к первой двери
}
println(door);
}
Короче не работет. Поставил чтобы показывалось состояние door, так вот, при вводе первого правильного знака пароля door становится равным 1,но через цикл 0 и опять 1, то есть как-бы чередуется door=1 door=0. После ввода второго знака door становится равным 0 постоянно пока не введу первый знак эталонного пароля.
Может нужно впихнуть в if (b),то есть когда кнопка отпускается?.
int[] pass = { 1, 2, 1, 2, 1, 2 };
int MaximumDoors = 6;
for(door=0; door<=MaximumDoors && pass[door]==pressType; door++){
if (door==MaximumDoors) { // мы прошли все двери, код введен правильно
println("Sucess!!!! You are winner!!!!"); // сообщили что код введен правильно
}
}
Добавил чтобы при большом интервале(межди нажатиями) сбрасывалась door.
byte n=0;// предыдущее состояние
byte p; //состояние кнопки
int i; //длинна нажатия
int a; //момент нажатия кнопки
int b; //момент отпускания кнопки
int pressType; // определяет круг и квадрат("."/"-")
byte door;
byte relay=0;
int interval;
void draw() {
int m=millis();
if (mousePressed||keyPressed) {
p=1;
}
else
p=0;
if (n==0 && p==1) {///////нажали
a=millis();
}
if (n==1 && p==0) {///////отпустили
b=millis();
i=b-a;
if (i > 30 && i < 130) { //определение короткого сигнала
pressType = 1; //
}
if (i > 170 && i < 620) { //определение длинного сигнала
pressType = 2; //
}
if (i<30||i>130&&i<170||i>620) { // все остальные сигналы
pressType=0;
}
int[] pass = { 1, 2, 1, 2, 1, 2 };
int MaximumDoors = 6;
if (pass[door]==pressType) { // пользователь угадал что нужно нажать для текущей двери
door++; // перехоим к следующей
if (door==MaximumDoors) { // мы прошли все двери, код введен правильно
println("Sucess!!!! You are winner!!!!"); // сообщили что код введен правильно
door=0; // и опять готовы слушать код с начала
if (relay==0) {
relay=1;
}
else {
relay=0;
}
}
if (interval>2500) // возвращаемся, если долго не нажимали
door=0;
}
else { // пользователь не угудал что нажуно нажать
println("faile, invalid code, try again...."); // сообщили об этом
door=0; // и вернулись к первой двери
}
println("Длинна нажатия " + i + " м"); //длинна нажатия
println("Интервал " +interval);
println("Дверь №"+door);
println("Реле "+relay);
}
n=p;
interval=m-b;
}
int[] pass = { 1, 2, 1, 2, 1, 2 };
int MaximumDoors = 6;
for(door=0; door<=MaximumDoors && pass[door]==pressType; door++){
if (door==MaximumDoors) { // мы прошли все двери, код введен правильно
println("Sucess!!!! You are winner!!!!"); // сообщили что код введен правильно
}
}
Попробовал с for. В чем ошибка ?))
Как минимум в условии door<=MaximumDoors. Нумерация массиова-то с нуля. Значит какой у нас максимально допустимый индекс при 6-ти дверях? Вообщем door<MaximumDoors
Во вторых. А вы пытались сами, в голове выполнить этот цикл? Ну вот пришли вы к нему, с каким-то значение в pressType. Давайте, крутите цикл в голов, сделали первый проход, сравнили введеное с door[0], пошли делать второй проход цикла, сравнили door[1]. А с чем сравнили-то? Ведь повторого чтения от пользователя вы не делали :( Сравнили-то опять тоже самое нажатие.
То есть вы от пользователя разспознали одно нажатие и пошли сравнивать его со всеми элементами pass[]. Пройти этот цикл "до конца" можно только в одном случае. Если весль пароль состоит из одних 1, или весь из 2.
После того как "прошли дверь", нужно ведь опять, начать опрашивать кнопки, выяснть что пользователь нажмет для второй двери и т.п.
Если "готово==работает" - то ответ "нет". Это вы и без меня могли-бы ответить, это я вас должен спрашивать работает-ли оно:)
Вы верно проверили давно-ли небыло нажатий. И что по этому поводу делать (если забыть зачем вы тут вообще вводили переменную m да еще так далеко от использования. Что-бы враги не догадались? Да и переменную interval вводить было не обязательно. Можно было сразу if(millis()-b>2500)... писать.).
Ну да ладно. Можно и c m,interval .
Только вот где вы делалаете проверку "давно не нажимали" (вернее вы сделали "давно не отпускали")? Внутри ветки, куда процессор попадает только если пользователь правильно ввел очередное нажатие.
То есть этот "сброс по timeout" у вас будет рабтоать только в случае "мы вводим правильный код оче-е--н--н-ь медд-дд-дд-леее-нн-оооо".
Вот там где вы сам interval вычисляет, почему там сразу и "проверку/сброс" не сделать? Не отходя от касссы?
Кстати, когда эта часть стояла в том месте куда я поставил все отлично работало. То есть, даже если моя нога ночью набирает верно первые 1,2,1,2, но до следующего касания ждет больше 2.5 сек,то door сбрасывается. Не очень понял насчет очень медленного ввода, ведь первые знаки были введены быстро)
"Телепаты в отпуске".
Причем тут это? Обычно эта фраза употребляется когда человек задает вопросы, не описав детали задачи, забыва что другие форумчане не видят того что у него перед глазами. И все нужно описывать. Вроде эту болезнь топик-стартер уже, более-менее, преодолел.
http://arduino-projects.ru/projects/zamok-otkryivayuschijsya-na-sekretnyij-stuk/
В стартовом посте уже было подобное видео. Так что существование подобных проекто - изначально не являлось тайной. Только, как я понял, хочется именно "самому написать". Все таки "скопироватьч чужой" и "самому пройти" - дают разные результат с точки зрения полученных умений.
Я вот, например, сейчас пишу свою Stepper библиотеку. Знаю ли я о существовании Stepper library и AccelStepper? Да, знаю. Будет ли моя "лучше"? Не факт. Скорее всего просто "не хуже" и "очень похожа". Возможно я в итоге ее выкину и воспользуюсь общеизвестными. Но вот мое понимание работы степперов - уже существенно поднялось.
Про телепатов я прав, потому что приведенный кусок кода не дает возможности понять, почему у тс некорректная запись в массив. UPD: Безусловно в нем есть ошибка, но это не значит, что её нет в другом месте.
Приведенная мной ссылка дает возможность посмотреть исходники готового проекта и примерно быть готовым к таким объемам кода.
да и еще
Почему не 0,1? В моем случае 0=1,1=2, а 0 это все остальные сигналы которые не относятся к моему сигналу. Ведь если дан "неправильный сигнал" то по вашей системе он будет расценен как 0, а это короткий сигнал.(поправьте если неправ)
Сначала думал, что вы предлагаете что-то вроде этого
но теперь вижу, что понял что-то не так))
Не пойму, что там дожимать, скажите прямо,
А я разве не сказал прямо?
Строки 17,18,19 выполняются постоянно. А вам достаточно один раз вычислять. И одни раз выводить. В момент отпускание кнопки. То есть все это нужно перенести внутрь второго if-а, после строки 15-ть вставить.
То есть вас есть кусок кода, который должен вызыватся при определенном событии (отпускание кнопки), а он у вас вызывается раз за разом (рисует, меняет переменные и т.п.) что, естесвенно, приводит к негативным последствиям. Одни из последсвий (получение бессмысленных интервалов и "информационный шум" - я вам указал), вы споткнулись на другом - меняются переменные когда мы не ждем.
Но первопричина, которую вы не устранили - общая: действия которые должны выполнятся на события, выполняются "когда прийдется". Словами бы как бы вы описали алгоритм? "Когда отпускается кнопка, вычисляем интервал его удержания, выводим его, если он больше чего-то, то..., если меньше, то...". А в коде все происходит не так. Мы как "белка в колесе" пытаемся что-то вычислить (при этом плюем на то, есть у нас корректные данные для вычисления или нет), что-то выводим (не заботясь о том, нужно это сейчас или нет) и т.п.
2. Задать вопрос, попросить объяснить.
да и еще
Почему не 0,1? В моем случае 0=1,1=2, а 0 это все остальные сигналы которые не относятся к моему сигналу.
А зачем на это записывать в "эталонный пароль"? Вам когда в банки выдавали бумажку с пин-кодом карты, на ней же было написанно, что-то вида PIN:"1234", а не PIN:"1234*", где * - всякие неправильные цифры.
В том то и дело, вот вы говорите 1234, допустим там не 1234 , а 1230. Любую другую цифру кроме 0,1,2,3 он будет воспринимать как 0 => при вводе 1235 = 1230
Я правильно все понял?
но теперь вижу, что понял что-то не так))
Да. Принципиально другой подход. Еще раз. Нам тут не нужно запомнить что ввел пользователь.
Представте что это игра. Есть длинный коридор . Перегороженный дверьми. Разбитый на комнаты. Каждая дверь имеет две кнопки 0 и 1. Что-бы пройти в следующую комнату нужно нажать правильную кнопку (у каждой двери своя). Игрок должен знать "какая кнопка правильная". Если он нажал правильную - дверь открывается, он проходит в следующую комнату и оказывается перед следующей дверью. Если нажал не верную - игрока убивают, и он начинает игру заново. С первой комнаты. Опять оказывается перед первой дверью. Так же его можно "убивать" (отбрасывать к началу), если он вообще "не попал по кнопке" или "слишком долго думал".
Если он прошел все команты (смог открыть последнюю дверь) - его встречает принцесса (и теща в нагрузку).
В нашем случае:
"проходение коридора" - ввод пароля,
"двери" - элементы массива "пароль" (как видите дверей с кнопками "2,3 или 4" - у нас просто нет).
"получение приза" - ну соственно какое-то действие которое вы задумали при введение правильного пароля. Например - зажечь светодиод.
"убивание пользователя" - текущим проверяемым элементом массива, опять становится нулевой элемент
"переход в следующую комнату" - увеличиваем переменную- "текущий индекс массива пароль" на еденицу.
Опять же, если я правильно понял , то вы имели в виду именно это
Но теперь это не работает :(
Нам же нужно что-то вроде матрешки??
(как видите дверей с кнопками "2,3 или 4" - у нас просто нет)
И снова "2,3,4" у нас есть. Смотрите есть короткое нажатие (=0) и длинное(=1), но есть и ооочень длинное (допустим 3 секунды) оно будет расцениваться как "0"! А это уже портит весь пароль))
В том то и дело, вот вы говорите 1234, допустим там не 1234 , а 1230. Любую другую цифру кроме 0,1,2,3 он будет воспринимать как 0 => при вводе 1235 = 1230
Я правильно все понял?
Не совсем. Вы правы что в том, что пользвоатель может вводить что-то вообще "непонятное". То есть пользователь у нас может ввести 0,1, * - где * - непонятно что (не смогли мы понять длинно он стукнул или коротко).
То есть ввод пользователя действительно может выглядить 101*101*, но вот в эталоном-то пароле нам * зачем?
Если "пароль у нас "10101010" и пользователь на четвертной цифре ввел "что-то отличное от нуля", то какая разница ошибся он введя еденицу, ввел непонятно что, или вообще впал к кому и перестал что-то вводить? Главное что он не ввел ожидаемый 0. Все - введеный пароль не верен. "Иди лесом".
Соотвественно когда мы "кодируем пароль в коде" - нам нет нужды в текст самого пароля записывать какие-то "неправильные символы". Бумажка-пароль с которой будет сверятся охранник - должна содержать только "правильные" символы, в правильной последовтельно. И больше ничего. Любое несовпадение с этой бумажкой рассценивается как "пароль введен неверно".
Да, вы правы в эталонном пароле это не нужно.
Просто подумал, раз "по дефолту" если присвоено значение не было то это 0.
ну ладно фиг с ним))
Опять же, если я правильно понял , то вы имели в виду именно это
Но теперь это не работает :(
n=p, сюда затесалось по ошибке. Оно, таки должно быть в конце loop(), вне if(). Оно ведь относится не "к дейсвтиям при отпускании кнопки", а к "обнаружению факта отпускания кнопки".
Ну и, какой-то print(i), вставить-бы туда (внутрь if-а), что-бы видеть какой же мы интервал высчитали.
Кстати, неплохо еще при нажатии кнопки - обнулять i. А то у нас выходит - кнопку нажали, и пока мы держим ее нажатой - переменная i, содержит неверное значение от предыдущего отпускания.
Все , разобрался с этим и с проходом сквозь "коридор", щас добью и кину))
Кстати, если бы я делал, то вооще не давал возможности пользователю ввести что-то кроме "короткое и длинное". И все проблемы с терьей цифрой - отпадут.
То есть у меня было-бы
меньше XXX - вообще считаем что нажатия небыло (дребезг кнопки и т.п.). Никаких действий вообще не предпринимаем.
от XXX до YYY - короткое нажания
больше YYY - длинное (нет ограничения "сверху", зачем?)
И еще, дополнительно, вычислял еще один интервал "а сколько времени прошло с последнего нажимания кнопки". То есть не "от нажатия до отпускания", а "от нажатия до текущего момента". Если он слишком большой, значит слишком долго ничего не нажимали вообще. Ввод пароля прекратился, и значит "нужно опять начинать все с начала". Убить пользоватля и ждать ввода первой цифры. Вот этот интервал - уже нужно будет вычислять при каждом проходе draw()/loop(). Это типичная реализация timeout.
Все работет, однако последняя часть могла выглядеть короче.
"Подарок" - белый экран.
Кстати, если бы я делал, то вооще не давал возможности пользователю ввести что-то кроме "короткое и длинное". И все проблемы с терьей цифрой - отпадут.
То есть у меня было-бы
меньше XXX - вообще считаем что нажатия небыло (дребезг кнопки и т.п.). Никаких действий вообще не предпринимаем.
от XXX до YYY - короткое нажания
больше YYY - длинное (нет ограничения "сверху", зачем?)
Все дело в том что это не кнопка, а кровать!))) и я могу касаться ее ногой ночью)))) и это будет расцениваться как длинный сигнал, хотя это особо мне не должно мешать.
И еще, дополнительно, вычислял еще один интервал "а сколько времени прошло с последнего нажимания кнопки". То есть не "от нажатия до отпускания", а "от нажатия до текущего момента". Если он слишком большой, значит слишком долго ничего не нажимали вообще. Ввод пароля прекратился, и значит "нужно опять начинать все с начала". Убить пользоватля и ждать ввода первой цифры. Вот этот интервал - уже нужно будет вычислять при каждом проходе draw()/loop(). Это типичная реализация timeout.
Эта идея приходила мне в голову, в дальнейшем будет 100% использована
Единственная проблема, надо найти замену "х== " и чтобы при неправильном вводе обнулялся door.
Все дело в том что это не кнопка, а кровать!))) и я могу касаться ее ногой ночью)))) и это будет расцениваться как длинный сигнал, хотя это особо мне не должно мешать.
И что с того? Ну сделали вы случайно ногой одно длинное нажатие. Это ж не не "код отстучали". Не примет этот код и ничего не произойдет. К тому же, даже если вы ограничити "длинное нажатие не более чем YYYY", то где гарантия что ногой ночью не "впишитесь в этот интервал"?
То есть вероятность случайно ввести "длинное нажатие", "короткое нажатие" - у вас будет в любом случае. Для того и "пароль" что-бы это не приводило к катострофичесим последствиям.
Добавил кое-что,что бы при неправильно вводе "умереть" и вернуться.
Выходит код рабочий?
Кстати, неплохо еще при нажатии кнопки - обнулять i. А то у нас выходит - кнопку нажали, и пока мы держим ее нажатой - переменная i, содержит неверное значение от предыдущего отпускания.
Выделил жирным.
При определении типа нажатия, лучше использовать конструкцию if(){} else if () {} - тогда условия станут попроще.
Так же пора привыкать следить не только за именами переменных, но и за форматированием кода. За оттупами. То что вложено в фигурные скобки - отодвигать вправо. Что-бы было видно какие {} к чему относятся.
В ArduinoIDE можно автоматом это "подравнять", нажить CTRL-T, но я предпочитаю - руками.
Кстати, неплохо еще при нажатии кнопки - обнулять i. А то у нас выходит - кнопку нажали, и пока мы держим ее нажатой - переменная i, содержит неверное значение от предыдущего отпускания.
Выделил жирным.
Не знаю зачем это, но поробую поставить
Единственная проблема, надо найти замену "х== " и чтобы при неправильном вводе обнулялся door.
Честно говоря, я вообще не понимаю что вы хотели тут сделать. Почему door у нас все время 1? Мы же должны дальше идти. Или у вас door - это не номер текущей двери? Тогда что?
И не обижайтесь, но вот реально эти j,x - взрывают мозг.
Вот смотрю этот кусок кода, ну что такое x?
а j? То что пользователь ввел?
Вот pass[] - уже можно догадатся приблизительно.
Ну так давайте и назовем
door - номер текущей двери
pressType - что распознанный ввод пользователя (0,1 или 2).
тогда:
При определении типа нажатия, лучше использовать конструкцию if(){} else if () {} - тогда условия станут попроще.
Так же пора привыкать следить не только за именами переменных, но и за форматированием кода. За оттупами. То что вложено в фигурные скобки - отодвигать вправо. Что-бы было видно какие {} к чему относятся.
В ArduinoIDE можно автоматом это "подравнять", нажить CTRL-T, но я предпочитаю - руками.
Про else if я не знал, спасибо, знал бы применил именно это. Но стоит ли сейчас это испралять?( не поймите неправильно, но уже мозги кипят)))
У меня door это состояние двери, то есть, если door = 1 , то дверь открыта и нам разрешено перейти к следующему шагу.
Х - это количество нажатий, а точнее каким по счету является данное нажатие, при неправильном "пароле" оно обнуляется(то есть оно отвечает за ячейку в пароле)
Ваш код выглядет поизящнее)))Исправлюсь.
Извините сразу както выпал из этой темы, не следил, хотя она очень интересная
Может я не прав , но я бы попробавал сделать так, решая задачу секретного кода
Насколько я понял Вы решили задачу определения временного растояния между нажатиями и у вас есть набор состояний единичка и временное растояние до следующего, за исключением последнего.
Я бы сделал скетч на основе Этого кода, который просто записывает эти расстояния в массив, преобразуя расстояния в музыкальные паузы
иТОго имели бы список пауз ограниченных по количеству ( точка , тире частный случай из этого ряда) как вариант 1/4,1/8 ,1/16/,1/32
музыкальные паузы - только для того чтобы ограничить варианты и уйти от временных числовых параметров.
Желательно этим же скетчем привести записанный массив к массиву из стандартных пауз по длительности.
То есть определить самую длинную паузу, взять ее за 1/4 например, остальные будут короче, 1/16 и тд. То есть решить проблему масштаба по длительности.
Далее имея пару тройку таких записей стуков как образцов для подражания, в аналогичном скетче пытаемся родить свой стук - похожий на какой либо из "библиотечных".
Перед нами задача сравнения только что набитого стука с "записанными ранее" , типичная задача по распознаванию образов, которая достаточно успешно решается подбором измеряемых параметров и вычислением корней из суммы квадратов ошибки параметров, подробнее можно поднять теорию распознования, там миллион методов
варианты параметров
1)количество стуков ( в штуках)
2) расстояние между первым и вторым стуком ( в паузах)
3) расстояние между первым и последним стуком
4) расстояние между вторым и третьим стуком ...
5) расстояние между первым и третьим стуком ... и тд
6) расстояние между самым длиным и последним ...
их можно придумать много
чем больше параметров тем многомернее вектор измерения библиотечных массивов, с только что записанным
сравнивать их необходимо так чтобы на выходе сравнивающей функции было значение скажем от 0 до 1 ( или от 1 - до десяти)
смысл в общем заключается в вычислении расстояния в многомерном пространстве параметров между эталоном и записью, суть которого в формуле sqrt( e1^2+e2^2 +e3^2 ...e5^2) минимальное значение будет указывать на максимальную близость с библиотечным образом стука
Извините что без кода )) это мысли вслух, я думаю что ардуино не та среда разработки чтобы отлаживать сам механизм распознования, но на Сях того же борланда почему нет, да хоть на Бэйсике, и потом все перенести на дуину.
2Borland: это вы из пушки по воробъям предложили лупануть.
Да и банально топик-стартер этого не потянет. Тут с простейшими алгоритмами пока на "вы".
То что мы делаем - это просто измерение времени нажатия кнопки.
Все "распознавание" сводится к простому "попала эта длительность в диапазон в ОТ и ДО" или нет.
Попала в один диапазон - короткое нажатие, попала в другой - длинное.
Все. Дальше остается только сравнить "распознанное" с котрольной последовательность (в каком порядке должны идти эти короткие/длинные) и все.
Это я понял , главную задачу Вы решили, просто если так оставить, то ждет небольшое разочарование в виде - Я почти так стучу код, а "оно" не понимает. Можно даже и точку тире попробовать сравнить не в лоб, а с помощью методов распознования, скажем лишний первый сигнал в "алгоритме открывания дверей" губительно скажется на результате, несмотря на то что в целом "мелодия" правильная.
Ну тут есть еще одно различие.
Не знаю помешает ли это мне, но если идти стуками, то измерятся должен интервал между нажатиями, а не длинна нажатия,как у меня.
Плюс я так и не понял как записать "ввод" в массив.(Намек на то , чтобы объяснили :))
Ну тут есть еще одно различие.
Не знаю помешает ли это мне, но если идти стуками, то измерятся должен интервал между нажатиями, а не длинна нажатия,как у меня.
Дык а в чем принципиальная разница? отнимаем "момент нажатия от момента отпускания", а в другом "от отпускания до нажатия".
Ну тут есть еще одно различие.
Не знаю помешает ли это мне, но если идти стуками, то измерятся должен интервал между нажатиями, а не длинна нажатия,как у меня.
В Ваш код не вникал, сейчас посмотрю, меня смущает ваш processing и мышка, я не работал с этим.
Ну скажем если фронты подъема в 1 мерять - то это растояние между нажатиями , как я понимаю
Плюс я так и не понял как записать "ввод" в массив.(Намек на то , чтобы объяснили :))
Опять, а в чем принципиальная разница от того что уже написанно?
Посмотрите как мы проверяем совпадает-ли введение с паролем?
if(pass[door]==pressType
Если мы всесто pass[] взмем другой массив, скажем userInputs[] и вместо сравнивания будем делаем присваивание его элементов то в итоге он будет содержать "что там юзер настучал"
Ну и, само собой, нужно следить что-бы door не стала больше чем размер массива userInputs. Вдруг у пользователя эпелептический припадок и он трое суток беспрерывно "стучит". Мы не сможем "запомнить все". Только "то что влезет в массив".
Вообщем почитайте какой-нибудь учебник по C/C++ про массивы и for и т.п. Явно этого не хватает (хотя-бы из попыток писать pass[1],pass[2],pass[3] и т.п.)
В Ваш код не вникал, сейчас посмотрю, меня смущает ваш processing и мышка, я не работал с этим.
Принимайте эстафету ;)
Плюс я так и не понял как записать "ввод" в массив.(Намек на то , чтобы объяснили :))
а тут все просто
вы рождаете тире в проге или точку
обнесите эту прогу циклом формирующим массив точек и тире
и придумайте как выходить из этого цикла ..ну скажем такое длинное длинное тире
в посте #47 великолепный выход из цикла, все остальные сигналы
38
if
(i<30||i>250&&i<280||i>420){
// все остальные сигналы
в посте #47 великолепный выход из цикла, все остальные сигналы
38
if
(i<30||i>250&&i<280||i>420){
// все остальные сигналы
Спасибо))
leshak, вставил ваш код.
Короче не работет. Поставил чтобы показывалось состояние door, так вот, при вводе первого правильного знака пароля door становится равным 1,но через цикл 0 и опять 1, то есть как-бы чередуется door=1 door=0. После ввода второго знака door становится равным 0 постоянно пока не введу первый знак эталонного пароля.
Может нужно впихнуть в if (b),то есть когда кнопка отпускается?.
Заработало)
Можно ли отрывок кода отвечающий за "коридор" записать с for?
Попробовал с for. В чем ошибка ?))
Добавил чтобы при большом интервале(межди нажатиями) сбрасывалась door.
Так готово или есть над чем поработать?
Попробовал с for. В чем ошибка ?))
Как минимум в условии door<=MaximumDoors. Нумерация массиова-то с нуля. Значит какой у нас максимально допустимый индекс при 6-ти дверях? Вообщем door<MaximumDoors
Во вторых. А вы пытались сами, в голове выполнить этот цикл? Ну вот пришли вы к нему, с каким-то значение в pressType. Давайте, крутите цикл в голов, сделали первый проход, сравнили введеное с door[0], пошли делать второй проход цикла, сравнили door[1]. А с чем сравнили-то? Ведь повторого чтения от пользователя вы не делали :( Сравнили-то опять тоже самое нажатие.
То есть вы от пользователя разспознали одно нажатие и пошли сравнивать его со всеми элементами pass[]. Пройти этот цикл "до конца" можно только в одном случае. Если весль пароль состоит из одних 1, или весь из 2.
После того как "прошли дверь", нужно ведь опять, начать опрашивать кнопки, выяснть что пользователь нажмет для второй двери и т.п.
Так готово или есть над чем поработать?
ну смотря что понимать под готово :)
Если "готово==работает" - то ответ "нет". Это вы и без меня могли-бы ответить, это я вас должен спрашивать работает-ли оно:)
Вы верно проверили давно-ли небыло нажатий. И что по этому поводу делать (если забыть зачем вы тут вообще вводили переменную m да еще так далеко от использования. Что-бы враги не догадались? Да и переменную interval вводить было не обязательно. Можно было сразу if(millis()-b>2500)... писать.).
Ну да ладно. Можно и c m,interval .
Только вот где вы делалаете проверку "давно не нажимали" (вернее вы сделали "давно не отпускали")? Внутри ветки, куда процессор попадает только если пользователь правильно ввел очередное нажатие.
То есть этот "сброс по timeout" у вас будет рабтоать только в случае "мы вводим правильный код оче-е--н--н-ь медд-дд-дд-леее-нн-оооо".
Вот там где вы сам interval вычисляет, почему там сразу и "проверку/сброс" не сделать? Не отходя от касссы?
да с m=millis() тупанул)), щас попробую с остальным разобраться
Вы имеете в виду поместить
в конец? Он там не работает)
Вы имеете в виду поместить
в конец? Он там не работает)
А должно. Возможно не в тот конец вставили :)
Кстати, когда эта часть стояла в том месте куда я поставил все отлично работало. То есть, даже если моя нога ночью набирает верно первые 1,2,1,2, но до следующего касания ждет больше 2.5 сек,то door сбрасывается. Не очень понял насчет очень медленного ввода, ведь первые знаки были введены быстро)