Функция нескончаемо инкременирует значение при нажатие на кнопку

savdm
Offline
Зарегистрирован: 03.02.2015

Здравствуйте, сделал вот по этому примеру, но при нажатии на любую из двух кнопок происходит бесконечный цикл, как его ограничить - нахожусь в прострации:) Подскажите, почему функция click1() так работает и как можно это исправить.

maksim пишет:

Можно например так сделать

unsigned long eventTime = 0;
int regim = 1; 
int flag = 0; 

void setup()   
{ 
  pinMode(4, OUTPUT);    
  pinMode(5, OUTPUT);        
}

void loop()
{       
  if(digitalRead(8) == HIGH && flag == 0)     
  { 
    flag = 1;  
    eventTime = millis();
  } 

  if(digitalRead(8) == HIGH && flag == 1 && millis()-eventTime > 3000) regim = 0;

  if(digitalRead(8) == LOW && flag == 1)      
  {
    flag = 0;   
    if(millis()-eventTime < 3000) regim++;
    if(regim > 3) regim = 1;
  }
  
  switch(regim)
  {
  case 0: 
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH); 
    break; 
  case 1: 
    digitalWrite(4, LOW);
    digitalWrite(5, LOW); 
    break;    
  case 2: 
    digitalWrite(4, HIGH);
    digitalWrite(5, LOW); 
    break;
  case 3:        
    digitalWrite(5, HIGH);
    digitalWrite(4, LOW);     
    break;   
  }       
}

кнопки которые выполняют либо увеличение на 1 либо на 5, но это циклично, и не пойму в чем проблема, подскажите, пожалуйста. Скетч

// DS отвечает за поток битов(данные). На Схеме 595 пин 14
#define DATA_PIN 4
//STCP отвечает за так называемое защелкивание. Когда мы все свои биты передали, посылаем сигнал, что окончили передачу. На Схеме 595 пин 12
#define LATCH_PIN 3
// SHCP отвечает за ШИМ. Когда 1 из данных забирается бит, 0 пропускается.Синхронизация потока. На Схеме 595 пин 11
#define CLOCK_PIN 2
const int digitPins[3] = {
  52,51,50}; //Массив пинов. Выбрал произвольные кониакты у меня Мега
int8_t Disp[3]={
  0};// задается тип int8_t чтобы к нам ничего, кроме набора бит не попало.
int Value = 120;
int i = 0;
int flag = 0;//0 - не нажата ни одна, 1 - нажата одна
int regim ;
unsigned long previousMillis = 0;//отсечка
unsigned long time;
int TimePush = 2000;

byte segments[10] = { //Массив из 10 значений
  B11000000, //0
  B11111001, //1
  B10100100, //2
  B10110000, //3
  B10011001, //4
  B10010010, //5
  B10000010, //6
  B11111000, //7
  B10000000, //8
  B10010000 //9 Бинарное значение цифры в моем подключении индикатора и сдвигового регистра, когда q1->a,..q7->g,q0->DP
};

void setup()
{
  Serial.begin(115200);
  for(byte j=0;j<3;j++)pinMode(digitPins[j],OUTPUT); //цикл - назначаем всем режим выход из нашего массива пинов
  pinMode(DATA_PIN, OUTPUT);
  pinMode(CLOCK_PIN, OUTPUT);
  pinMode(LATCH_PIN, OUTPUT);
}
// Моя функция для работы с индикатором и сдвиговым регистром 74НС595
void printInd()
{
  //цифровые выходы из массива в 0 (LOW) - отключаем используем цикл
  for(byte d=0; d<3; d++) digitalWrite(digitPins[d], LOW);

  //Для начала записи в 74HC595 нужно подать 0 на STCP (открыть)
  digitalWrite(LATCH_PIN, LOW);
  // с данными выпускаем поток битов на DS синхроннированные с SHCP
  shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, segments[Disp[i]]);
  // А теперь когда последний бит числа передали закрываем
  digitalWrite(LATCH_PIN, HIGH);
  //на индикатор подаем 5V смотреть в DATASHEET вашего индикатора!!!
  digitalWrite(digitPins[i], HIGH);
  //delayMicroseconds(300); //Частота ирцания и собственно она же яркость индикатора:)
  //delay(1000);// проследить появление
  i++;
  if(i > 2) i=0;
}
void click1()
{
  int VRes = analogRead(0); // значение с аналог пина
  if(flag == 0 && VRes<300 && VRes>0) // нажата ли кнопка 1 +
  {
    previousMillis= millis(); // когда нажата
    flag = 1; // состояние что нажата
    Serial.println("IF 1");   
  }
  if(flag == 1 && VRes<300 && VRes>0 && ((millis()-previousMillis) > TimePush)){
    regim=1;
    Serial.println("IF 2");
  }// выполняем первый режим работы прибавление 5 ед.
  if(VRes > 1000 && flag ==1) 
  {
    flag = 0; //кнопка отжата 
    Serial.println("IF 3");
    if(millis()-previousMillis<TimePush)
    {
      regim = 2;
      Serial.println("IF 4");
    } //прибавление единицы
  }
  //Два других режима по аналогии
  //  if(flag == 0 && VRes > 250 && VRes < 530) // нажата ли кнопка 2 -
  //  {
  //    Serial.println("IF 5");
  //    previousMillis = millis();  // когда нажата
  //    flag = 1; // состояние что нажата
  //  }
  //  if(flag == 1 && VRes > 250 && VRes < 530 && millis()-previousMillis > TimePush){
  //    Serial.println("IF 6");
  //    regim=3;// третий режим - отнимаем 5 ед.
  //  }
  //  if(VRes > 1000 && flag ==1) 
  //  {
  //    Serial.println("IF 7");
  //    flag=0; //кнопка отжата 
  //    if(millis()-previousMillis<TimePush) 
  //    {
  //      Serial.println("IF 8");
  //      regim=4; //отнимаем единицы
  //    }
  //  }
  switch(regim) 
  {
  case 1:
    Value+=5;
    break;
  case 2:
    Value++;
    break;
  case 3:
    Value-=5;
    break;
  case 4:
    Value--;
    break; 
  }
}
void loop()
{
  click1();

  Serial.println(Value);

  //Выводим значение отсрочки срабатывания таймера на дисплей
  Disp[0] = (Value/100)%10; //сотни
  Disp[1] = (Value/10)%10; //десятки
  Disp[2] = Value%10; //единицы
  printInd(); //Функция для отображения на индикаторе
}





 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Ну как минимум, пример Вы взяли для цифровых конопок да еще и с реализацией длительного нажатия. А сами используете аналоговые кнопки и задержка вроде как не нужна. flag у Вас один а кнопок две, соответственно значение флага будет "какое попало".

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Ну а вообще надо regim еще обнулять именно из-за него у Вас цакикливание в +=5

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

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

savdm
Offline
Зарегистрирован: 03.02.2015

Кнопки отдельно тестировались, и было тоже самое, полный скетч - для полноты картины.

savdm
Offline
Зарегистрирован: 03.02.2015

Penni пишет:

Ну как минимум, пример Вы взяли для цифровых конопок да еще и с реализацией длительного нажатия. А сами используете аналоговые кнопки и задержка вроде как не нужна. flag у Вас один а кнопок две, соответственно значение флага будет "какое попало".

Penni пишет:

Ну а вообще надо regim еще обнулять именно из-за него у Вас цакикливание в +=5

 

// DS отвечает за поток битов(данные). На Схеме 595 пин 14
#define DATA_PIN 4
//STCP отвечает за так называемое защелкивание. Когда мы все свои биты передали, посылаем сигнал, что окончили передачу. На Схеме 595 пин 12
#define LATCH_PIN 3
// SHCP отвечает за ШИМ. Когда 1 из данных забирается бит, 0 пропускается.Синхронизация потока. На Схеме 595 пин 11
#define CLOCK_PIN 2
const int digitPins[3] = {
  52,51,50}; //Массив пинов. Выбрал произвольные кониакты у меня Мега
int8_t Disp[3]={
  0};// задается тип int8_t чтобы к нам ничего, кроме набора бит не попало.
int Value = 120;
int i = 0;
int flag = 0;
int flag1 = 0;//0 - не нажата ни одна, 1 - нажата одна
int regim ;
unsigned long previousMillis = 0;//отсечка
unsigned long time;
int TimePush = 2000;

byte segments[10] = { //Массив из 10 значений
  B11000000, //0
  B11111001, //1
  B10100100, //2
  B10110000, //3
  B10011001, //4
  B10010010, //5
  B10000010, //6
  B11111000, //7
  B10000000, //8
  B10010000 //9 Бинарное значение цифры в моем подключении индикатора и сдвигового регистра, когда q1->a,..q7->g,q0->DP
};

void setup()
{
  Serial.begin(115200);
  for(byte j=0;j<3;j++)pinMode(digitPins[j],OUTPUT); //цикл - назначаем всем режим выход из нашего массива пинов
  pinMode(DATA_PIN, OUTPUT);
  pinMode(CLOCK_PIN, OUTPUT);
  pinMode(LATCH_PIN, OUTPUT);
}
// Моя функция для работы с индикатором и сдвиговым регистром 74НС595
void printInd()
{
  //цифровые выходы из массива в 0 (LOW) - отключаем используем цикл
  for(byte d=0; d<3; d++) digitalWrite(digitPins[d], LOW);

  //Для начала записи в 74HC595 нужно подать 0 на STCP (открыть)
  digitalWrite(LATCH_PIN, LOW);
  // с данными выпускаем поток битов на DS синхроннированные с SHCP
  shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, segments[Disp[i]]);
  // А теперь когда последний бит числа передали закрываем
  digitalWrite(LATCH_PIN, HIGH);
  //на индикатор подаем 5V смотреть в DATASHEET вашего индикатора!!!
  digitalWrite(digitPins[i], HIGH);
  //delayMicroseconds(300); //Частота ирцания и собственно она же яркость индикатора:)
  //delay(1000);// проследить появление
  i++;
  if(i > 2) i=0;
}
void click1()
{
  int VRes = analogRead(0); // значение с аналог пина
  if(flag == 0 && analogRead(0)<300 && analogRead(0)>0) // нажата ли кнопка 1 +
  {
    previousMillis= millis(); // когда нажата
    flag = 1; // состояние что нажата
    Serial.println("IF 1");   
  }
  if(flag == 1 && analogRead(0)<300 && analogRead(0)>0 && ((millis()-previousMillis) > TimePush)){
    regim=1;
    Serial.println("IF 2");
  }// выполняем первый режим работы прибавление 5 ед.
  if(analogRead(0) > 1000 && flag ==1) 
  {
    flag = 0; //кнопка отжата 
    Serial.println("IF 3");
    if(millis()-previousMillis<TimePush)
    {
          regim++;
   if(regim > 3)  regim = 2;
      Serial.println("IF 4");
    } //прибавление единицы
  }
  //Два других режима по аналогии
  if(flag1 == 0 && VRes > 250 && VRes < 530) // нажата ли кнопка 2 -
 {
   Serial.println("IF 5");
   previousMillis = millis();  // когда нажата
    flag1 = 1; // состояние что нажата
  }
  if(flag1 == 1 && VRes > 250 && VRes < 530 && millis()-previousMillis > TimePush){
    Serial.println("IF 6");
   regim=3;// третий режим - отнимаем 5 ед.
  }
  if(VRes > 1000 && flag1 ==1) 
 {
   Serial.println("IF 7");
    flag1=0; //кнопка отжата 
    if(millis()-previousMillis<TimePush) 
    {
     Serial.println("IF 8");
     regim++;
   if(regim > 4) regim = 4;
 //отнимаем единицы
    }
  }
  switch(regim) 
  {
  case 1:
    Value+=5;
    break;
  case 2:
    Value++;
    break;
  case 3:
    Value-=5;
    break;
  case 4:
    Value--;
    break; 
  }
}
void loop()
{
  click1();
  Serial.println(Value);

  //Выводим значение отсрочки срабатывания таймера на дисплей
  Disp[0] = (Value/100)%10; //сотни
  Disp[1] = (Value/10)%10; //десятки
  Disp[2] = Value%10; //единицы
  printInd(); //Функция для отображения на индикаторе
}

О таком изменении речь?

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

savdm пишет:

Кнопки отдельно тестировались, и было тоже самое, полный скетч - для полноты картины.

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

savdm
Offline
Зарегистрирован: 03.02.2015

bwn пишет:

savdm пишет:

Кнопки отдельно тестировались, и было тоже самое, полный скетч - для полноты картины.

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

Дело в том, что есть 7 ми сегмент и значения на нем зависят от этих кнопок, поэтому не совсем понимаю о чем вы скетч итак только основное здесь имеет. И кнопки вызвали крайнее недоумение.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Ну если в двух словах то у Вас click1() выполняется постоянно, при этом regim всегда имеет какое-то значение от 1 до 4, а значит switch case будет срабатывать на каждом цикле, отсюда и Ваша зацикленность. Если уверенны, что кнопки работают правильно то надо после каждого case перед break писать regim=0 Тогда на следующем цикле мы не попадём в case, а попадём туда тоьлко когда действительно нужно т.е. при нажатиях на кнопки.

savdm
Offline
Зарегистрирован: 03.02.2015

Penni пишет:

Ну если в двух словах то у Вас click1() выполняется постоянно, при этом regim всегда имеет какое-то значение от 1 до 4, а значит switch case будет срабатывать на каждом цикле, отсюда и Ваша зацикленность. Если уверенны, что кнопки работают правильно то надо после каждого case перед break писать regim=0 Тогда на следующем цикле мы не попадём в case, а попадём туда тоьлко когда действительно нужно т.е. при нажатиях на кнопки.

Действительно, как же не догадался, спасибо огромное, помогло!! Светлая голова.

  switch(regim) 
  {
  case 1:
    Value+=5;
    regim=0;
    break;
  case 2:
    Value++;
    regim=0;
    break;
  case 3:
    Value-=5;
    regim=0;
    break;
  case 4:
    Value--;
    regim=0;
    break; 
  }

 

savdm
Offline
Зарегистрирован: 03.02.2015

Теперь нужно разобраться почему при действии +5 срабатывает счетчик без конца

+ единица работает отлично!!

- единица не хочет

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

((millis()-previousMillis) > TimePush

Вот это Вам зачем? Вам надо длинные и короткие нажатия на кнопку?

savdm
Offline
Зарегистрирован: 03.02.2015

Нажал первую кнопку в лог выкинуло

IF 1
IF 3
IF 4

и + 5 к значению

Нажал вторую кнопку в лог выкинуло
IF 5
IF 7
IF 8

и + 5 к значению

Хотя по case иное:((

// DS отвечает за поток битов(данные). На Схеме 595 пин 14
#define DATA_PIN 4
//STCP отвечает за так называемое защелкивание. Когда мы все свои биты передали, посылаем сигнал, что окончили передачу. На Схеме 595 пин 12
#define LATCH_PIN 3
// SHCP отвечает за ШИМ. Когда 1 из данных забирается бит, 0 пропускается.Синхронизация потока. На Схеме 595 пин 11
#define CLOCK_PIN 2
const int digitPins[3] = {
  52,51,50}; //Массив пинов. Выбрал произвольные кониакты у меня Мега
int8_t Disp[3]={
  0};// задается тип int8_t чтобы к нам ничего, кроме набора бит не попало.
int Value = 120;
int i = 0;
int flag = 0;
int flag1 = 0;//0 - не нажата ни одна, 1 - нажата одна
int regim ;
unsigned long previousMillis = 0;//отсечка
unsigned long time;
int TimePush = 2000;

byte segments[10] = { //Массив из 10 значений
  B11000000, //0
  B11111001, //1
  B10100100, //2
  B10110000, //3
  B10011001, //4
  B10010010, //5
  B10000010, //6
  B11111000, //7
  B10000000, //8
  B10010000 //9 Бинарное значение цифры в моем подключении индикатора и сдвигового регистра, когда q1->a,..q7->g,q0->DP
};

void setup()
{
  Serial.begin(115200);
  for(byte j=0;j<3;j++)pinMode(digitPins[j],OUTPUT); //цикл - назначаем всем режим выход из нашего массива пинов
  pinMode(DATA_PIN, OUTPUT);
  pinMode(CLOCK_PIN, OUTPUT);
  pinMode(LATCH_PIN, OUTPUT);
}
// Моя функция для работы с индикатором и сдвиговым регистром 74НС595
void printInd()
{
  //цифровые выходы из массива в 0 (LOW) - отключаем используем цикл
  for(byte d=0; d<3; d++) digitalWrite(digitPins[d], LOW);

  //Для начала записи в 74HC595 нужно подать 0 на STCP (открыть)
  digitalWrite(LATCH_PIN, LOW);
  // с данными выпускаем поток битов на DS синхроннированные с SHCP
  shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, segments[Disp[i]]);
  // А теперь когда последний бит числа передали закрываем
  digitalWrite(LATCH_PIN, HIGH);
  //на индикатор подаем 5V смотреть в DATASHEET вашего индикатора!!!
  digitalWrite(digitPins[i], HIGH);
  //delayMicroseconds(300); //Частота ирцания и собственно она же яркость индикатора:)
  //delay(1000);// проследить появление
  i++;
  if(i > 2) i=0;
}
void click1()
{
  int VRes = analogRead(0); // значение с аналог пина
  if(flag == 0 && VRes<300 && VRes>0) // нажата ли кнопка 1 +
  {
    previousMillis= millis(); // когда нажата
    flag = 1; // состояние что нажата
    Serial.println("IF 1");   
  }
  if(flag == 1 && VRes<300 && VRes>0 && ((millis()-previousMillis) > TimePush)){
   regim++;
   if(regim > 1)  regim = 1;
    Serial.println("IF 2");
  }// выполняем первый режим работы прибавление 5 ед.
  if(analogRead(0) > 1000 && flag ==1) 
  {
    flag = 0; //кнопка отжата 
    Serial.println("IF 3");
    if(millis()-previousMillis<TimePush)
    {
   regim++;
   if(regim > 2)  regim = 2;
      Serial.println("IF 4");
    } //прибавление единицы
  }
  //Два других режима по аналогии
  if(flag1 == 0 && VRes > 300 && VRes < 600) // нажата ли кнопка 2 -
 {
   Serial.println("IF 5");
   previousMillis = millis();  // когда нажата
    flag1 = 1; // состояние что нажата
  }
  if(flag1 == 1 && VRes > 300 && VRes < 600 && millis()-previousMillis > TimePush){
    Serial.println("IF 6");
       regim++;
   if(regim > 3)  regim = 3;
   // третий режим - отнимаем 5 ед.
  }
  if(VRes > 1000 && flag1 ==1) 
 {
   Serial.println("IF 7");
    flag1=0; //кнопка отжата 
    if(millis()-previousMillis<TimePush) 
    {
     Serial.println("IF 8");
     regim++;
   if(regim > 4) regim = 4;
 //отнимаем единицы
    }
  }
    switch(regim) 
  {
  case 1:
    Value+=5;
    regim=0;
    break;
  case 2:
    Value++;
    regim=0;
    break;
  case 3:
    Value-=5;
    regim=0;
    break;
  case 4:
    Value--;
    regim=0;
    break; 
  }
}
void loop()
{
  click1();
 // Serial.println(analogRead(0));

  //Выводим значение отсрочки срабатывания таймера на дисплей
  Disp[0] = (Value/100)%10; //сотни
  Disp[1] = (Value/10)%10; //десятки
  Disp[2] = Value%10; //единицы
  printInd(); //Функция для отображения на индикаторе
}

 

savdm
Offline
Зарегистрирован: 03.02.2015

Penni пишет:

((millis()-previousMillis) > TimePush

Вот это Вам зачем? Вам надо длинные и короткие нажатия на кнопку?

Да, именно. Краткое нажатие прибавляет(/ отнимает) единицу. А с задержкой в 2 сек прибавляет(/ отнимает) 5 единиц

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

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

Вот, например, тут. Заходим в условие меняем флаг один раз сверяем время и всё больше мы в это условие не попадём так как флаг сменили, а значит и не отработаем длинное нажатие.

if(analogRead(0) > 1000 && flag ==1)
{
  flag = 0; //кнопка отжата
  Serial.println("IF 3");
  if(millis()-previousMillis<TimePush)
  {
    regim++;
    if(regim > 3)  regim = 2;
    Serial.println("IF 4");
  } //прибавление единицы
}

Хотя судя по < оно тут вообще непонять зачем. В общем кнопки надо делать

savdm
Offline
Зарегистрирован: 03.02.2015

добавил в условия  &&regim ==0

теперь всё как надо но 5 ки не могу поймать по времени, то есть если передержать то счетчик "летит"

void click1()
{
  int VRes = analogRead(0); // значение с аналог пина
  if(flag == 0 && VRes<300 && VRes>0) // нажата ли кнопка 1 +
  {
    previousMillis= millis(); // когда нажата
    flag = 1; // состояние что нажата
    Serial.println("IF 1");   
  }
  if(flag == 1 && VRes<300 && VRes>0 && ((millis()-previousMillis) > TimePush&&regim ==0)){
 regim = 1;
    Serial.println("IF 2");
  }// выполняем первый режим работы прибавление 5 ед.
  if(analogRead(0) > 1000 && flag ==1) 
  {
    flag = 0; //кнопка отжата 
    Serial.println("IF 3");
    if(millis()-previousMillis<TimePush&&regim ==0)
    {
   regim = 2;
      Serial.println("IF 4");
    } //прибавление единицы
  }
  //Два других режима по аналогии
  if(flag1 == 0 && VRes > 300 && VRes < 600) // нажата ли кнопка 2 -
 {
   Serial.println("IF 5");
   previousMillis = millis();  // когда нажата
    flag1 = 1; // состояние что нажата
  }
  if(flag1 == 1 && VRes > 300 && VRes < 600 && millis()-previousMillis > TimePush&&regim ==0){
    Serial.println("IF 6");
regim = 3;
   // третий режим - отнимаем 5 ед.
  }
  if(VRes > 1000 && flag1 ==1) 
 {
   Serial.println("IF 7");
    flag1=0; //кнопка отжата 
    if(millis()-previousMillis<TimePush&&regim ==0) 
    {
     Serial.println("IF 8");
    regim = 4;
 //отнимаем единицы
    }
  }

 

savdm
Offline
Зарегистрирован: 03.02.2015

Penni пишет:

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

Вот, например, тут. Заходим в условие меняем флаг один раз сверяем время и всё больше мы в это условие не попадём так как флаг сменили, а значит и не отработаем длинное нажатие.

if(analogRead(0) > 1000 && flag ==1)
{
  flag = 0; //кнопка отжата
  Serial.println("IF 3");
  if(millis()-previousMillis<TimePush)
  {
    regim++;
    if(regim > 3)  regim = 2;
    Serial.println("IF 4");
  } //прибавление единицы
}

Хотя судя по < оно тут вообще непонять зачем. В общем кнопки надо делать

Не совсем понимаю, посмотрите последний, пожалуйста

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

В целом вам надо конкретизировать понятия - короткое и длинное нажатие. Можем принять - короткое это от 1сек до 2сек, а длинное от 3сек до 5сек. Тогда можно что то реализовать. Если нижний предел короткого не ограничивать, как прога узнает что наступило длинное? Алгоритм - нажали, начали считать время, если отпустили и время в первом диапазоне - короткое, во вторм - длинное.

savdm
Offline
Зарегистрирован: 03.02.2015

bwn пишет:

В целом вам надо конкретизировать понятия - короткое и длинное нажатие. Можем принять - короткое это от 1сек до 2сек, а длинное от 3сек до 5сек. Тогда можно что то реализовать. Если нижний предел короткого не ограничивать, как прога узнает что наступило длинное? Алгоритм - нажали, начали считать время, если отпустили и время в первом диапазоне - короткое, во вторм - длинное.

 
int VRes = analogRead(0); // значение с аналог пина
  if(flag == 0 && VRes<300 && VRes>0) // нажата ли кнопка 1 +
  {
    previousMillis= millis(); // когда нажата
    flag = 1; // состояние что нажата
    Serial.println("IF 1");   
  }
  if(flag == 1 && VRes<300 && VRes>0 && ((millis()-previousMillis) > TimePush&&regim ==0)){
 regim = 1;
 flag =2;
    Serial.println("IF 2");
  }// выполняем первый режим работы прибавление 5 ед.
  if(analogRead(0) > 1000 && flag ==2) 
  {
    flag = 0; //кнопка отжата 
    Serial.println("IF 3");
    if(millis()-previousMillis<TimePush&&regim ==0)
    {
   regim = 2;
      Serial.println("IF 4");
    } //прибавление единицы
  }

Так вроде же IF 1 - это кнопка нажата, IF 2 - если 2 сек была нажата, IF 3-4  - если мы её отпустили раньше 2 секунд

savdm
Offline
Зарегистрирован: 03.02.2015
  int VRes = analogRead(0); // значение с аналог пина
  if(flag == 0 && VRes<300 && VRes>0) // нажата ли кнопка 1 +
  {
    previousMillis= millis(); // когда нажата
    flag = 1; // состояние что нажата
    Serial.println("IF 1");   
  }
  if(flag == 1 && VRes<300 && VRes>0 && ((millis()-previousMillis) >= TimePush&&regim ==0)){
    regim = 1;
    flag =2;
    Serial.println("IF 2");
  }// выполняем первый режим работы прибавление 5 ед.
  if(analogRead(0) > 1000 && flag ==1) 
  {

    Serial.println("IF 3");
    if(millis()-previousMillis<TimePush&&regim ==0)
    {
      regim = 2;
      flag = 0; //кнопка отжата 
      Serial.println("IF 4");
    } //прибавление единицы
  }

Вот рабочий вариант только 5 ка срабатывает один раз из-за флага = 2

А если флаг = 0

  if(flag == 1 && VRes<300 && VRes>0 && ((millis()-previousMillis) >= TimePush&&regim ==0)){
    regim = 1;
    flag =2;
    Serial.println("IF 2");

то 5 + 1 срабатывает

Чувствую надо поспать:(

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Зачем вот это условие при отжатии кнопки?

if(millis()-previousMillis<TimePush&&regim ==0)

savdm
Offline
Зарегистрирован: 03.02.2015

Penni пишет:

Зачем вот это условие при отжатии кнопки?

if(millis()-previousMillis<TimePush&&regim ==0)

Нажатие менее 2 сек и выполняется case 2:    Value++;

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

if(regim==0) достаточно. Если оно 0 то это короткое нажатие, т.к. если бы это было длинное нажатие то regim уже был бы 1

savdm
Offline
Зарегистрирован: 03.02.2015

Penni пишет:

if(regim==0) достаточно. Если оно 0 то это короткое нажатие, т.к. если бы это было длинное нажатие то regim уже был бы 1

Тогда без всяких нажатий пойдет цикл) Или большими бросками будет считать. Думаю что тут что то с флагами, но сам не могу понять

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Куда он пойдет? Если перед ним еще одно условие с флагом и значением... Никуда оно не пойдет.

savdm
Offline
Зарегистрирован: 03.02.2015

Penni пишет:

На это обратите пожалуйста внимание, как ограничить прибавления в след 5 ке. Например жму две секунды и не успеваю отжать как уже 5 +1 получилось

 


void click1()
{
  int VRes = analogRead(0); // значение с аналог пина
   if(flag == 0 && VRes<300 && VRes>0) // нажата ли кнопка 1 +
  {
    previousMillis= millis(); // когда нажата
    flag = 1; // состояние что нажата
    Serial.println("IF 1");   
  }
  if(flag == 1 && VRes<300 && VRes>0 && ((millis()-previousMillis) >= TimePush&&regim ==0)){
    regim = 1;
    flag =2;
    Serial.println("IF 2");
  }// выполняем первый режим работы прибавление 5 ед.
  if(analogRead(0) > 1000 && flag ==1&&regim ==0) 
  {

    Serial.println("IF 3");
    if(millis()-previousMillis<TimePush)
    {
      regim = 2;
      flag = 3; //кнопка отжата 
      Serial.println("IF 4");
    } //прибавление единицы
  }

  }
  switch(regim) 
  {
  case 1:
    Value+=5;
    regim=0;
    flag=0;
    break;
  case 2:
    Value++;
    regim=0;
    flag=0;
    break;


Вот решил всё флагами и режимами, как сделать, но остается проблема, как единовременное нажатие +5 и 1 не делалось !??

 

savdm
Offline
Зарегистрирован: 03.02.2015

Penni пишет:

Куда он пойдет? Если перед ним еще одно условие с флагом и значением... Никуда оно не пойдет.

Проверил, без нажатия, если оставил regim==0 или вместе с flag==1 при нажатии летит значение

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Сделайте так примерно

void click1()
{
  int VRes = analogRead(0); // значение с аналог пина
  if(flag == 0 && VRes<300 && VRes>0) // нажата ли кнопка 1 +
  {
    previousMillis= millis(); // когда нажата
    flag = 1; // состояние что нажата
    Serial.println("IF 1");   
  }
  if(flag == 1 && VRes<300 && VRes>0 && ((millis()-previousMillis) >= TimePush))
  {    
    flag =2;
    Serial.println("IF 2");
  }// выполняем первый режим работы прибавление 5 ед.
  if(analogRead(0) > 1000 && flag > 0) 
  {
    // отпустили кнопку смотрим сколько её держали
    switch(flag)
    {
      case 1:
        regim=2; // короткое нажатие        
        break;
      case 2:
        regim=1; // длинное нажатие        
        break;
    }
    flag = 3; //кнопка отжата
  } //прибавление единицы

  switch(regim) 
  {
  case 1:
    Value+=5;
    regim=0;
    flag=0;
    break;
  case 2:
    Value++;
    regim=0;
    flag=0;
    break;
  }
}

 

savdm
Offline
Зарегистрирован: 03.02.2015

Penni пишет:

Сделайте так примерно

void click1()
{
  int VRes = analogRead(0); // значение с аналог пина
  if(flag == 0 && VRes<300 && VRes>0) // нажата ли кнопка 1 +
  {
    previousMillis= millis(); // когда нажата
    flag = 1; // состояние что нажата
    Serial.println("IF 1");   
  }
  if(flag == 1 && VRes<300 && VRes>0 && ((millis()-previousMillis) >= TimePush))
  {    
    flag =2;
    Serial.println("IF 2");
  }// выполняем первый режим работы прибавление 5 ед.
  if(analogRead(0) > 1000 && flag > 0) 
  {
    // отпустили кнопку смотрим сколько её держали
    switch(flag)
    {
      case 1:
        regim=2; // короткое нажатие        
        break;
      case 2:
        regim=1; // длинное нажатие        
        break;
    }
    flag = 3; //кнопка отжата
  } //прибавление единицы

  switch(regim) 
  {
  case 1:
    Value+=5;
    regim=0;
    flag=0;
    break;
  case 2:
    Value++;
    regim=0;
    flag=0;
    break;
  }
}

 

Идеально!!!!!  Очень благодарен, что помогли!!! А то я уже паниковать начинал, пойду теперь посплю, дело сделано. Приобрел для себя неоценимый опыт.

savdm
Offline
Зарегистрирован: 03.02.2015

Добавил еще защиту и разделил переменные flag

if (flag1==3&&flag==0||flag1==0&&flag==3) //Защита при одновременном нажатии двух кнопок
{
  flag1=0;
  flag=0;
}
	switch (regim)
	{
	case 1:
		Value += 5;
		regim = 0;
		flag = 0;
		break;
	case 2:
		Value++;
		regim = 0;
		flag = 0;
		break;
	case 3:
		Value -= 5;
		regim = 0;
		flag1 = 0;
		break;
	case 4:
		Value--;
		regim = 0;
		flag1 = 0;
		break;
	}

Теперь как Швейцарские часы работает))