Считывание нажатия кнопки в момент выполнения цикла

rdbv-18ww-09
Offline
Зарегистрирован: 11.06.2018

Не получается реализовать смену режимов работы нажатием кнопкой, если заместо кнопки ставишь поочередную смену через время то все работает. Выходит что проблема именно в считывании самой кнопки, как можно это победить?

 

 
Moderator : пожалуйста, вставьте код правильно (новым сообщением в тему), как описано в http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii
 
 
 
rdbv-18ww-09
Offline
Зарегистрирован: 11.06.2018

* к выходу 12

rdbv-18ww-09
Offline
Зарегистрирован: 11.06.2018
int redPin = 11;
int greenPin = 10;
int bluePin = 9;            
int ButPin = 12 ;               
int flag = 0;                  // флаг состояния
int regim = 0;                 // Переключалка
int r, g, b;

#define FADESPEED 5

void setup()
{
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);  
}  

void loop()
{
 if(digitalRead(ButPin) == HIGH && flag == 0) flag = 1;
 if(digitalRead(ButPin) == LOW && flag == 1)
  {   
   regim ++;
   if(regim == 3) regim = 0;
   flag = 0;
  } 

 switch(regim)
  {
   case 0:
    r = b = g = 0;
    analogWrite(redPin, r);
    analogWrite(greenPin, g);
    analogWrite(bluePin, b);
   break; 
   case 1:
    r = b = g = 255;
    analogWrite(redPin, r);
    analogWrite(greenPin, g);
    analogWrite(bluePin, b);    
   break;
   case 2:
    for (r = 0; r < 256; r++)
     { 
      analogWrite(redPin, r);
      delay(FADESPEED);
     } 
    for (b = 255; b > 0; b--)
     {
      analogWrite(bluePin, b);
      delay(FADESPEED);
     } 
    for (g = 0; g < 256; g++)
     {
      analogWrite(greenPin, g);
      delay(FADESPEED);
     } 
    for (r = 255; r > 0; r--)
     {
      analogWrite(redPin, r);
      delay(FADESPEED);
     } 
    for (b = 0; b < 256; b++)
     {
      analogWrite(bluePin, b);
      delay(FADESPEED);
     }
    for (g = 255; g > 0; g--)
     {
      analogWrite(greenPin, g);
      delay(FADESPEED);
     } 
    break; 
   }
}

 

BOOM
BOOM аватар
Онлайн
Зарегистрирован: 14.11.2018

Использовать прерывание. 

rdbv-18ww-09
Offline
Зарегистрирован: 11.06.2018

Какое прерывание? есть же break, как мне видится проблема в том что при не может программа одновременно выполнять цикл и считывать нажатие или я не прав?

Нужно чтобы условие 3 выполнялось постоянно пока не будет нажата кнопка в очередной раз.

sadman41
Offline
Зарегистрирован: 19.10.2016

rdbv-18ww-09 пишет:

как мне видится проблема в том что при не может программа одновременно выполнять цикл и считывать нажатие или я не прав?

Правы насчёт своей программы.

rdbv-18ww-09
Offline
Зарегистрирован: 11.06.2018

Так работает практически как задумано, но при коротких нажатиях, если кнопку нажимать не супер быстро то проскакивает практически всегда второй режим.


int redPin = 11;
int greenPin = 10;
int bluePin = 9;            
int ButPin = 6 ;               
int flag = 0;                 
int regim = 0;                
int r, g, b;

#define FADESPEED 10

void setup()
{
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);  
  pinMode(ButPin, INPUT_PULLUP);
}  

void loop()
{
L:  
 if(digitalRead(ButPin) == HIGH && flag == 0) flag = 1;
 if(digitalRead(ButPin) == LOW && flag == 1)
  {   
   regim ++;
   if(regim == 3) regim = 0;
   flag = 0;
  } 

 switch(regim)
  {
   case 0:
    r = b = g = 0;
    analogWrite(redPin, r);
    analogWrite(greenPin, g);
    analogWrite(bluePin, b);
   break; 
   case 1:
    r = b = g = 255;
    analogWrite(redPin, r);
    analogWrite(greenPin, g);
    analogWrite(bluePin, b);    
   break;
   case 2:
    for (r = 0; r < 256; r++)
     { 
      if(digitalRead(ButPin) == HIGH && flag == 0) flag = 1;
      if(digitalRead(ButPin) == LOW && flag == 1)
       {   
        regim ++;
        if(regim == 3) regim = 0;
        flag = 0;
        goto L;
       } 
      analogWrite(redPin, r);
      delay(FADESPEED);
     } 
    for (b = 255; b > 0; b--)
     {
      if(digitalRead(ButPin) == HIGH && flag == 0) flag = 1;
      if(digitalRead(ButPin) == LOW && flag == 1)
       {   
        regim ++;
        if(regim == 3) regim = 0;
        flag = 0;
        goto L;
       } 
      analogWrite(bluePin, b);
      delay(FADESPEED);
     } 
    for (g = 0; g < 256; g++)
     {
      if(digitalRead(ButPin) == HIGH && flag == 0) flag = 1;
      if(digitalRead(ButPin) == LOW && flag == 1)
       {   
        regim ++;
        if(regim == 3) regim = 0;
        flag = 0;
        goto L;
       } 
      analogWrite(greenPin, g);
      delay(FADESPEED);
     } 
    for (r = 255; r > 0; r--)
     {
      if(digitalRead(ButPin) == HIGH && flag == 0) flag = 1;
      if(digitalRead(ButPin) == LOW && flag == 1)
       {   
        regim ++;
        if(regim == 3) regim = 0;
        flag = 0;
        goto L;
       } 
      analogWrite(redPin, r);
      delay(FADESPEED);
     } 
    for (b = 0; b < 256; b++)
     {
      if(digitalRead(ButPin) == HIGH && flag == 0) flag = 1;
      if(digitalRead(ButPin) == LOW && flag == 1)
       {   
        regim ++;
        if(regim == 3) regim = 0;
        flag = 0;
        goto L;
       } 
      analogWrite(bluePin, b);
      delay(FADESPEED);
     }
    for (g = 255; g > 0; g--)
     {
      if(digitalRead(ButPin) == HIGH && flag == 0) flag = 1;
      if(digitalRead(ButPin) == LOW && flag == 1)
       {   
        regim ++;
        if(regim == 3) regim = 0;
        flag = 0;
        goto L;
       } 
      analogWrite(greenPin, g);
      delay(FADESPEED);
     } 
    break; 
   }
}

 

nik182
Онлайн
Зарегистрирован: 04.05.2015

У Вас в коде есть delay(). У делея есть слабая функция  в нутрь которой можно вставить проверку нажатия клавишь. Или заменить все делеи на свою функцию задержки с провекой клавишь. Пока есть свободные делеи проблемы с клавишами будут всегда. 

leks
Offline
Зарегистрирован: 22.10.2017

Слабая функция у делея - а где про это можно почитать?

sadman41
Offline
Зарегистрирован: 19.10.2016
void delay(unsigned long ms)
{
	uint32_t start = micros();

	while (ms > 0) {
		yield();
		while ( ms > 0 && (micros() - start) >= 1000) {
			ms--;
			start += 1000;
		}
	}
}

...

static void __empty() {
	// Empty
}
void yield(void) __attribute__ ((weak, alias("__empty")));

 

 

nik182
Онлайн
Зарегистрирован: 04.05.2015

Недавно обсуждали найдите. А вообще в файлах ядра ардуино. Напишите свою yield();

Green
Offline
Зарегистрирован: 01.10.2015

Слабая функция, ядро ардуино, yield()... Да тяжело это для ТС! Проще вместо delay(x) поставить свою Delay(x), которая будет выглядеть примерно так:

void Delay(long x)
{
  while (x--) {
    delay(1);
    // здесь ваша функция опрашивающая кнопку и
    // сохраняющая результат в переменной и вываливающаяся по break
  }
}

 

Green
Offline
Зарегистрирован: 01.10.2015

Я и сам не люблю эти фишки Ардуино, плюсов, GCC... Проще нужно быть.)

Voodoo Doll
Voodoo Doll аватар
Offline
Зарегистрирован: 18.09.2016
unsigned long last_key=millis();
unsigned long last_fade=millis();
bool dir_increase=0; // 0=dec, 1=inc
byte level_led=0;

#define KEY1 (2)
#define LED1 (3)
#define KEYPOLL (100) // look for keys 10 times/sec
#define FADESTEP (16) // approx equ 4000/256 if we want 4s fade

void setup(){
  pinMode(KEY1,INPUT_PULLUP);
  pinMode(LED1,OUTPUT);
}

void loop(){
  if(mills()-last_key>=KEYPOLL){
    if(!digitalRead(KEY1)) do_chng_dir();
    last_key=millis();
  }
  if(mills()-last_fade>=FADESTEP){
    if(dir_increase){
      if(level_led<255) level_led++;
      // others if they exists
    }else{
      if(level_led>0) level_led--;
      // others
    }
    last_fade=millis();
  }
  // other NONBLOCKING code
  analogWrite(LED1,level_led);
}

void do_chng_dir(){
  dir_increase=!dir_increase;
}

Пора базу знаний забацать. Постоянно эти вопросы.

b707
Offline
Зарегистрирован: 26.05.2017

Voodoo Doll пишет:

Пора базу знаний забацать. Постоянно эти вопросы.

Лучшая база знаний - Гугл. Но и он не поможет. Чтобы найти решение в поиске - надо знать половину ответа

SLKH
Offline
Зарегистрирован: 17.08.2015

Voodoo Doll пишет:


Пора базу знаний забацать. Постоянно эти вопросы.

Знания "как вставить код" забацаны. Сильно помогло?

BOOM
BOOM аватар
Онлайн
Зарегистрирован: 14.11.2018

При регистрации своего рода капча (много где встречал), по типу:

1. Например, продолжить фразу - Ардуино это (а. Крутая игрушка, в которой разберётся даже домохозяйка; б. Средство быстрой разработки и макетирования устройства; в. Не понял ничего из а. и б.). Ну короче понятно. 
2. Правильно вставить код;

3. Что такое поиск по форуму? (Ну и там: а. я не знаю; б. Где-то слышал; в. Знал бы не обращался сюда.; г. Поле ввода в верхнем правом углу; д. Поле ввода в верхнем левом углу; е. Я сдаюсь)

n. Etc....

b707
Offline
Зарегистрирован: 26.05.2017

не надо. Если не будет новичков - будет скучно :)

BOOM
BOOM аватар
Онлайн
Зарегистрирован: 14.11.2018

Новички будут, я же вопросы/ответы примерные написал. Можно что то более логичное для новичков придумать. Но хотя бы «как мигать светодиодом» отсеется. ))

или все же не?)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

А "как мигать светодиодом" как раз никого не напрягает. Напрягает, когда когда человек просит сообщить ему, сможет ли он сделать проект на 200 датчиков, 800 кнопок и 2000 светодиодов, и просит написать список, какие именно датчики, кнопки и светодиоды ему нужны.