Время сработки реле по энкодеру

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Всем добрый!.

Проблема с временем сработки реле. Требуется изменять время сработки реле с помощью энкодера. Время сработки меняю энкодером. Цыфры исправно выводятся на LCD. Но не могу реле упросить работать с этими цыфрами. Реле не срабатывает. Где ошибка?

/*Уставка времени сработки реле энкодером используя 
датчик касания и выставляя время сработки энкодером
*/
 #define relay (6)//цепляем  реле  
 #define sens   (2) //  сенсор
 
 int pinA = 3;  // Pin  CLK энкодера KY-040
 int pinB = 4;  // Pin DT энкодера   KY-040
 int encoderPosCount = 0; 
 int pinALast;  
 int aVal;
 boolean bCW;
 
 #include <Wire.h> 
 #include <LiquidCrystal_I2C.h>
 LiquidCrystal_I2C lcd(0x27,16,2);  // установка  LCD 

 unsigned long currentTime;
 unsigned long loopTime;
 
 void setup() 
 { 
   
   pinMode(2,INPUT_PULLUP);
   pinMode(6,OUTPUT);
   pinMode (pinA,INPUT);
   pinMode (pinB,INPUT);
   // читаем Pin A
   pinALast = digitalRead(pinA);   
   
   lcd.init();   // Инициализируем lcd 
   
   currentTime = millis();       // считываем время, прошедшее с момента запуска программы
   loopTime = currentTime;  
 } 

 void loop() { 
   aVal = digitalRead(pinA);
   if (aVal != pinALast){ // Для определения направления вращения считываем pinВ
     if (digitalRead(pinB) != aVal) {  // Значит правое вращение
       encoderPosCount ++;
       bCW = true;
     } else {
       bCW = false;
       encoderPosCount--;
     }
   
   if(digitalRead(2)==LOW)//если сенсор сработал ...
   {
    digitalWrite(relay, HIGH);//включаем реле
    
    if(currentTime >= (loopTime + encoderPosCount*1000))
    {              // сравниваем текущий таймер с переменной loopTime + время на энкодере в милисек.
    digitalWrite(relay, LOW);     // выключаем реле
    loopTime = currentTime;   
    }
    delay(4000);//пауза 
   } 
   
    /*if(digitalRead(2)==LOW)//если сенсор сработал ...
   {
    digitalWrite(relay, HIGH);//включаем реле
    delay(encoderPosCount*1000);//реле включено  n сек.
    digitalWrite(relay, LOW); //выключаем реле
   
    delay(4000);//пауза 
   } 
   */
      lcd.setCursor(0, 0);
      lcd.print("BPEMA  ");
      lcd.print(encoderPosCount); 
      lcd.print("  Cek  ");
      lcd.setCursor(0, 1);// вывод второй строки
      lcd.print("Chegonibud pishem");
     
   } 
   pinALast = aVal;
 } 

 

T.Rook
Offline
Зарегистрирован: 05.03.2016

А что за сенсор на пине 2? Реле выключается только если на пине 2 Low + прошло время. Так и задумано?

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

когда на сенсоре LOW(pin2) - должно сработать реле. и отработать время заданное энкодером

T.Rook
Offline
Зарегистрирован: 05.03.2016

Повторю вопрос: и выключается когда на пине 2 Low + прошло время. Так и задумано?

Если нет, то вынесите выключение реле из If digitalread(2){}

   if(digitalRead(2)==LOW)//если сенсор сработал ...
   {
    digitalWrite(relay, HIGH);//включаем реле
    loopTime = currentTime; 
   }
   if(currentTime >= (loopTime + encoderPosCount*1000))
    {              // сравниваем текущий таймер с переменной loopTime + время на энкодере в милисек.
    digitalWrite(relay, LOW);     // выключаем реле
    }

 

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

В таком виде?

/*Уставка времени сработки реле энкодером используя 
датчик касания и выставляя время сработки энкодером
*/
 #define relay (6)//цепляем  реле  
 #define sens   (2) //  сенсор
 
 int pinA = 3;  // Pin  CLK энкодера KY-040
 int pinB = 4;  // Pin DT энкодера   KY-040
 int encoderPosCount = 0; 
 int pinALast;  
 int aVal;
 boolean bCW;
 
 #include <Wire.h> 
 #include <LiquidCrystal_I2C.h>
 LiquidCrystal_I2C lcd(0x27,16,2);  // установка  LCD 

 unsigned long currentTime;
 unsigned long loopTime;
 
 void setup() 
 { 
   
   pinMode(2,INPUT_PULLUP);
   pinMode(6,OUTPUT);
   pinMode (pinA,INPUT);
   pinMode (pinB,INPUT);
   // читаем Pin A
   pinALast = digitalRead(pinA);   
   lcd.backlight();
   lcd.init();   // Инициализируем lcd 
   
   currentTime = millis();       // считываем время, прошедшее с момента запуска программы
   loopTime = currentTime;  
 } 

 void loop() { 
   aVal = digitalRead(pinA);
   if (aVal != pinALast){ // Для определения направления вращения считываем pinВ
     if (digitalRead(pinB) != aVal) {  // Значит правое вращение
       encoderPosCount ++;
       bCW = true;
     } else {
       bCW = false;
       encoderPosCount--;
     }
   
   if(digitalRead(2)==LOW)//если сенсор сработал ...
   {
    digitalWrite(relay, HIGH);//включаем реле
    loopTime = currentTime; }
    if(currentTime >= (loopTime + encoderPosCount*1000))
    {              // сравниваем текущий таймер с переменной loopTime + время на энкодере в милисек.
    digitalWrite(relay, LOW);     // выключаем реле
      
    }
         
      lcd.setCursor(0, 0);
      lcd.print("BPEMA  ");
      lcd.print(encoderPosCount); 
      lcd.print("  Cek  ");
      lcd.setCursor(0, 1);// вывод второй строки
      lcd.print("Chegonibud pishem");
     
   } 
   pinALast = aVal;
 } 

 

T.Rook
Offline
Зарегистрирован: 05.03.2016

Если работает так как Вы задумывали, то да :)

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

пока ни как :)

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Нет сигнала на реле при LOW на pin2

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

В таком виде срабатывает, но не отключается.

/*Уставка времени сработки реле энкодером используя 
датчик касания и выставляя время сработки энкодером
*/
 #define relay (6)//цепляем  реле  
 #define sens   (2) //  сенсор
 
 int pinA = 3;  // Pin  CLK энкодера KY-040
 int pinB = 4;  // Pin DT энкодера   KY-040
 int encoderPosCount = 0; 
 int pinALast;  
 int aVal;
 boolean bCW;
 
 #include <Wire.h> 
 #include <LiquidCrystal_I2C.h>
 LiquidCrystal_I2C lcd(0x27,16,2);  // установка  LCD 

 unsigned long currentTime;
 unsigned long loopTime;
 
 void setup() 
 { 
   
   pinMode(2,INPUT_PULLUP);
   pinMode(6,OUTPUT);
   pinMode (pinA,INPUT);
   pinMode (pinB,INPUT);
   // читаем Pin A
   pinALast = digitalRead(pinA);   
   
   lcd.init();   // Инициализируем lcd 
    lcd.backlight();
     lcd.setCursor(1, 0);
  lcd.print("BODOLEY");
   lcd.setCursor(4, 1);
  lcd.print("TEST");
  delay(5000);
  lcd.clear();
   currentTime = millis();       // считываем время, прошедшее с момента запуска программы
   loopTime = currentTime;  
 } 

 void loop() { 
   aVal = digitalRead(pinA);
   if (aVal != pinALast){ // Для определения направления вращения считываем pinВ
     if (digitalRead(pinB) != aVal) {  // Значит правое вращение
       encoderPosCount ++;
       bCW = true;
     } else {
       bCW = false;
       encoderPosCount--;
     }
   
   
      
      lcd.setCursor(0, 0);
      lcd.print("BPEMA  ");
      lcd.print(encoderPosCount); 
      lcd.print("  Cek  ");
      lcd.setCursor(0, 1);// вывод второй строки
      lcd.print("Chegonibud pishem");
     
   } 
   pinALast = aVal;
   
   if(digitalRead(2)==LOW)//если сенсор сработал ...
   {
    digitalWrite(relay, HIGH);//включаем реле
    loopTime = currentTime; }
    if(currentTime >= (loopTime + encoderPosCount*1000))
    {              // сравниваем текущий таймер с переменной loopTime + время на энкодере в милисек.
    digitalWrite(relay, LOW);     // выключаем реле
      
    }
   
 } 

 

T.Rook
Offline
Зарегистрирован: 05.03.2016

Ну давайте думать, чему равно значение переменной CurrentTime  при первом проходе? а при втором и далее?

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

T.Rook пишет:

Повторю вопрос: и выключается когда на пине 2 Low + прошло время. Так и задумано?

Если нет, то вынесите выключение реле из If digitalread(2){}

   if(digitalRead(2)==LOW)//если сенсор сработал ...
   {
    digitalWrite(relay, HIGH);//включаем реле
    loopTime = currentTime; 
   }
   if(currentTime >= (loopTime + encoderPosCount*1000))
    {              // сравниваем текущий таймер с переменной loopTime + время на энкодере в милисек.
    digitalWrite(relay, LOW);     // выключаем реле
    }

 

Ради вселенской справедливости хочу заметить, что есть реле, которые включаются по низкому уровню, поэтому ваш код такие реле будет не включать на строчке "включаем реле", а выключать ;) Причём реле, включающихся по низкому уровню - в природе больше ;)

T.Rook
Offline
Зарегистрирован: 05.03.2016

DIYMan пишет:

Ради вселенской справедливости хочу заметить

:)))) Не путайте его, он и так совсем запутался :)

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Нет. реле высоко уровня. Это сенсор при касании дает LOW

T.Rook
Offline
Зарегистрирован: 05.03.2016

Вячеслав 151 пишет:

Нет. реле высоко уровня. Это сенсор при касании дает LOW

Не отвлекатесь. Вы разобрались с CurrentTime?

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

переписал, заработало как надо.:)

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Нет с CurrentTime не разобрался

T.Rook
Offline
Зарегистрирован: 05.03.2016

А зачем Вам переменная CurrentTime? Ну да ладно. Главное что работает.

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

T.Rook пишет:

Ну давайте думать, чему равно значение переменной CurrentTime  при первом проходе? а при втором и далее?

 loopTime = currentTime; 

always !

хватает же у вас терпения :)

 

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

CurrentTime тикает и тикает. При втором заходе loopTime = currentTime  и при третьем так же. Или что то не так?

T.Rook
Offline
Зарегистрирован: 05.03.2016

Вячеслав 151 пишет:

CurrentTime тикает и тикает.

А покажите нам, в какой строке оно тикает?

unsigned long currentTime;

 

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

в 39ой пост8

T.Rook
Offline
Зарегистрирован: 05.03.2016

И сколько раз оно там тикнет?

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

не понял. разжуйте

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

это же на внутренних таймерах?

T.Rook
Offline
Зарегистрирован: 05.03.2016

Из setup в loop перенесите эту строку чтоб тикало.

millis тикает. а CurrentTime  - это переменная значение которой Вы присваете в 39 строке один раз.

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Перенес. Реле срабатывает от сигнала и не выключается

/*Уставка времени сработки реле энкодером используя 
датчик касания и выставляя время сработки энкодером
*/
 #define relay (6)//цепляем  реле  
 #define sens   (2) //  сенсор
 
 int pinA = 3;  // Pin  CLK энкодера KY-040
 int pinB = 4;  // Pin DT энкодера   KY-040
 int encoderPosCount = 0; 
 int pinALast;  
 int aVal;
 boolean bCW;
 
 #include <Wire.h> 
 #include <LiquidCrystal_I2C.h>
 LiquidCrystal_I2C lcd(0x27,16,2);  // установка  LCD 

 unsigned long currentTime;
 unsigned long loopTime;
 
 void setup() 
 { 
   
   pinMode(2,INPUT_PULLUP);
   pinMode(6,OUTPUT);
   pinMode (pinA,INPUT);
   pinMode (pinB,INPUT);
   // читаем Pin A
   pinALast = digitalRead(pinA);   
   
   lcd.init();   // Инициализируем lcd 
    lcd.backlight();
     lcd.setCursor(1, 0);
  lcd.print("BODOLEY");
   lcd.setCursor(4, 1);
  lcd.print("TEST");
  delay(5000);
  lcd.clear();
   
 } 

 void loop() { 
   aVal = digitalRead(pinA);
   if (aVal != pinALast){ // Для определения направления вращения считываем pinВ
     if (digitalRead(pinB) != aVal) {  // Значит правое вращение
       encoderPosCount ++;
       bCW = true;
     } else {
       bCW = false;
       encoderPosCount--;
     }
   
   
      
      lcd.setCursor(0, 0);
      lcd.print("BPEMA  ");
      lcd.print(encoderPosCount); 
      lcd.print("  Cek  ");
      lcd.setCursor(0, 1);// вывод второй строки
      lcd.print("Chegonibud pishem");
     
   } 
   pinALast = aVal;
   
   if(digitalRead(2)==LOW)//если сенсор сработал ...
   {
    digitalWrite(relay, HIGH);//включаем реле
    currentTime = millis();       // считываем время, прошедшее с мо
    loopTime = currentTime; }
    if(currentTime >= (loopTime + encoderPosCount*1000))
    {              // сравниваем текущий таймер с переменной loopTime + время на энкодере в милисек.
    digitalWrite(relay, LOW);     // выключаем реле
      
    }
   
 } 

 

T.Rook
Offline
Зарегистрирован: 05.03.2016
/*Уставка времени сработки реле энкодером используя 
датчик касания и выставляя время сработки энкодером
*/
 #define relay (6)//цепляем  реле  
 #define sens   (2) //  сенсор
 
 int pinA = 3;  // Pin  CLK энкодера KY-040
 int pinB = 4;  // Pin DT энкодера   KY-040
 int encoderPosCount = 0; 
 int pinALast;  
 int aVal;
 boolean bCW;
 
 #include <Wire.h> 
 #include <LiquidCrystal_I2C.h>
 LiquidCrystal_I2C lcd(0x27,16,2);  // установка  LCD 

 unsigned long currentTime;
 unsigned long loopTime;
 
 void setup() 
 { 
   
   pinMode(2,INPUT_PULLUP);
   pinMode(6,OUTPUT);
   pinMode (pinA,INPUT);
   pinMode (pinB,INPUT);
   // читаем Pin A
   pinALast = digitalRead(pinA);   
   
   lcd.init();   // Инициализируем lcd 
    lcd.backlight();
     lcd.setCursor(1, 0);
  lcd.print("BODOLEY");
   lcd.setCursor(4, 1);
  lcd.print("TEST");
  delay(5000);
  lcd.clear();
   currentTime = millis();       // считываем время, прошедшее с момента запуска программы
   loopTime = currentTime;  
 } 

 void loop() { 
   aVal = digitalRead(pinA);
   if (aVal != pinALast){ // Для определения направления вращения считываем pinВ
     if (digitalRead(pinB) != aVal) {  // Значит правое вращение
       encoderPosCount ++;
       bCW = true;
     } else {
       bCW = false;
       encoderPosCount--;
     }
   
   
      
      lcd.setCursor(0, 0);
      lcd.print("BPEMA  ");
      lcd.print(encoderPosCount); 
      lcd.print("  Cek  ");
      lcd.setCursor(0, 1);// вывод второй строки
      lcd.print("Chegonibud pishem");
     
   } 
   pinALast = aVal;
    currentTime = millis();       // считываем время, прошедшее с мо
   
   if(digitalRead(2)==LOW)//если сенсор сработал ...
   {
    digitalWrite(relay, HIGH);//включаем реле
    loopTime = currentTime; }
    if(currentTime >= (loopTime + encoderPosCount*1000))
    {              // сравниваем текущий таймер с переменной loopTime + время на энкодере в милисек.
    digitalWrite(relay, LOW);     // выключаем реле
      
    }
   
 } 

 

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Да. это работает :)

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Во тонкость, не туда строку вбил ... Спасибо!

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

Ну во те на, а уже пивка взял...

ctrl+T в среде нажимайте почаще, а то код уже нечитаемый становится.

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Куда рыбки прислать? :)

T.Rook
Offline
Зарегистрирован: 05.03.2016

О! Это лучше xDriver-у. У него вон пиво есть!

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

Вячеслав 151 пишет:

Во тонкость, не туда строку вбил ... Спасибо!

Ничего себе, действительно че там, туда строку воткну или сюда...

Это не тонкость, а эллементарная невнимательность или непонимание что делает ваш код.

Ну судя по тому что вы считаете что присвоив переменой значение функции millis(), она сама потом будет инкременироваться, то это второе.

Вот когда вы столкнетесь с настоящими тонкостями, это будете вспоминать как детский лепет.

Удачи.

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Всем спасибо! Приятных снов!