1

Тема: Что не так

Купил фридуину. Сижу изучаю.
Опыт программирования никакой. Но очень охота научиться.
Написал вот такой скетч

// переменные и порты
int led10 = 10;   
int led11 = 11;
int pot = 0;
int button = 2;
int v;// время мигания - регулирутся переменником
int b;// состояние кнопки
int s;
// установки
void setup()
{
pinMode(led10, OUTPUT);
pinMode(led11, OUTPUT);
pinMode(pot, INPUT);
pinMode(button, INPUT);

}
// работаем
void loop()
{
 
   digitalWrite(led10, LOW); //тушим светодиоды
   digitalWrite(led11, LOW); //тушим светодиоды
   b = digitalRead(button);// читаем состояние кнопки
if (b == HIGH) // если кнопка не нажата
{
 
  for(int shim = 0; shim <=255; shim +=5)
  {
  analogWrite(led11, shim);
  delay(30);
  }
    for(int shim = 255; shim >=0; shim -=5)
  {
  analogWrite(led11, shim);
  delay(30);
  }
   for(int shim10 = 0; shim10 <=255; shim10 +=5)
  {
  analogWrite(led10, shim10);
  delay(30);
  }
    for(int shim10 = 255; shim10 >=0; shim10 -=5)
  {
  analogWrite(led10, shim10);
  delay(30);
  }
}
else // иначе
{

  for(int j = 0; j <= 15; j++) // цикл
  {
  v = analogRead(pot);        //мигаем и меняем частоту
v /= 4;
digitalWrite(led10, HIGH);
digitalWrite(led11, LOW);
delay(v);
digitalWrite(led10, LOW);
digitalWrite(led11, HIGH);
delay(v);
}
}
}

Вроде все работает но есть одно но
Нажатие на кнопку воспринимается только при завершении цикла
   for(int shim10 = 0; shim10 <=255; shim10 +=5)
  {
  analogWrite(led10, shim10);
  delay(30);
  }
    for(int shim10 = 255; shim10 >=0; shim10 -=5)
  {
  analogWrite(led10, shim10);
  delay(30);
  }
а хотелось чтобы это происходило всегда.
И второй вопрос как сделать чтобы при нажатии кнопки 1 раз выполнялось какое либо действие - например мигал светодиод, а если еще раз нажать - то дркгое действие - например другой светодиод.

2

Re: Что не так

Не совсем понял почему кнопка не нажата 1(HIGH), кнопка на размыкание, или кнопка на землю с резистером подтяжки к плюсу? Без схемы не очень понятно.

1) Чтобы кнопка прерывала работу цикла -  добавь проверку кнопки внутрь цикла. Например так:

for(int shim10 = 0; shim10 <=255; shim10 +=5) //здесь прервет
  {
b = digitalRead(button);// читаем состояние кнопки
if (b == 0){break;} // если кнопка нажата прервать цикл
  analogWrite(led10, shim10);
  delay(30);
  }
    for(int shim10 = 255; shim10 >=0; shim10 -=5)
  {
  b = digitalRead(button);// читаем состояние кнопки
  if (b == 0){break;} // если кнопка нажата прервать цикл
  analogWrite(led10, shim10);
  delay(30);
  }

2)чтобы использовать кнопку как переключатель нескольких положений надо добавить переменную-хранилище положений и использовать ее для сравнения. Пример:

int led10 = 10;   
int led11 = 11;
int led12 = 9;   
int led13 = 6;
int button = 2;
int v;// время мигания - регулирутся переменником
int b;// состояние кнопки
int C=0;//переменная-хранилище положений


//поскольку проверка кнопки будет повторяться, чтобы не ломать 
//клавиатуру и пальцы вынесем все это в отдельную функцию
void buttonread() 
{
b = digitalRead(button);// читаем состояние кнопки
if (b == LOW) // если кнопка нажата
{
C=C+1; //нажали кнопку - увеличили на 1 хранилище
if (C>4){C=0;}//Для примера - 5 положений 0 1 2 3 4, если больше - очищаем хранилище
 }
delay(130);//задержка для защиты от двойного нажатия, стоит ее подкорректировать под себя
}

void setup()
{
pinMode(led10, OUTPUT);
pinMode(led11, OUTPUT);
pinMode(led12, OUTPUT);
pinMode(led13, OUTPUT);
pinMode(button, INPUT);
}

void loop()
{
buttonread(); //читаем кнопки используя свою функцию
//Для выбора положений мне удобнее switch-case, но можно и на if - else if, вопрос удобства.
switch (C)
{
case 4: //положение 4, горят все светодиоды
digitalWrite(led10, 1);
digitalWrite(led11, 1);
digitalWrite(led12, 1);
digitalWrite(led13, 1);
break;
case 3: //положение 3, мигают все светодиоды
int i;//Для мигания введем переменную хранилище состояний мигания
i=i+1;//увеличиваем
if (i==2){i=0;}//ограничиваем
digitalWrite(led10, i);
digitalWrite(led11, i);
digitalWrite(led12, i);
digitalWrite(led13, i);
buttonread(); //читаем кнопки используя свою функцию, поскольку в нее уже внесена задержка
//дополнительную паузу не ставим
break;
case 2://а тут поиграем с ШИМ
   for(int shim10 = 0; shim10 <=255; shim10 +=5)
  {
  analogWrite(led10, shim10);
  analogWrite(led11, shim10);
  analogWrite(led12, shim10);
  analogWrite(led13, shim10);
  buttonread();//читаем кнопки используя свою функцию, поскольку в нее уже внесена задержка
//дополнительную паузу опять не ставим
if (C!=2){break;}//проверяем, небыло ли изменений в хранилище. Именно так и прервем цикл
  }
    for(int shim10 = 255; shim10 >=0; shim10 -=5)
  {
  analogWrite(led10, shim10);
  analogWrite(led11, shim10);
  analogWrite(led12, shim10);
  analogWrite(led13, shim10);
  analogWrite(led10, shim10);
  buttonread();//читаем кнопки используя свою функцию, поскольку в нее уже внесена задержка
//дополнительную паузу и опять не ставим.
if (C!=2){break;}//проверяем, небыло ли изменений в хранилище
  }
break;
case 1://тут все просто выключим
digitalWrite(led10, 0);
digitalWrite(led11, 0);
digitalWrite(led12, 0);
digitalWrite(led13, 0);
break;
default: //если положение хранилища не попадает под описанные ранее, в нашем случае это 0
//что оно делает не предумал
break;
}
}

3

Re: Что не так

Кнопка подтянута к плюсу.
Спасибо. Сейчас попробую!

4

Re: Что не так

Вот тут не хочет из цикла выходить
Не пойму почему?

  for(int j = 0; j <= 15; j++) // цикл
  {
b = digitalRead(button);// читаем состояние кнопки
v = analogRead(pot);        //мигаем и меняем частоту
v /= 4;
digitalWrite(led10, HIGH);
digitalWrite(led11, LOW);
delay(v);
digitalWrite(led10, LOW);
digitalWrite(led11, HIGH);
delay(v);

5

Re: Что не так

Anton-ST пишет:

Вот тут не хочет из цикла выходить
Не пойму почему?

  for(int j = 0; j <= 15; j++) // цикл
  {
b = digitalRead(button);// читаем состояние кнопки
v = analogRead(pot);        //мигаем и меняем частоту
v /= 4;
digitalWrite(led10, HIGH);
digitalWrite(led11, LOW);
delay(v);
digitalWrite(led10, LOW);
digitalWrite(led11, HIGH);
delay(v);

Потому что состояние кнопки только читается, но не сравнивается.
добавь в цикл проверку кнопки: if (b==LOW){break;}

6

Re: Что не так

понял

7

Re: Что не так

Почему то у меня вот этот блок работает непонятно

// проверка кнопки
void buttonread()
{
b = digitalRead(button);// читаем состояние кнопки
if (b == LOW) // если кнопка нажата
{
C=C+1; //нажали кнопку - увеличили на 1 хранилище
if (C>4){C=0;}//Для примера - 5 положений 0 1 2 3 4, если больше - очищаем хранилище
}
delay(50);//задержка для защиты от двойного нажатия, стоит ее подкорректировать под себя
Serial.println(C);
}
Запускаю программу - сразу по кнопке идет 0. По нажатию проскакивают 1-2-3. переменная С становится 3. Еще раз нажимаю. Переменная С == 4, Еще раз жму. Проскакивает 0-1-2-3. И С ==3.

8 (2011-03-01 13:55:45 отредактировано Anton-ST)

Re: Что не так

Delay поставил сразу после провеки кнопки - стало лучше. Но всеравно не четко срабатывает

9 (2011-03-01 15:04:10 отредактировано mogalkov)

Re: Что не так

delay(50);//задержка для защиты от двойного нажатия, стоит ее подкорректировать под себя
увеличивай время задержки, попробуй 100 150 200 250 300 и так далее.
Также может помоч кондер мелкий (10пФ -100пФ) паралельно кнопке.

Еще для устранения дребезга контактов можно попробовать так:

// проверка кнопки
void buttonread() 
{
b = digitalRead(button);// читаем состояние кнопки
//Операция A % B возвращает остаток от деления числа A на B, в данном случае на 100.
// А поскольку условие сравнивает его с нулем, то блок операторов в 
//фигурных скобках исполнится только если число миллисекунд будет кратно 100: 100, 200, 300
  if ( (millis() % 100) == 0) {
if (b == LOW) // если кнопка нажата
{
C=C+1; //нажали кнопку - увеличили на 1 хранилище
if (C>4){C=0;}//Для примера - 5 положений 0 1 2 3 4, если больше - очищаем хранилище
 }
}
delay(50);//задержка для защиты от двойного нажатия, стоит ее подкорректировать под себя
Serial.println(C);
}