Пьезопищалка и светодиод
- Войдите на сайт для отправки комментариев
Чт, 10/08/2017 - 11:58
Всем привет. Как и многие болбесы задающие вопросы на форумах новички в Arduino я тоже не исключение и прошу помочь. Написал небольшой код для NAno все вроде фунциклирует но светодиод не мигает при выполнение скетча. Он просто загорается при выполнение кода, НО не мигает. Пьезо пишалка при этом работает нормально. Если закомментировать блок пишалки светодиод начинает мигать. Пьезо пишалка пассивная и подключена напрямую к цифровому пину.
const int button1 = A4;
const int button2 = A5;
const int led1 = 9;
const int pic1 = 6;
void setup()
{
pinMode (A4,INPUT_PULLUP);
pinMode (A5,INPUT_PULLUP);
pinMode (led1,OUTPUT);
pinMode (pic1,OUTPUT);
}
void loop()
{
boolean button1 = !digitalRead(A4);
boolean button2 = !digitalRead(A5);
if (button1 == 1 || button2 == 1) {
millis_led1();
pic();
}
else {
digitalWrite(led1,0);
}
}
void millis_led1() {
if (round(millis() /500)% 2 ==0)
digitalWrite(led1,HIGH);
else
digitalWrite(led1,LOW);
}
void pic() {
tone (pic1, 600);
delay(1000);
tone(pic1, 900);
delay(1000);
noTone(pic1);
delay(5000);
}
совсем не мигает? - должен мигать, но совсем не с той частотой, что вы ожидаете... думаю, где-то раз в 20-30 секунд должен переключаться...
Пьезо пишалка пассивная и подключена напрямую к цифровому пину.
Замерьте ток - у многих пищалок ток превосходит то, что допустимо для пина.
Он просто загорается при выполнение кода, НО не мигает.
Вы всерьёз ожидаете, что светодиод будет мигать каждые полсекунды, когда в функции pic у Вас делэев на целых 7 секунд? Пока не избавитесь от делэев мигать ничего не будет.
Что делает round в строке 34? Его аргумент должен быть плавающим, Вы же подсовываете ему целое число. Зачем его округлять, когда оно и так целое? Кроме того, результат функции round тоже плавающее число типа double. Вы в курсе как плавающие числа относятся к операции взятия отстатка от деления? Не то, чтобы это было как-то критично, но весьма странно выглядит.
думаю, где-то раз в 20-30 секунд должен переключаться...
Это как повезёт. Если делэи "синхронизируются" с проверкой в строке 34, то может и не переключаться, а всегда только включаться. Там же не инвертирование стоит, а разедльно включение и выключение.
Это как повезёт. Если делэи "синхронизируются" с проверкой в строке 34
именно поэтому я написал 20-30 секунд, а не 7... период будет хаотичным... может так "совпасть". что и вообще залипнет в одном состоянии
совсем не мигает? - должен мигать, но совсем не с той частотой, что вы ожидаете... думаю, где-то раз в 20-30 секунд должен переключаться...
совсем не мигает даже по истечению 30 секунд
Вы всерьёз ожидаете, что светодиод будет мигать каждые полсекунды, когда в функции pic у Вас делэев на целых 7 секунд? Пока не избавитесь от делэев мигать ничего не будет.
спасибо. попробую разобраться с этим куском кода. если не получится вернусь опять вам мозг кушать
пока пришел к данному варианту.
const int button1 = A4; const int button2 = A5; const int led1 = 9; const int pic1 = 6; void setup() { pinMode (A4,INPUT_PULLUP); pinMode (A5,INPUT_PULLUP); pinMode (led1,OUTPUT); pinMode (pic1,OUTPUT); } void loop() { boolean button1 = !digitalRead(A4); boolean button2 = !digitalRead(A5); if (button1 == 1 || button2 == 1) { millis_led1(); pic(); } else { digitalWrite(led1,0); } } void millis_led1() { if (round(millis() /500)% 2 ==0) digitalWrite(led1,HIGH); else digitalWrite(led1,LOW); } void pic() { tone (pic1, 600,1000); }буду дальше разбираться
1. что бы пишалка пиликала а не просто пишала. как я понял delay зло )))
2. по вашему совету поробую применить др функцию для светодиода
последний вопрос(измерить напряжение на пишалке пока не удалось) нужно ли ставить конденсатор на 1 мкФ на управляюший пин пишалки?
В обшем спасибо что указали на косяки в коде.
В итоге получилось следуюшие
const int button1 = A4; const int button2 = A5; const int led1 = 9; const int pic1 = 6; void setup() { pinMode (A4,INPUT_PULLUP); pinMode (A5,INPUT_PULLUP); pinMode (led1,OUTPUT); pinMode (pic1,OUTPUT); } void loop() { boolean button1 = !digitalRead(A4); boolean button2 = !digitalRead(A5); if (button1 == 1 || button2 == 1) { millis_led1(); pic(); } else { digitalWrite(led1,0); } } void millis_led1() { if ( (millis() /1000)% 2 ==0) digitalWrite(led1,HIGH); else digitalWrite(led1,LOW); } void pic() { if ( (millis() /500)% 2 ==0) tone (pic1, 600,100); else noTone(pic1); }Все мигает и пишит как и планировалось.без задержек. если есть еше советы или косяки буду рад выслушать. вопрос по конденсатору открыт. Спасибо
на присторах интернета каждый второй ардуиньшик советует вот и интересуюсь. Пишут что пин может погореть.
на присторах интернета каждый второй ардуиньшик советует вот и интересуюсь. Пишут что пин может погореть.
Ну, я видимо нечётный - не второй, а второй+1. Чтобы с пином ничего не случилось, ограничьте ток до 20мА в пике.
на присторах интернета каждый второй ардуиньшик советует вот и интересуюсь. Пишут что пин может погореть.
Ну, я видимо нечётный - не второй, а второй+1. Чтобы с пином ничего не случилось, ограничьте ток до 20мА в пике.
Спасибо. Буду дальше учится, хоть хобби нормальное и физику вспомню, а то в танки надоело играть )))))
То, что глобальные константы и локальные переменные названы одинаково, разве не вызывает ошибки компиляции?
вы просили еще советы... ну так держите.
Хоть вы и добились. что светик теперь у вас мигает правильно - это не отменяет того, что алгоритм отсчета времени у вас неверный. Я имею в виду вот этот код:
void millis_led1() { if ( (millis() /1000)% 2 ==0) digitalWrite(led1,HIGH); else digitalWrite(led1,LOW); }Приведу такой пример: допустим, вы хотите сварить яйцо. Положили в воду, поставили на огонь, дождались пока закипит - дальше надо заметить 30 секунд. На часах 14:25:15 - значит выключим плиту, когда будет больше 45 секунд. В следующий раз вы посмотрели на часы. допустим, в 14:26:04. Пора выключать или нет? - с человеческой точки зрения - несомненно. Но с точки зрения компьютера - рано, ведь вы сформулировали условие как " если число секунд больше 45".
Так вот, ваши выкрутасы с делением millis() на тысячу и взятием целой-дробной части - ровно то же самое, как учитывать на часах только секунды. Этот код переключит светик, если прошло от 500 до 1000мс, однако не станет переключать, если программа почему-то притормозила и дотянула до секунды. То есть, в принципе, глюк с отсчетом времени, который не давал переключаться светодиоду в самом первом скетче - никуда не делся, вы его не устранили, а просто замаскировали.
Нормальный, общепринятый подход к измерению интервалов в программе - точно такой же, как "человеческий" метод в примере с варкой яйца - необходимо заметить начало интервала. а потом вычитать это время из текущего.
То, что глобальные константы и локальные переменные названы одинаково, разве не вызывает ошибки компиляции?
Ошибки компиляции не будет.
То, что глобальные константы и локальные переменные названы одинаково, разве не вызывает ошибки компиляции?
а должны? Это называется "область действия" - локальные переменные во вложенном блоке маскируют одноименные переменные внешних блоков (в том числе глобальные). Для компилятора это совершенно разные переменные.
однако не станет переключать, если программа почему-то притормозила и дотянула до секунды.
необходимо заметить начало интервала. а потом вычитать это время из текущего.
и, как ты заметишь начало интервала, если у тебя периодически секундные лаги?
Т. е. при наличии локальной переменной к глобальной переменной с тем же именем обратиться нельзя. Спасибо за разъяснение!
Т. е. при наличии локальной переменной к глобальной переменной с тем же именем обратиться нельзя. Спасибо за разъяснение!
да, и значение глобальной переменной при этом не портится, просто становится недоступным. После выхода программы из области действия локальной переменной глобальная восстанавливается. Можно даже сделать вот такой изврат - проверил, компилируется и правильно печатает значения :)
for (int i =0; i<3;i++) { for (int i =0; i<3;i++) { for (int i =0; i<3;i++) { printf("innest i %d\n", i); } printf("medium i %d\n", i); } printf("outer i %d\n", i); }глобальная восстанавливается.
откуда восстанавливается?
глобальная восстанавливается.
откуда восстанавливается?
" - из толстых кошельков моя деточка" (с)
Клапа. не мешай. я с детьми разговариваю
Клапа. не мешай. я с детьми разговариваю
ну, как не мешай?
что ты советуешь и как аргументируешь?
с какого перепуга у тебя программы превращают контроллер на секунду в кирпич так, что
if(round(ты заюзать не можешь, а начало интервала - можешь?if(round(millis() /500)% 2 ==0)/500)% 2 ==0)нафиг ТС начало интервала? - у тего тупая мигалко и у него начало интервала
millis() == 0про локальные и глобальные переменные - тоже какая-то шняга. то нет, то восстанавливаются - откуда восстанавливаются?
то есть непонарошку спрашиваешь? :) - ну давай
1. Про время. Понятно, что если loop делает оборот дольше, чем период мигалки - нормальной работы не будет ни с тем, ни с другим кодом. Но разница все же есть. При традиционном взятии интервала типа
(Old_millis - millis()) > interval
мигалка будет мигать не реже, чем длина цикла loop плюс интервал. По методу ТС - как повезет, может не мигать вообще, как мы видели в первом скетче.
2. Про переменные - согласен, неправильно формулирую. Правильно будет не "восстанавливаются", а "становятся доступны". так согласен?
1. Про время. Понятно, что если loop делает оборот дольше, чем период мигалки - нормальной работы не будет ни с тем, ни с другим кодом.
ок.
но далее противоречишь сам себе - цитирую тебя же: "нормальной работы не будет ни с тем, ни с другим кодом".
(Old_millis - millis()) > interval
мигалка будет мигать не реже, чем длина цикла loop плюс интервал.
когда продолжительность цикла loop более interval - мигать не будет, т.к. всегда будет Old_millis - millis()) > interval
2. Про переменные - согласен, неправильно формулирую. Правильно будет не "восстанавливаются", а "становятся доступны". так согласен?
перечитай [С++ область видимости]
когда продолжительность цикла loop более interval - мигать не будет, т.к. всегда будет Old_millis - millis()) > interval
Не понимаю. Почему не будет? Условие будет истинным после каждого оборота loop - значит после каждого оборота и будет переключаться. Поянтно, что переключать надо инвертированием, а не как ТС
перечитай [С++ область видимости]
ок, перечитаю. Но сдается мне, спор идет о терминологии, а не о сути. В терминах я не силен, так как никогда не изучал программирование в теории
Не понимаю. Почему не будет? Условие будет истинным после каждого оборота loop - значит после каждого оборота и будет переключаться. Поянтно, что переключать надо инвертированием, а не как ТС
ага. будет переключаться, но не в соответсвии interval, а больше.
и нафиг такакое нуно?
и аргументируешь ты это всё исключительно брошенными тобой в тред граблями, что луп у тебя аж секунда.
бросай тогда в луп digitalWrite(13, !digitalRead(13));
про область видимости.
Перечитал. Каждое имя переменной разрешается, начиная от локального пространства имен, а если в ближайшем пространстве имен такого нет - то во все более широких, вплоть до глобального. Поэтому если у нас есть локальная и глобальная переменная с одинм именем, то внутри локального пространства имен это имя будет давать доступ к локальной переменной, а при выходе из области действия - к глобальной переменной.
И что я не так сказал? внутри области действия локальная переменная маскирует глобальную, а при выходе глобальная становится доступна.
И что я не так сказал?
После выхода программы из области действия локальной переменной глобальная восстанавливается. Можно даже сделать вот такой изврат
не востанавливается, т.к. не уничтожается.
и твой пример не изврат
Становяца видимыми одни, и уходют в небытие другие, более локальные.
уходют в небытие другие
аха... попадают в АдЪ
уходют в небытие другие
аха... попадают в АдЪ
Это, в зависимости от содержимаго.
То, что глобальные константы и локальные переменные названы одинаково, разве не вызывает ошибки компиляции?
С чего бы? Почитайте вот здесь про экранирование переменных. Там и примеры есть.
Т. е. при наличии локальной переменной к глобальной переменной с тем же именем обратиться нельзя. Спасибо за разъяснение!
Ну, прямо так сразу и нельзя. Уметь просто надо.
Хоть вы и добились. что светик теперь у вас мигает правильно - это не отменяет того, что алгоритм отсчета времени у вас неверный. Я имею в виду вот этот код:
void millis_led1() { if ( (millis() /1000)% 2 ==0) digitalWrite(led1,HIGH); else digitalWrite(led1,LOW); }Приведу такой пример: допустим, вы хотите сварить яйцо. Положили в воду, поставили на огонь, дождались пока закипит - дальше надо заметить 30 секунд. На часах 14:25:15 - значит выключим плиту, когда будет больше 45 секунд. В следующий раз вы посмотрели на часы. допустим, в 14:26:04. Пора выключать или нет? - с человеческой точки зрения - несомненно. Но с точки зрения компьютера - рано, ведь вы сформулировали условие как " если число секунд больше 45".
Вот теперь правильно варю )))
const byte button1 = A4; const byte button2 = A5; const byte led_pin1 = 9; const byte pic1 = 6; const int interval_led_pin1 =2000; unsigned long time_millis; void setup() { pinMode (A4,INPUT_PULLUP); pinMode (A5,INPUT_PULLUP); pinMode (led_pin1,OUTPUT); pinMode (pic1,OUTPUT); } void loop() { boolean button1 = !digitalRead(A4); boolean button2 = !digitalRead(A5); if (button1 == 1 || button2 == 1) { millis_led1(); pic(); } else { digitalWrite(led_pin1,0); } } void millis_led1() { if(millis()-time_millis > interval_led_pin1) { time_millis = millis(); digitalWrite(led_pin1,!digitalRead(led_pin1)); } } void pic() { if ( (millis() /2000)% 2 ==0){ tone (pic1, 600,500); } else { noTone(pic1); } }как понимаю для пишалки код можно оставить таким же или тоже косяки ?