анти дребезг

Wip85
Offline
Зарегистрирован: 24.03.2015

Ребята подскажите новичку как это читается правильно 

digitalWrite(ledOn,!digitalRead(ledOn))

Установаливае 1 ledOn не равно ledOn

Я правильно понимаю или нет?

arssev1
Offline
Зарегистрирован: 10.04.2014

Wip85 пишет:

Ребята подскажите новичку как это читается правильно

Так скинте полностью код

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

digitalWrite(ledOn,!digitalRead(ledOn))
установить на пине светодиода инвертированный уровень, считанный с пина светодиода
режим пина светодиода - OUTPUT, его нельзя считать ( читаются пины с режимом INPUT )

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

SU-27-16, Как нельзя? Да не, прочесть то можно в любом режиме . Читается  через регистр PINx, ему всё равно . Есть ещё малоизвестная фишка -можно не только читать из PINx.*, то и писать в него, а меняться будет значение в PORTx.*  Причём если писать единицу поверх единицы -то значение в регистре инвертируется.  DDR можно тоже и читать и писать.

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

dimax пишет:

SU-27-16, Как нельзя? Да не, прочесть то можно в любом режиме . Читается  через регистр PINx, ему всё равно . Есть ещё малоизвестная фишка -можно не только читать из PINx.*, то и писать в него, а меняться будет значение в PORTx.*  Причём если писать единицу поверх единицы -то значение в регистре инвертируется.  DDR можно тоже и читать и писать.

этда....
digitalWrite(ledOn,!digitalRead(ledOn))
...нету смысла, нет ?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

SU-27-16, должно работать, вроде нет таких ардуиновских функций, что б упростить выражение..   Я бы конечно написал так: PINB|=1<<5; (это используя "секрет" о котором сейчас написал)  или так PORTB ^= (1<<5)  если светик на 13 пине.

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

никогда не пробовал digitalRead(ledOn) если пин прописан как выход....
ledOn  - может быть статусом состояния СД, но тогда тревожит digitalWrite(ledOn.... - номер пина

будем подождать весь код :)

bwn
Offline
Зарегистрирован: 25.08.2014

SU-27-16 пишет:

никогда не пробовал digitalRead(ledOn) если пин прописан как выход....
ledOn  - может быть статусом состояния СД, но тогда тревожит digitalWrite(ledOn.... - номер пина

будем подождать весь код :)

Строка в таком виде точно работает, сам иногда пользую. Инвертить светики - релюшки нормально выходит.

Datak
Offline
Зарегистрирован: 09.10.2014

dimax пишет:

Я бы конечно написал так: PINB|=1<<5; (это используя "секрет" о котором сейчас написал)

PINB=1<<5; - так правильней. А в первом случае могут проинвертироваться биты, которые инвертировать совсем не предполагалось. 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Datak пишет:

PINB=1<<5; - так правильней. А в первом случае могут проинвертироваться биты, которые инвертировать совсем не предполагалось. 

Почему, есть какое-то обоснование? Я всегда  делал с | , соседние биты никогда не трогает..

Wip85
Offline
Зарегистрирован: 24.03.2015

Вот написал от дребезга контактов нажимаем кнопку СД горит отпускаем горит. Повторное нажатие на кнопку СД не горит. Не судите строго. Я только начинающий )))

void loop()
{
   if (digitalRead(switchPin) == HIGH && flag == LOW)
   {
     delay(5);
     digitalWrite(ledOn,!digitalRead(ledOn));
         flag = HIGH;
    }
  if (digitalRead(switchPin) == LOW && flag == HIGH)
  {
    delay(5);
    flag = LOW;
Любопытно было бы узнать мнение бывалых. Стоит ли так писать в будущим или что то есть по лучше???
dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Wip85, есть и лучше :) Тут вы вынуждены использовать delay() и чем больше он будет тем лучше,  т.к. в противном случае  программа может успеть снять флаг быстрее, чем человек снимет палец с кнопки. Более совершенный  алгоритм, когда программа исключает дребезг совсем , т.е. после  нажатия кнопки ждёт примерно 20мс, потом снова читает вход, если состояние такое -же -значит кнопку держит человек ) И тоже самое при обратном движении.Если при опросе digitalRead стал LOW, то через 20мс снова проверяется на LOW. И только после второго чтения принимается решение что кнопку больше не дерджат. И Всё это без delay() разумеется..

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

так можно ? делей на антидребезг , while - ждём отпускания....

      if(countKnopka<10)
      {
        if(!digitalRead(knopka1))
        {
          delay(75);
          while(!digitalRead(knopka1))
          reply[countKnopka]=1;
          countKnopka++;
        }

 

Wip85
Offline
Зарегистрирован: 24.03.2015

Скажите пожалуйста я правильно функцию написал или нет? 

int Dreb ( boolean Button ){          
  long time = 20;
Button = digitalRead(switchPin);
  if ( Button == HIGH){
   time = millis();}
    if ( Button == HIGH){
     Button = HIGH;}
     if (Button == LOW){
       time=millis();}
       if (Button == LOW){
         Button=LOW;}
         return switchPin;
Я так понимаю что можно написать один раз функцию и применять ее в дальнейшем в программе?  Но что то у меня не работает она ))))
Может я что-то не так сделал?
 
Coolerr
Offline
Зарегистрирован: 30.06.2014

int y=0;
int x=0;
unsigned long z=0;
int a=0;
void setup(){
  pinMode(15,OUTPUT);
  pinMode(2,INPUT);
digitalWrite(2,HIGH);
}
void loop(){
   x=digitalRead(2);
    if(millis()-z>300)
         {
      if(x==LOW&&y==0){
       y=1;
        a=!a;
	}
      z=millis();
      }
      if(x==HIGH)y=0;
 digitalWrite(15,a);
}

 

ИК выключатель.

На кнопке тоже работает

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Wip85 Я для себя написал функцию для дребезга, работает. Посмотрите может Вам подойдет


int buttonPin1 = 6;
int t1 = 50; //Время для дребезга
bool fl_Pin1;//Флаг кн. Выбор
bool fl_drebezg = 0;//Флаг - Дребезга
bool kn_poz = 0;//Переменная кн. Выбор
unsigned long currentTime; //Переменная для drebezg

void setup()
{
pinMode(buttonPin1, INPUT_PULLUP); //  пин, как вход + подтягивающий резистор
}

//Функция дребезга
int drebezg(int y)
{
	bool x = 0;
	if (fl_drebezg == 0)currentTime = millis(), fl_drebezg = 1;
	if (millis() - currentTime >= y) x = 1, fl_drebezg = 0;
  return x;
}

void loop()
{
//проверяем кнопку 1, на дребезг
 if (digitalRead(buttonPin1) == LOW && kn_poz == 0) //  Нажали
{
  	if (fl_Pin1 == 0) fl_drebezg = 0, fl_Pin1 = 1;
    kn_poz = drebezg (t1); // Отправляем в Функцию дребезга
}
if (kn_poz == 1)  //Если кнопка нажата
{
	if (digitalRead(buttonPin1) == HIGH) //Отпустили
	{
		if (fl_Pin1 == 1) fl_drebezg = 0, fl_Pin1 = 0;
        kn_poz = !drebezg (t1); // Отправляем в Функцию дребезга
    }
}
}

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

А я уже не использую программные способы подавления дребезга :)  Раньше  не пользовался внешними прерываниями, а позже всё же оценил их удобства. Но в прерывании дребезг подавлять очень проблематично. Можно конечно, но как говорится "мне этой геморой не нужен" :) Но не всё так плохо, если подобрать конденсатор паралельно кнопке, то вероятность ложного срабатывания будет почти нулевой. При условии использования внутренней подтяжки я остановился на электролитах 1uF. С самой обычной кнопкой (а-ля ресет с морды компьютерного системника)  вероятность корректного срабатывания при тестировании была 100 раз из 100. Если у вас уже заняты оба внешних перывания, то есть ещё одно "секретное" -прерывание компаратора. Не видел что-бы его кто-нибудь использовал, а ведь оно такое же функциональное, как и два обычных внешних. Вот заодно пример работы с ним. Кнопка с паралельно включённым конденсатором 1мкф вешается на 7 ногу ардуины, включается внутренняя подтяжка. В качестве индикации срабатывания традиционно вкл/выкл встроенный светик на 13 ноге.

void setup(){
DDRB|=1<<5; //13 пин ард. - установлен как выход (светодиод)
PORTD|=1<<7; // 7 пин ард. -вход с подтяжкой
ACSR=(0<<ACD)|(1<<ACBG)|(1<<ACIE)|(1<<ACIS1)|(1<<ACIS0); 
// включить компаратор, сравнение с ион, включить прерывание,
//срабатывание по нажатию на кнопку  или  если 0<<ACIS0 по отпусканию
}

ISR (ANALOG_COMP_vect) { 
 PORTB ^= (1<<5); //инверсия 13 пина ардуино по прерыванию
}

void loop() {  }

 

Wip85
Offline
Зарегистрирован: 24.03.2015

Большое спасибо Dimax. Я так понимаю что ваша профессиональная деятельность связана с программирование микроконтроллеров? А еще хотел спросить у вас. Что посоветуете в освеоение программирование МК. Какой язык лучше осваивать? Какую литературу посоветуете в этом не легком деле? Я только начинающий в программирование. Но вообще интересное это ремесло. Работа творческая  )))) Спасибо что отвечаете на комментарии.  

Datak
Offline
Зарегистрирован: 09.10.2014

dimax пишет:

Datak пишет:

PINB=1<<5; - так правильней. А в первом случае могут проинвертироваться биты, которые инвертировать совсем не предполагалось. 

Почему, есть какое-то обоснование? Я всегда  делал с | , соседние биты никогда не трогает..

Извините, давно сюда не заходил.

Соседние биты не трогает, только если на соответствующих входах PINB были нули.
А единичные биты должны инвертироваться.







PINB  = 1 << 5;   // PORTB = PORTB ^ ( 1 << 5 );

PINB |= 1 << 5;   // PORTB = PORTB ^ ( PINB | ( 1 << 5 ) );

Кажется так, если не ошибаюсь.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Wip85, микроконтроллеры -исключительно моё хобби) Если вы начали заниматься с ардуино, то язык сответственно СИ, ибо под него всё и задумывалось. Литературы хорошей нет, но на многое можно найти примеры на этом форуме или на arduino.cc. На robocraft.ru очень много полезного, есть практические статьи-уроки по работе с датчиками, дисплеями, итп.  Но главные помощники -яндекс и гугль :)

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012
Wip85
Offline
Зарегистрирован: 24.03.2015

Dimax Я так и делаю. Правильно вы заметили что хорошей литературы нет. Что то читать безполезно. Гугл и яндекс. Все по крупицам приходиться собирать. ((( Опыт дело дорогое. 

mag155
Offline
Зарегистрирован: 21.12.2017

dimax вопрос конкретно к вам. Есть задача управление трех фазный тиристорным мостом . Суть в том что есть три синхроимпульса каждый от своей фазы нужно по каждому из них независимо друг от друга отсчитывать время и давать импульс на свой выход . ?