Ви не увійшли.
Сторінки 1
currentState=digitalRead(button); //Считываем состояние кнопки
if (currentState == 0 && prevState == 1 &&(millis()-debounceTime)>50) //Антидребезг
{
prevState=0;
++flag; //Инкрементируем флаг
if (flag>=3) flag=0; //Устраняем перегруженость
prevContact = digitalRead(contact); //Считываем текущее состояние контакта
debounceTime=millis(); //Записываем значение времени для антидребезга
}
else if (currentState == 1 && prevState == 0 &&(millis()-debounceTime)>5) //При отпускании кнопки
{
prevState=1; //меняем предыдущее состояние
}
Вот кусок кода, который обрабатывает нажатие кнопки.
С ним у меня проблемы, но я нашел альтернативный код, а именно:
bool reading = digitalRead (button);
if (reading != lastButton) lastDebounce = millis();
if ((millis()-lastDebounce) > debounceDelay)
{
if (reading != buttonState)
{
buttonState = reading;
if (buttonState == LOW)
{
++flag;
if (flag >= 3) flag = 0;
prevContact = digitalRead (contact);
}
}
}
lastButton = reading;
И вот с ним то все работает. Но я не могу понять в чем ошибка первого обработчика и почему он у меня все же работал, но после того как я ушел от использования delay в блоке кода отображения чисел на индикаторе то начал проскакивать дребезг.
И куда поцепить конденсатор? Паралельно кнопке?
Кнопка подключена к выводу А1.
Может хоть подскажите где ошибка?
Вот схема, если это поможет.
Я знаю что код - говнище. Это мой первый хоть сколько серьёзный проект. Подскажите по оформлению - нормально ли что 90% кода - это вызов функции "if"?
Здравствуйте.
Такая проблема, делаю таймер с тремя условиями остановки. По внешнему контакту, по истечению времени и по кнопке.
Кнопку я использую и для пуска, и для остановки, и для сброса таймера. Проблема в том что я не могу нормально реализовать антидребезг, часто проскакивает несколько нажатий. Использую внешнюю подтяжку на 5кОм.
Помогите, скажите где ошибка.
Вот скетч
#define secOne 11 //Порт управления младшего розряда индикатора секунд
#define secTwo 10 //Порт управления старшего розряда индикатора секунд
#define minOne 12 //Порт управления молодшим розрядом индикатора минут
#define minTwo 13 //Порт управления старшим розрядом индикатора минут
#define segG 8 //Вывод ручного управления сегментом G
#define segDP 9 //Вивод ручного управления точкой
#define divider A0 //Разделитель разрядов
#define rele A3 //Виход на реле
#define button A1 //Вход для кнопки
#define contact A2 //Вход для контакта
byte numbersArray[]={ //Массив управления портом D для отображения чисел на индикаторе
0x00, //0
0x9C, //1
0x24, //2
0x0C, //3
0x98, //4
0x48, //5
0x40, //6
0x1C, //7
0x00, //8
0x08 //9
};
byte segmentsPos[] = {secOne, secTwo, minOne, minTwo}; //Массив для хранения
//виводов управления сегментами
unsigned long prevTime=0; //Переменная для хранения предыдущего значения millis()
//для подсчета времени
unsigned long debounceTime=0; //Переменная времени для функции антидребезга контактов
unsigned long delaySegments=0; //Переменная для задержки отображения индикаторов
byte timeNumbers[5]; //Массив для хранения чисел для отображения
bool currentState = HIGH; //Нинешнее состояние кнопки
bool prevState = HIGH; //Предыдущее состояние кнопки
bool prevContact=HIGH; //Стабильное состояние контакта
byte flag = 0; //Флаг работы таймера
byte serviceCounter=0; //Переменная для перебора значений отображаемых индикатором
void setup()
{
DDRD=DDRD|B11111100; //Конфигурируем порт D на выход
PORTD=B11111100; //Сегменты не горят
for(byte i=0; i<=3; ++i) //Конфигурируем
{ //порты
pinMode(segmentsPos[i], OUTPUT); //для
digitalWrite(segmentsPos[i], HIGH); //работы
} //с
pinMode(segG, OUTPUT); //сегментами
pinMode(segDP, OUTPUT); //на выход
pinMode(button, INPUT_PULLUP); //Вход для кнопки
pinMode(contact, INPUT_PULLUP); //Вход для контакта
digitalWrite(segG, HIGH); //Сегменты светятся при подаче на них низкого уровня
digitalWrite(segDP, HIGH); //поскольку используються индикаторы с общим анодом
}
void loop()
{
currentState=digitalRead(button); //Считываем состояние кнопки
if (currentState == 0 && prevState == 1 &&(millis()-debounceTime)>50) //Антидребезг
{
prevState=0;
++flag; //Инкрементируем флаг
if (flag>=3) flag=0; //Устраняем перегруженость
prevContact = digitalRead(contact); //Считываем текущее состояние контакта
debounceTime=millis(); //Записываем значение времени для антидребезга
}
else if (currentState == 1 && prevState == 0 &&(millis()-debounceTime)>5) //При отпускании кнопки
{
prevState=1; //меняем предыдущее состояние
}
if (digitalRead(contact)!= prevContact) flag=3; //Остановка таймера по
//изменению состояния
//контакта
if ((millis()-prevTime)>=1000 && flag == 1) //Ожидаем прошествия секунды
{ //после запуска таймера
++timeNumbers[0]; //Инкрементируем значение секунд
prevTime=millis(); //Записываем текущее значение millis()
}
else if(flag == 0) //Сброс таймера по флагу
{
for (byte i=0; i<=4; ++i)
{ //Можно ли записать значения в массив
timeNumbers[i]=0; //без применения цыкла?
}
}
if (timeNumbers[0]==10) //Проверка перегружености
{ //счетчика единиц секунд
timeNumbers[0]=0; //Сборс
++timeNumbers[1]; //Инкрементирование десяток секунд
}
if (timeNumbers[1]==6) //Проверка перегрузки
{ //счетчика десяток секунд
timeNumbers[1]=0; //Сброс
++timeNumbers[2]; //Инкрементируем значение
} //единиц минут
if (timeNumbers[2]==10) //Проверка перегружености
{ //Счетчика единиц минут
timeNumbers[2]=0; //Сброс
++timeNumbers[3]; //Инкрементирование десяток минут
}
if (timeNumbers[3]==2 && timeNumbers[2]==5) flag=4; //Условие остановки таймера по истечению времени
if ((millis() - delaySegments)>=2) //Передача значений подпрограмме по
{ //работе с индикаторами
if(serviceCounter >= 4) serviceCounter=0; //Проверка перегружености счетчика
dispSeg(timeNumbers[serviceCounter], segmentsPos[serviceCounter], 1); //Передача значений подпрограмме
++serviceCounter; //Инкрементирование счетчика
delaySegments=millis();
}
}
void dispSeg(byte num, byte segNum, bool statDP) //Подпрограмма работы с индикатором
{
for(byte i=0; i<=3; ++i) //Гасим индикаторы
{
digitalWrite(segmentsPos[i], HIGH);
}
if (segNum != 4) //Функция if - апендицыт,который остался после попыток управления разделителем сегментов
{
PORTD=numbersArray[num]; //Подаем нужный потенциал на сегменты
if (num == 0 || num == 1 || num == 7) //Ручное управление сегментом G
{
digitalWrite(segG, HIGH);
}
else
{
digitalWrite(segG, LOW);
}
digitalWrite(segDP, statDP); //Управление точкой
digitalWrite(segNum, LOW); //Зажигаем нужный сегмент
}
}
Сторінки 1