У меня кнопка (обычный выключатель) подключена к ардуино на расстоянии 15м. При этом в выключенном состоянии выключателя идут наводки (мк то включит свет, то выключит). Подтягивающий резистр стоит правда на 4.7МОм. (лень было выпаивать, проверил на коротком хвосте - все работает)
Подскажите, необходимо уменьшить номинал резистора или на таком расстоянии это в принципе не воможно. Какой номинал посоветуете. Кабель использую КСПВ 4х0,5.
чем меньше номинал резистора - тем больше помехоустойчивость , но и больше ток питания
номинал - не менее 5 V / 40 mA = 125 Om
т.е. - 150 Om .... 30 kOm
чем меньше номинал резистора - тем больше помехоустойчивость , но и больше ток питания
номинал - не менее 5 V / 40 mA = 125 Om
т.е. - 150 Om .... 30 kOm
поставил 510 Ом, теперь ситуация обратная, выключение кнопки отрабатывает правильно, а при включении свет моргает, как будто МК считает, что на входе пина LOW-сигнал. Попробую увеличить сопротивление
чем меньше номинал резистора - тем больше помехоустойчивость , но и больше ток питания
номинал - не менее 5 V / 40 mA = 125 Om
т.е. - 150 Om .... 30 kOm
поставил 510 Ом, теперь ситуация обратная, выключение кнопки отрабатывает правильно, а при включении свет моргает, как будто МК считает, что на входе пина LOW-сигнал. Попробую увеличить сопротивление
я не рекомендовал , я предположил..... теория , блин....
опытным путём всё прояснится...
Хочу вставить свои пять копеек по работе с кнопками.
Ситуация такая, у меня проект освещения содержит диммер, соответственно в скетче используются прерывания (детектор нуля). При подключении кнопок и стандартном обращении в основном цикле
buttonState1 = digitalRead(buttonPin1);
из-за частых прерываний иногда возникает еффект "дребезга", то есть неправильного определения состояния кнопки, что приводит к ложным срабатываниям МК (мигание света, преключение режимов). Все озвученные примеры не спасают от такого вида дребезга, так как расчитаны на простую задержку на время переходного периода при нажатии на кнопку.
Вот выкладываю кусок кода с настоящим антидребезгом. Идея в том, что через заданный промежуток времени необходимо провести повторное измерение состояния кнопки и сравнить с первичным для принятия решения.
void CheckButtons()
{
buttonState1 = digitalRead(buttonPin1);
if (sob>0){
if (millis()-CurrentMillis1>500){
if (sob==1 && buttonState1 == HIGH && prevState1==0){
prevState1=buttonState1;
CheckRC(15); //действия
}
else if (sob==2 && buttonState1 == LOW && prevState1==1){
prevState1=buttonState1;
CheckRC(13); //действия
}
sob=0;
}
}
else {
if (buttonState1 == HIGH && prevState1==0){
sob=1;
CurrentMillis1=millis();
}
else if (buttonState1 == LOW && prevState1==1){
sob=2;
CurrentMillis1=millis();
}
}
}
код немного черезспину на коленке сделанный, можно причесать, чтобы красиво было. Вдруг кому пригодится.
Нажал-Отпустил кнопку UP или Down мотор должен крутиться 10 секунд или пока не не сработает датчик тока.
Но в тот момент поа крутиться мотор при нажатие кнопки противоположного действия. Мотор должен остановиться, а принажатие кнопки того же напровления должен крутиться но только пока кнопка нажата или не сработает датчик тока.
Когда мотор стоит если нажать на кнопку и держать мотор должен крутиться только это промежуток времени.
long pMillis = 0;
int val = 0;
int button = 0;
int crashload = 0;
int Up = 2;
int Down = 3;
void setup()
{
pinMode(Up, OUTPUT);
pinMode(Down, OUTPUT);
pinMode(12, OUTPUT);
}
void loop()
{
MSTART:
{
button = analogRead(A0); //считываем сигнал с кнопок
crashload = analogRead(A1); //считываем сигнал превышения тока двигателем
if (crashload > 36) {goto MSTOP;}
if (button > 690 && button < 700 ) {delay (250); goto AUTOUP;}//нажатие кнопки Up
if (button > 785 && button < 795) {delay (250); goto AUTODOWN;} //нажатие кнопки Down
if (button > 860 && button < 870 || button < 100) {goto MSTOP;}// Страховка от нажатия 2 кнопок
else goto MSTOP;
}
AUTOUP:
{
for (int y=0; y<=60; y++)
{
for (int x=0; x<=500; x++)
{
digitalWrite(Up, HIGH);
digitalWrite(Down, LOW);
button = analogRead(A0); //считываем сигнал с кнопок
crashload = analogRead(A1); //считываем сигнал превышения тока двигателем
if (button >785 && button <795) {delay (250); goto MSTOP;}
if (button > 690 && button < 700 ){delay (250); goto UP;}
if (crashload > 36) {goto MSTOP;}
}
}
goto MSTART;
}
return;
AUTODOWN:
{
for (int y=0; y<=100; y++)
{
for (int x=0; x<=5000; x++)
{
digitalWrite(Up, LOW);
digitalWrite(Down, HIGH);
button = analogRead(A0); //считываем сигнал с кнопок
crashload = analogRead(A1); //считываем сигнал превышения тока двигателем
if (button >785 && button <795) {delay (250); goto DOWN;}
if (button > 690 && button < 700 ){delay (250); goto MSTOP;}
if (crashload > 36) {goto MSTOP;}
}
}
goto MSTART;
}
UP:
{
button = analogRead(A0); //считываем сигнал с кнопок
crashload = analogRead(A1); //считываем сигнал превышения тока двигателем
digitalWrite(Up, HIGH);
digitalWrite(Down, LOW);
if (button > 690 && button < 700)
{
if (crashload > 36) {goto MSTOP;}
goto UP;
}
else goto MSTOP;
}
DOWN:
{
button = analogRead(A0); //считываем сигнал с кнопок
crashload = analogRead(A1); //считываем сигнал превышения тока двигателем
digitalWrite(Up, LOW);
digitalWrite(Down, HIGH);
if (button > 785 && button < 795)
{
if (crashload > 36) {goto MSTOP;}
goto DOWN;
}
else goto MSTOP;
}
MSTOP:
{
digitalWrite(Up, LOW);
digitalWrite(Down, LOW);
}
goto MSTART;
}
Даработал немного код в протеусе работает. Но хотелось услышать мнение специалистов все ли я правельно написал, правельные операторы применил. Может это все можно написать через другой код
Тоесть при нажатие кнопок UP и DOWN переход происходит на autoUP и autoDown . И в этих функциях происходит только цикл по for , а не одно if не выполняеться кроме crashload на выходе светодиод моргает пока держишь кнопку и длиться чикл.
Буду рад любым разьяснениям. Сам только учусь програмировать. А учитель у меня только один это ИНТЕРНЕТ.
Здравствуйте, подскажите пожалуйста каким образом сделать переключение экрана не просто по нажатию кнопки а чтоб переключение осуществлялось после удерживания кнопки не меньше 1 секунды (для избежания ложного переключения при просто нажатии) ???
if (digitalRead(nextPin)== HIGH)
{
m++;//увеличиваем переменную уровня меню
previousMillis = currentMillis;
if (m>6)//если уровень больше 3
{
m=0;// то вернуться к началу
}
}
boolean f_nextPin = 0; //фЛАГ кнопки
unsigned long previousMillis = 0;
#define nextPin 7//Порт подключения кнопки
int m = 0;
void setup()
{
pinMode(nextPin, INPUT);
}
void loop() {
if (digitalRead(nextPin) == HIGH && f_nextPin == 0)//Фиксируем нажатие и запоминаем время
{
previousMillis = millis();
f_nextPin = 1;
}
else if (digitalRead(nextPin) == LOW) { //Если отпустили кнопку - сбрасуем флаг
f_nextPin = 0;
}
if (f_nextPin == 1 && millis() - previousMillis >= 1000)//Проверяем нажата ли кнопка и прошла ли секунда
{
m++;//увеличиваем переменную уровня меню
f_nextPin = 0;// и сбрасуем флаг
if (m > 3) //если уровень больше 3
{
m = 0; // то вернуться к началу
}
}
}
Здравствуйте. Хочу сделать так, чтобы по нажатию кнопки мелодия заиграла циклично, а после повторного нажатия - прекратила играть. С возможностью переделать в дальнейшем в следующие действия: нажал первый раз кнопку - заиграла первая мелодия циклично, нажал второй раз кнопку - вторая мелодия циклично, нажал третий раз - все остановилось. Arduino начал только изучать, и вообще, программирование только в школе изучал. Но почитав неделю форумы, собрал скетч из разных постов:
#include "pitches.h"
int regim=1;
int flag=0;
int melody[] = {NOTE_G4, NOTE_FS4, NOTE_G4, NOTE_FS4, NOTE_G4, NOTE_D4, NOTE_F4, NOTE_DS4, NOTE_C4, 0, NOTE_DS3, NOTE_G3, NOTE_C4, NOTE_D4, 0, NOTE_G3, NOTE_B3, NOTE_D4, NOTE_DS4, 0, NOTE_G3, NOTE_G4, NOTE_FS4, NOTE_G4, NOTE_FS4, NOTE_G4, NOTE_D4, NOTE_F4, NOTE_DS4, NOTE_C4, 0, NOTE_DS3, NOTE_G3, NOTE_C4, NOTE_D4, 0, NOTE_G3, NOTE_DS4, NOTE_D4, NOTE_C4};
int noteDurations[] = {8, 8, 8, 8, 8, 8, 8, 8, 4, 8, 8, 8, 8, 4, 8, 8, 8, 8, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, 8, 8, 8, 4, 8, 8, 8, 8, 4};
long previousMillis = 0;
void play(int melody[],int noteDurations[],int msize, int slow)
{
for (int thisNote = 0; thisNote < msize; thisNote++)
{
int noteDuration = 1000 / noteDurations[thisNote];
tone(9, melody[thisNote], noteDuration);
int pauseBetweenNotes = noteDuration * slow;
delay(pauseBetweenNotes);
noTone(9);
}
}
void setup()
{
pinMode(9,OUTPUT);
}
void loop()
{
if(digitalRead(14)==HIGH&&flag==0)//если кнопка нажата и перемення flag равна 0 , то ...
{
if (millis() -previousMillis >100) //то ждем 100мс для
{
previousMillis = millis();
regim++;
flag=1;
}
if(regim>2)//ограничим количество режимов
{
regim=1;//так как мы используем только одну кнопку, то переключать режимы будем циклично
}
}
if(digitalRead(14)==LOW&&flag==1)//если кнопка НЕ нажата и переменная flag равна - 1 ,то ...
{
if (millis() -previousMillis >100) //то ждем 100мс для
{
previousMillis = millis(); //отсечки дребезга контактов
flag=0;//обнуляем переменную "knopka"
}
}
if(regim==1)//первый режим
{
noTone(9);
}
if(regim==2)//второй режим
{
play(melody, noteDurations, 40, 2.9);
}
}
Но в итоге получается, что нажимаю кнопку - мелодия играет, второй раз нажимаю - она не останавливается. Если нажимать кнопку многократно, то в какой-то момент она срабатывает и мелодия останавливается, но только когда доиграет до последней ноты. Подскажите, как сделать так, чтобы после повторного нажатия мелодия останавливалась сразу или сразу играла вторая мелодия?
С миганием светодиодов все отлично отрабатывает, а с проигрыванием музыки переключение режимов тупит.
Не может ли это быть связано с тем, что пока выполняется tone(), сигнал с кнопки не читается, а если нажатие попадает в интервал между повторами, то мелодия играет еще раз и отключается?
Давйте посмотрим Ваш код: Когда regim==2 прграма из void loop() переходит в функцию void play() а там работает цыкл for () и пока он не закончит назад в void loop() программа не вернется, следовательно Ваше нажатие кнопок обрабатываться не будет.
Что делать? В даном случае кнопку можно поцепить на прерывание а в for () каждый раз проверять не изменился ли regim и если да то выйти из цыкла.
Добрый день. Прочитал про прерывания, после этого избавился от переменных в функции play(), повесли кнопку на pin2 для внешнего прерывания. Установил проверку в цикл for(), но самое лучшее, чего я добился, это прерывание цикла for () и запуск его с начала. Мне нужно, чтобы при нажатии кнопки прерывался не только цикл, а еще и функция play() и программа переходила в regim=1. Подскажите нубу, что мне еще дописать надо или строки поменять? Может нужно использовать оператор goto?
#include "pitches.h"
const int Pin_tone = 9; // номер порта зуммера
const byte COUNT_NOTES = 40; // Колличество нот
int regim=1;
int flag=0;
long previousMillis = 0;
//частоты ноты
int frequences[COUNT_NOTES] = {
NOTE_G4, NOTE_FS4, NOTE_G4, NOTE_FS4, NOTE_G4, NOTE_D4, NOTE_F4, NOTE_DS4, NOTE_C4, 0, NOTE_DS3, NOTE_G3, NOTE_C4, NOTE_D4, 0, NOTE_G3, NOTE_B3, NOTE_D4, NOTE_DS4, 0, NOTE_G3, NOTE_G4, NOTE_FS4, NOTE_G4, NOTE_FS4, NOTE_G4, NOTE_D4, NOTE_F4, NOTE_DS4, NOTE_C4, 0, NOTE_DS3, NOTE_G3, NOTE_C4, NOTE_D4, 0, NOTE_G3, NOTE_DS4, NOTE_D4, NOTE_C4};
//длительность нот
int durations[COUNT_NOTES] = {
125, 125, 125, 125, 125, 125, 125, 125, 250, 125, 125, 125,
125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 125,
125, 125, 125, 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 250
};
void setup() {
attachInterrupt(0, play, HIGH);
}
void play()
{
interrupts ();
for (int i = 0; i <= COUNT_NOTES; i++ ) { // Цикл от 0 до количества нот
if (regim!=2)
{break;}
else {
tone(9, frequences[i], durations [i]);
delay(durations[i] * 2); // Дауза для заданой ноты
noTone(Pin_tone); // Останавливаем звук
}
}
}
void loop() {
if(digitalRead(2)==HIGH&&flag==0)//если кнопка нажата и перемення flag равна 0 , то ...
{
if (millis() -previousMillis >100) //то ждем 100мс для
{
previousMillis = millis();
regim++;
flag=1;
}
if(regim>2)//ограничим количество режимов
{
regim=1;//так как мы используем только одну кнопку, то переключать режимы будем циклично
}
}
if(digitalRead(2)==LOW&&flag==1)//если кнопка НЕ нажата и переменная flag равна - 1 ,то ...
{
if (millis() -previousMillis >100) //то ждем 100мс для
{
previousMillis = millis(); //отсечки дребезга контактов
flag=0;//обнуляем переменную "knopka"
}
}
if(regim==1)//первый режим
{
noTone(9);
}
if(regim==2)//второй режим
{
play();
}
}
В прерывании Вы должны выполнить только regim++; Все остальное в других функциях, антидребезг-апаратно. Вы же читали что прерывание должно быть как можно короче а Вы туда мелодию поставили!
Спасибо большое за помощь, все получилось. Разобрался как привязать прерывание на другие выходы. Теперь все работает на выходе А0. По поводу антидребизга. Будет ли иметь смысл припаивать конденсаторы на плату с такими кнопками? Arduino будет вместо разрушенного "паука".
2 кнопки и 2 индикатора (светодиоды или реле не важно). При включении индикаторы выключены. При нажатии одной из кнопок в течении определенного времени (в коде это 600 циклов) соответствующий кнопке индикатор начинает мигать сначало медленнее, потом быстрее и еще быстрее (3 степени, от 0 до 200, от 200 до 400, и от 400 до 600), и по достижении установленного времени кнопка загорается и горит, даже при отпущенной кнопке. Если кнопку отпустить раньше времени- индикатор гаснет. Дальнейшее воздействие возможно только на другую кнопку, и там все аналогично, только если первый индикатор уже горит, то при нажатии на вторую кнопку он гаснет. Если "недодержать" вторую кнопку- загорается обратно. Чтото на подобие шахматных часов получается, только с удержанием.
Код прилагаю, но с ним чтото (я так подозреваю многое) не так :( Прошу помощи, это мой первый, полностью самописный код... Раньше только переделывал/ дописывал имеющийся под свои задачи.
const int buttonGreen = 4; // Задаем зеленую кнопку
const int buttonRed = 3; // Задаем красную кнопку
const int ledGreen = 12; // Задаем зеленый диод
const int ledRed = 13; // Задаем красный диод
int FlagGreen = 1; //Задаем зеленый флаг
int FlagRed = 0; //Задаем красный флаг
int Timer = 0; //Задаем таймер
int FlagTimer = 0; //Задаем таймер
int Timer2 = 0; //Задаем таймер 2
int FlagTimer2 = 0; //Задаем таймер
int buttonStateGreen = 0; // Считываем состояние зеленой кнопки
int buttonStateRed = 0; // Считываем состояние красной кнопки
void setup() {
// Инициализируем контакты под диоды как выходы:
pinMode(ledGreen, OUTPUT);
pinMode(ledRed, OUTPUT);
Serial.begin(9600);
// Инициализируем контакты под кнопки как входы:
pinMode(buttonGreen, INPUT);
pinMode(buttonRed, INPUT);
}
void loop() {
// Считываем состояние кнопок:
buttonStateGreen = digitalRead(buttonGreen);
buttonStateRed = digitalRead(buttonRed);
// Мониторим все
Serial.print(buttonStateGreen);
Serial.print(" ");
Serial.print(buttonStateRed);
Serial.print(" | ");
Serial.print(Timer);
Serial.print(" ");
Serial.print(Timer2);
Serial.print(" | ");
Serial.print(FlagTimer);
Serial.print(" ");
Serial.print(FlagTimer2);
Serial.print(" ");
Serial.print(FlagGreen);
Serial.print(" ");
Serial.println(FlagRed);
// Проверяем статус зеленой кнопки.
if (FlagGreen == 0 && buttonStateGreen == LOW) { // Если кнопка нажата (Инвертируем, т.к. кнопка у меня на размыкание) И если зеленый диод не горит
FlagTimer = 1;
FlagTimer2 = 1;
if (FlagTimer >= 1) {
Timer ++;
}
else {
Timer = 0;
}
if (FlagTimer2 >= 1) {
Timer2 ++;
}
else {
Timer2 = 0;
}
if (Timer2 >= 600) {
FlagTimer = 0;
FlagTimer2 = 0;
if (FlagTimer >= 1) {
Timer ++;
}
else {
Timer = 0;
}
if (FlagTimer2 >= 1) {
Timer2 ++;
}
else {
Timer2 = 0;
}
FlagGreen = 1;
FlagRed = 0;
}
else if (Timer2 >= 400) {
if (Timer2 == 25) {
if (ledGreen == LOW) {
digitalWrite(ledGreen, HIGH);
Timer2 = 25;
}
else {
digitalWrite(ledGreen, LOW);
Timer2 = 0;
}
}
}
else if (Timer2 >= 200) {
if (Timer2 == 50) {
if (ledGreen == LOW) {
digitalWrite(ledGreen, HIGH);
Timer2 = 0;
}
else {
digitalWrite(ledGreen, LOW);
Timer2 = 0;
}
}
}
else if (Timer2 >= 0) {
if (Timer2 == 100) {
if (ledGreen == LOW) {
digitalWrite(ledGreen, HIGH);
Timer2 = 0;
}
else {
digitalWrite(ledGreen, LOW);
Timer2 = 0;
}
}
}
}
else if (buttonStateGreen == HIGH) {
FlagTimer = 0;
FlagTimer2 = 0;
if (FlagTimer >= 1) {
Timer ++;
}
else {
Timer = 0;
}
if (FlagTimer2 >= 1) {
Timer2 ++;
}
else {
Timer2 = 0;
}
}
// Проверяем статус красной кнопки кнопки.
if (FlagRed == 0 && buttonStateRed == LOW) { // И если зеленый диод не горит Если кнопка нажата (Инвертируем, т.к. кнопка у меня на размыкание)
FlagTimer = 1;
FlagTimer2 = 1;
if (Timer2 >= 600) {
FlagTimer = 0;
FlagTimer2 = 0;
if (FlagTimer >= 1) {
Timer ++;
}
else {
Timer = 0;
}
if (FlagTimer2 >= 1) {
Timer2 ++;
}
else {
Timer2 = 0;
}
FlagGreen = 0;
FlagRed = 1;
}
else if (Timer2 >= 400) {
if (Timer2 == 25) {
if (ledRed == LOW) {
digitalWrite(ledRed, HIGH);
Timer2 = 25;
}
else {
digitalWrite(ledRed, LOW);
Timer2 = 0;
}
}
}
else if (Timer2 >= 200) {
if (Timer2 == 50) {
if (ledRed == LOW) {
digitalWrite(ledRed, HIGH);
Timer2 = 0;
}
else {
digitalWrite(ledRed, LOW);
Timer2 = 0;
}
}
}
else if (Timer2 >= 0) {
if (Timer2 == 100) {
if (ledRed == LOW) {
digitalWrite(ledRed, HIGH);
Timer2 = 0;
}
else {
digitalWrite(ledRed, LOW);
Timer2 = 0;
}
}
}
}
else if (buttonStateRed == HIGH) {
FlagTimer = 0;
FlagTimer2 = 0;
if (FlagTimer >= 1) {
Timer ++;
}
else {
Timer = 0;
}
if (FlagTimer2 >= 1) {
Timer2 ++;
}
else {
Timer2 = 0;
}
}
//Управление светодиодами с помощью флагов
if (FlagGreen == 0) {
digitalWrite(ledGreen, LOW);
}
else if (FlagGreen == 1) {
digitalWrite(ledGreen, HIGH);
}
if (FlagRed == 0) {
digitalWrite(ledRed, LOW);
}
else if (FlagRed == 1) {
digitalWrite(ledRed, HIGH);
}
delay (1);
}
Прошу помощи в написании программы, умные люди посоветовали, но я всю голову сломал как это должно выглядеть
Во внешнемм прерывании attachinterrupt инкрементируешь ++ переменную счётчика, в главном цикле проверяешь значение, если значение больше или равно нужному количеству, записываешь на вход реле еденицу, в противном случае записываешь 0
#include <Wire.h>
unsigned long lastflash;
int RPM;
void setup() {
Serial.begin(9600); //открыть порт
attachInterrupt(0, sens, ); //подключить прерывание на 2 пин при повышении сигнала
pinMode(3, OUTPUT); //3 пин как выход
digitalWrite(3, HIGH); //подать 5 вольт на 3 пин
}
void sens() {
RPM = 60 / ((float)(micros() - lastflash) / 1000000); //расчет
lastflash = micros(); //запомнить время последнего оборота
}
void loop() {
if ((micros() - lastflash) > 1000000) { //если сигнала нет больше секунды
RPM = 0; //считаем что RPM 0
}
сенсор sens в моём случае датчик холла я так понял цеплять на 2 пин? и я не вижу переменной счётчика, куда тут её вставлять?
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
const int buttonPin = 3; // the number of the pushbutton pin
const int ledPin = 13;
int buttonState = 0;
int flag=0;
void setup()
{
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
pinMode(13, OUTPUT);
lcd.init(); // initialize the lcd
lcd.clear();
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(0,0);
}
void loop()
{
if(digitalRead(3)==HIGH&&flag==0)
{
lcd.clear();
lcd.print("altitude");
digitalWrite(13,!digitalRead(13));
flag=1;
}
if(digitalRead(3)==LOW&&flag==1)//
{
lcd.clear();
lcd.print("time");
flag=0;
}
}
Здравствуйте, я начинающий) Собираю простую метеостанцию, так вот, хочу на дисплее 1602 на одной страничке выводить информацию о температуре, давлении, на другой странице высоту, на третьей время. С выводом информации на первую страницу проблем не возникло, а вот как создать вторую страницу и последующую ума не приложу, два дня бьюсь и все бестолку((( Вообщем задача такая, после включения выводится первая страничка с информацией о погоде(у меня это страница altitude для примера), при нажатии на кнопку должна загрузиться вторая страница( у меня она называется TIME) и остаться на экране до следующего нажатия на кнопку, с которой у меня возникли проблемы. Помогите. Нужно кусок кода который я не соображу как написать как я понимаю вставить в свой скетч.Как я понимаю это элементарно, но у меня не получается...Замечу что светодиод на 13 пине работает как положено, при нажимании и отпускании загорается, при повторном нажимпнии и отпускании-тухнет.А вот страничка altitude при нажатии включается, а при отпускании не сохраняется а переключается на страницу time и так бесконечно.
По настройке не проверял но по экранам попробуйте так
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
const int buttonPin = 3; // the number of the pushbutton pin
const int ledPin = 13;
int buttonState = 0;
bool flag = 0;
int ekran = 1;
void setup()
{
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
pinMode(13, OUTPUT);
lcd.init(); // initialize the lcd
lcd.clear();
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(0, 0);
}
void loop()
{
if (digitalRead(3) == HIGH && flag == 0)
{
ekran ++;
if (ekran >= 3)ekran = 1;
flag = 1;
digitalWrite(13, !digitalRead(13));
}
if (digitalRead(3) == LOW && flag == 1) //
{
flag = 0;
}
if (ekran == 1)
{
lcd.clear();
lcd.print("altitude");
}
if (ekran == 2)
{
lcd.clear();
lcd.print("time");
}
if (ekran == 3)
{
lcd.clear();
lcd.print("?????");
}
}
#include <OneWire.h>
#include <Adafruit_BMP085.h>
#include "DHT.h"
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
Adafruit_BMP085 bmp;
#define DHTPIN 2 // what pin we're connected to
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27,16,2);
const int buttonPin = 3; // the number of the pushbutton pin
const int ledPin = 13;
int buttonState = 0;
bool flag = 0;
int ekran = 1;
void setup(void) {
sensors.begin();
Serial.begin(9600);
lcd.init(); // initialize the lcd
lcd.clear();
lcd.begin(16, 2);
lcd.backlight();
//lcd.print("Reading sensors");
dht.begin();
if (!bmp.begin()) {
Serial.println("Could not find a valid BMP085 sensor, check wiring!");
while (1) {}
}
}
void loop()
{
sensors.requestTemperatures();
float humidity;
humidity = dht.readHumidity()+10.0f;
char humF[6];
dtostrf(humidity, 2, 0, humF);
//Printing Temperature
if (digitalRead(3) == HIGH && flag == 0)
{
//lcd.clear();
lcd.print("T:");
lcd.print(bmp.readTemperature());
lcd.print((char)223);
lcd.print("C ");
lcd.print("H: ");
lcd.print(humF);
lcd.print("%");
lcd.setCursor(0,1);
lcd.print("P: ");
lcd.print(bmp.readPressure()/133.3);
lcd.print(" mmHg ");
ekran ++;
if (ekran >= 4)ekran = 1;
flag = 1;
}
if (digitalRead(3) == LOW && flag == 1) //
{
flag = 0;
}
if (ekran == 1)
{ //вывод метеоинформации
lcd.clear();
lcd.print("T:");
lcd.print(bmp.readTemperature());
lcd.print((char)223);
lcd.print("C ");
lcd.print("H:");
lcd.print(sensors.getTempCByIndex(0));
lcd.print("%");
lcd.setCursor(0,1);
lcd.print("P: ");
lcd.print(bmp.readPressure()/133.3);
lcd.print(" mmHg ");
}
if (ekran == 2)
{ //вывод температуры наружного воздуха
lcd.clear();
lcd.print("OUT TEMP ");
lcd.print(sensors.getTempCByIndex(0));
lcd.print((char)223);
lcd.print("C ");
}
if (ekran == 3)
{ //вывод влажности
lcd.clear();
lcd.print("Humidity");
lcd.print(humF);
lcd.print("%");
}
//Serial.print("Altitude = ");
//Serial.print(bmp.readAltitude());
//Serial.println(" meters");
//Serial.print("Pressure at sealevel (calculated) = ");
//Serial.print(bmp.readSealevelPressure()/133.3);
//Serial.println(" mm");
//Serial.print("Temperature = ");
//Serial.print(bmp.readTemperature());
//Serial.println(" *C");
//Serial.print("Pressure = ");
//Serial.print(bmp.readPressure()/133.3);
//Serial.println(" Pa");
//delay(500);
}
Vosara , спасибо, помогли, кое что получилось, но вот переключение страниц идет с задержкой, я так понимаю пока опросятся датчики,пока выполнятся другие команды. А мне надо чтобы переключение было моментальным, потому что хочу сделать задержеку опроса датчиков с помощью DELAY хотя бы минуту, зачем их опрашивать каждые 5 секунд, для погоды это ведь не актуально. Наверно надо делать переключение страниц с помощью оператора SWITCH, или еще как,может кто подскажет. Код прилагаю.
Привет всем,извинитеза глупый вопрос Я толко начинаю в ARDUINO, как ето эделать на две кнопки и два LED?
"Алгоритм такой. Нажали кнопку – загорелся светодиод, удерживаем кнопку – ничего не происходит (светодиод горит). Отпустили кнопку – светодиод горит.
Для того чтобы погасить светодиод нужно повторно нажать кнопку.
Т.е. нажали – горит, отпустили, нажали – не горит."
int flag=0;
void setup()
{
pinMode(13, OUTPUT);
}
void loop()
{
if(digitalRead(14)==HIGH&&flag==0)//если кнопка нажата
// и перемення flag равна 0 , то ...
{
digitalWrite(13,!digitalRead(13));
flag=1;
//это нужно для того что бы с каждым нажатием кнопки
//происходило только одно действие
// плюс защита от "дребезга" 100%
}
if(digitalRead(14)==LOW&&flag==1)//если кнопка НЕ нажата
//и переменная flag равна - 1 ,то ...
{
flag=0;//обнуляем переменную flag
}
}
// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin
// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}
void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonState == HIGH) {
// turn LED on:
digitalWrite(ledPin, HIGH);
} else {
// turn LED off:
digitalWrite(ledPin, LOW);
}
}
Доброе время суток!
Прошу помощи по кнопкам.
У меня кнопка (обычный выключатель) подключена к ардуино на расстоянии 15м. При этом в выключенном состоянии выключателя идут наводки (мк то включит свет, то выключит). Подтягивающий резистр стоит правда на 4.7МОм. (лень было выпаивать, проверил на коротком хвосте - все работает)
Подскажите, необходимо уменьшить номинал резистора или на таком расстоянии это в принципе не воможно. Какой номинал посоветуете. Кабель использую КСПВ 4х0,5.
Заранее спасибо!
Конечно, как минимум надо уменьшить номинал резистора, подбирать что-то из 4,7 кОм - 22 кОм. Резистор надеюсь возле ардуины стоит, а не возле кнопки?
чем меньше номинал резистора - тем больше помехоустойчивость , но и больше ток питания
номинал - не менее 5 V / 40 mA = 125 Om
т.е. - 150 Om .... 30 kOm
Подтягивающий резистр стоит правда на 4.7МОм. (лень было выпаивать, проверил на коротком хвосте - все работает)
обычно хватает и встроенного в МК на 20 kOm.....
digitalWrite( pin , HIGH ) , если , конечно , он настроен как вход
этот ТОЧНО будет на стороне МК :)
чем меньше номинал резистора - тем больше помехоустойчивость , но и больше ток питания
номинал - не менее 5 V / 40 mA = 125 Om
т.е. - 150 Om .... 30 kOm
поставил 510 Ом, теперь ситуация обратная, выключение кнопки отрабатывает правильно, а при включении свет моргает, как будто МК считает, что на входе пина LOW-сигнал. Попробую увеличить сопротивление
чем меньше номинал резистора - тем больше помехоустойчивость , но и больше ток питания
номинал - не менее 5 V / 40 mA = 125 Om
т.е. - 150 Om .... 30 kOm
поставил 510 Ом, теперь ситуация обратная, выключение кнопки отрабатывает правильно, а при включении свет моргает, как будто МК считает, что на входе пина LOW-сигнал. Попробую увеличить сопротивление
я не рекомендовал , я предположил..... теория , блин....
опытным путём всё прояснится...
Хочу вставить свои пять копеек по работе с кнопками.
Ситуация такая, у меня проект освещения содержит диммер, соответственно в скетче используются прерывания (детектор нуля). При подключении кнопок и стандартном обращении в основном цикле
из-за частых прерываний иногда возникает еффект "дребезга", то есть неправильного определения состояния кнопки, что приводит к ложным срабатываниям МК (мигание света, преключение режимов). Все озвученные примеры не спасают от такого вида дребезга, так как расчитаны на простую задержку на время переходного периода при нажатии на кнопку.
Вот выкладываю кусок кода с настоящим антидребезгом. Идея в том, что через заданный промежуток времени необходимо провести повторное измерение состояния кнопки и сравнить с первичным для принятия решения.
код немного черезспину на коленке сделанный, можно причесать, чтобы красиво было. Вдруг кому пригодится.
Доброго врямяни суток. Нужна помошь профисеоналов. Сам я только начал увлекаться программировованием микроконтролеров.
Я составил схемку и стараюсь написат код чтоб она заработала как надо но пока струдом получаеться
int button = 0;
Алгоритм работы такой хотелось бы
Нажал-Отпустил кнопку UP или Down мотор должен крутиться 10 секунд или пока не не сработает датчик тока.
Но в тот момент поа крутиться мотор при нажатие кнопки противоположного действия. Мотор должен остановиться, а принажатие кнопки того же напровления должен крутиться но только пока кнопка нажата или не сработает датчик тока.
Когда мотор стоит если нажать на кнопку и держать мотор должен крутиться только это промежуток времени.
Алгоритм работы такой хотелось бы...
Вы нарисуйте на бумаге блок-схему алгоритма. Так Вам легче будет программу составить. На блок-схеме логика видна гораздо лучше, чем в коде.
Даработал немного код в протеусе работает. Но хотелось услышать мнение специалистов все ли я правельно написал, правельные операторы применил. Может это все можно написать через другой код
goto замени на функции, а то сейчас вой поднимут, как за применение расово неверных операторов.
Примерно так:
Уважаемый Tomasina.
Подскажи после твоих подсказок по исправлению у меня ошибка при компиляции. Что делать и как это исправить
Народ только не пинайте.
Прошу о помоши. Не как не могу понять почему когда я написал код так:
У меня все работало, но Tomasina меня поправи и сказал что писать нужно так
и теперь работает это все на половину.
Тоесть при нажатие кнопок UP и DOWN переход происходит на autoUP и autoDown . И в этих функциях происходит только цикл по for , а не одно if не выполняеться кроме crashload на выходе светодиод моргает пока держишь кнопку и длиться чикл.
Буду рад любым разьяснениям. Сам только учусь програмировать. А учитель у меня только один это ИНТЕРНЕТ.
Так что люди добрые помогите навичку.
Ура разобрался надо было всего лиш одну строчку дописать
Здравствуйте, подскажите пожалуйста каким образом сделать переключение экрана не просто по нажатию кнопки а чтоб переключение осуществлялось после удерживания кнопки не меньше 1 секунды (для избежания ложного переключения при просто нажатии) ???
Может так понятней:
Благодарю:) но что то не разобрался еще или в коде ошибка.
вот кстати такой масив работает у меня для включение освещения? но для переключения режимов экрана не могу интегрировать.
Прокоментировал, проверил все работает
Еще один антидребезг
Здравствуйте. Хочу сделать так, чтобы по нажатию кнопки мелодия заиграла циклично, а после повторного нажатия - прекратила играть. С возможностью переделать в дальнейшем в следующие действия: нажал первый раз кнопку - заиграла первая мелодия циклично, нажал второй раз кнопку - вторая мелодия циклично, нажал третий раз - все остановилось. Arduino начал только изучать, и вообще, программирование только в школе изучал. Но почитав неделю форумы, собрал скетч из разных постов:
Но в итоге получается, что нажимаю кнопку - мелодия играет, второй раз нажимаю - она не останавливается. Если нажимать кнопку многократно, то в какой-то момент она срабатывает и мелодия останавливается, но только когда доиграет до последней ноты. Подскажите, как сделать так, чтобы после повторного нажатия мелодия останавливалась сразу или сразу играла вторая мелодия?
С миганием светодиодов все отлично отрабатывает, а с проигрыванием музыки переключение режимов тупит.
Не может ли это быть связано с тем, что пока выполняется tone(), сигнал с кнопки не читается, а если нажатие попадает в интервал между повторами, то мелодия играет еще раз и отключается?
M@X's
Давйте посмотрим Ваш код: Когда regim==2 прграма из void loop() переходит в функцию void play() а там работает цыкл for () и пока он не закончит назад в void loop() программа не вернется, следовательно Ваше нажатие кнопок обрабатываться не будет.
Добрый день. Прочитал про прерывания, после этого избавился от переменных в функции play(), повесли кнопку на pin2 для внешнего прерывания. Установил проверку в цикл for(), но самое лучшее, чего я добился, это прерывание цикла for () и запуск его с начала. Мне нужно, чтобы при нажатии кнопки прерывался не только цикл, а еще и функция play() и программа переходила в regim=1. Подскажите нубу, что мне еще дописать надо или строки поменять? Может нужно использовать оператор goto?
В прерывании Вы должны выполнить только regim++; Все остальное в других функциях, антидребезг-апаратно. Вы же читали что прерывание должно быть как можно короче а Вы туда мелодию поставили!
vosara
Спасибо большое за помощь, все получилось. Разобрался как привязать прерывание на другие выходы. Теперь все работает на выходе А0. По поводу антидребизга. Будет ли иметь смысл припаивать конденсаторы на плату с такими кнопками? Arduino будет вместо разрушенного "паука".
Если есть проблемы ставте програмный антидребезг, примерно так: В прерывании пишем
Здравствуйте, вот
Подскажите почему у меня при переключении режима когда серва меняет угол светодиод предидущего режима не гаснет а горит???
Потому что Вы включаете следующий, но не выключаете предыдущий: digitalWrite(ledХ, LOW);
Добрый день.
У меня такая задача:
2 кнопки и 2 индикатора (светодиоды или реле не важно). При включении индикаторы выключены. При нажатии одной из кнопок в течении определенного времени (в коде это 600 циклов) соответствующий кнопке индикатор начинает мигать сначало медленнее, потом быстрее и еще быстрее (3 степени, от 0 до 200, от 200 до 400, и от 400 до 600), и по достижении установленного времени кнопка загорается и горит, даже при отпущенной кнопке. Если кнопку отпустить раньше времени- индикатор гаснет. Дальнейшее воздействие возможно только на другую кнопку, и там все аналогично, только если первый индикатор уже горит, то при нажатии на вторую кнопку он гаснет. Если "недодержать" вторую кнопку- загорается обратно. Чтото на подобие шахматных часов получается, только с удержанием.
Код прилагаю, но с ним чтото (я так подозреваю многое) не так :( Прошу помощи, это мой первый, полностью самописный код... Раньше только переделывал/ дописывал имеющийся под свои задачи.
Luziy Мой код.
Всем спасибо, сам разобрался.
Хорошо что разобрались!!! Ноя всетаки я покажу Вам свой код по решению Вашей задачи, озвученой в первом посте, так как я его все равно уже написал
Прошу помощи в написании программы, умные люди посоветовали, но я всю голову сломал как это должно выглядеть
Во внешнемм прерывании attachinterrupt инкрементируешь ++ переменную счётчика, в главном цикле проверяешь значение, если значение больше или равно нужному количеству, записываешь на вход реле еденицу, в противном случае записываешь 0
ROTOR001 Смотри на этот код. А потом, как скультор убкри лишнее.
http://arduino.ru/forum/programmirovanie/takhometr-na-arduino-pro-mini-o...
сенсор sens в моём случае датчик холла я так понял цеплять на 2 пин? и я не вижу переменной счётчика, куда тут её вставлять?
Я этот код говорил
А вот код счетчиком
А вот как снимаются показания
Здравствуйте, я начинающий) Собираю простую метеостанцию, так вот, хочу на дисплее 1602 на одной страничке выводить информацию о температуре, давлении, на другой странице высоту, на третьей время. С выводом информации на первую страницу проблем не возникло, а вот как создать вторую страницу и последующую ума не приложу, два дня бьюсь и все бестолку((( Вообщем задача такая, после включения выводится первая страничка с информацией о погоде(у меня это страница altitude для примера), при нажатии на кнопку должна загрузиться вторая страница( у меня она называется TIME) и остаться на экране до следующего нажатия на кнопку, с которой у меня возникли проблемы. Помогите. Нужно кусок кода который я не соображу как написать как я понимаю вставить в свой скетч.Как я понимаю это элементарно, но у меня не получается...Замечу что светодиод на 13 пине работает как положено, при нажимании и отпускании загорается, при повторном нажимпнии и отпускании-тухнет.А вот страничка altitude при нажатии включается, а при отпускании не сохраняется а переключается на страницу time и так бесконечно.
По настройке не проверял но по экранам попробуйте так
Vosara , спасибо, помогли, кое что получилось, но вот переключение страниц идет с задержкой, я так понимаю пока опросятся датчики,пока выполнятся другие команды. А мне надо чтобы переключение было моментальным, потому что хочу сделать задержеку опроса датчиков с помощью DELAY хотя бы минуту, зачем их опрашивать каждые 5 секунд, для погоды это ведь не актуально. Наверно надо делать переключение страниц с помощью оператора SWITCH, или еще как,может кто подскажет. Код прилагаю.
Привет всем, извините за глупый вопрос Я толко начинаю в ARDUINO, как ето эделать на две кнопки и два LED?
"Алгоритм такой. Нажали кнопку – загорелся светодиод, удерживаем кнопку – ничего не происходит (светодиод горит). Отпустили кнопку – светодиод горит.
Для того чтобы погасить светодиод нужно повторно нажать кнопку.
Т.е. нажали – горит, отпустили, нажали – не горит."
Sigla Код такой . Но не для начинающего.
Что не так? :(
хотелось чтобы включилось реле и лед мигал.
Могу дать код для продвинутых.
Спасибо! Вы профессионал ...
Нужно простой код. Есть кнопка нажали сработало реле. отпустили реле выключилось. Сколько держим столько реле и включено.
код мой ниже, но не всегда правильно работает. Заранее спасибо за помощь.
ПС: Sigla Хороший индийский код у вас.