Привод монитора

simpl1k
Offline
Зарегистрирован: 06.06.2020

Добрый день. Вообщем есть моторизированный монитор который открывается при подаче 12в. Подали 12в монитор открылся, далее есть кнопка (tilt в коде) при нажатии которой монитор по значению потенциометра опускается на определенный угол.

#include <Eeprom24C01_02.h>
#include <Wire.h>

// устанавливаем порты:
const uint8_t motor_in1 = 8;    // номер порта к которому подключен драйвер мотора с входом 1
const uint8_t motor_in2 = 9;    // номер порта к которому подключен драйвер мотора с входом 2
const uint8_t acc = 12;         // номер порта к которому подключен acc
const uint8_t btn_open = 11;    // номер порта к которому подключена кнопка OpenClose
const uint8_t btn_tilt = 10;    // номер порта к которому подключена кнопка Tilt
const uint8_t pot = 1;

// переменные:
bool acc_val = 0;               // переменная для хранения состояния ACC
bool btn_open_close_val = 1;    // переменная для чтения статуса кнопки OpenClose
bool btn_tilt_val = 1;          // переменная для чтения статуса кнопки Tilt

void setup()
{
  delay(200);
   //устанавливаем скорость 9600 бит/сек
  Serial.begin(9600);
 
  // инициализировать порты драйвера электродвигателей:
  pinMode(motor_in1, OUTPUT);
  pinMode(motor_in2, OUTPUT);
 
// инициализировать кнопки в качестве входа:
  pinMode(btn_open, INPUT_PULLUP);
  pinMode(btn_tilt, INPUT_PULLUP);

// инициируем порт потенциометра
  pinMode(pot, INPUT);
}

// адреса eeprom
const byte address = 0;

void loop()
{
acc_val = digitalRead(acc); // читаем состояние значения ACC:

btn_open_close_val = digitalRead(btn_open);
btn_tilt_val = digitalRead(btn_tilt);  
 
pot_val = analogRead(pot) / 4;
Serial.println(pot_val);

if (acc_val == HIGH) { // если на acc пришел сигнал 12+
   if (pot_val <= 30) {  //если монитор закрыт то.
    digitalWrite(motor_in1, HIGH); // открываем монитор
    do {
        Serial.println("motor up"); //
        delay(50);          // подождать, пока датчик стабилизируется
        pot_val = analogRead(pot) / 4; // проверить датчик
        }
        while (pot_val < 220); // если крышка поднялась то сигнал будет больше 220, цикл разрывается
        digitalWrite(motor_in1, LOW); // отключаем мотор для поднятия крышки
      }
        else {
          tilt();
          }

   }
void tilt()
{
    if (btn_tilt_val == LOW && pot_val == constrain(pot_val, 180, 256))
    {
    if (pot_val >= 218)
      {
      digitalWrite(motor_in2, HIGH);
      {
      delay(50);          
      pot_val = analogRead(pot) / 4;
      }
      while (pot_val > 216);
      digitalWrite(motor_in2, LOW);
      }

     
    else if (pot_val == constrain(pot_val, 200, 216))
      {
      digitalWrite(motor_in2, HIGH);
      do
      {
      delay(50);          
      pot_val = analogRead(pot) / 4;
      }
      while (pot_val > 198);
      digitalWrite(motor_in2, LOW);
      }
      else if (pot_val == constrain(pot_val, 180, 190))
      {
      digitalWrite(motor_in1, HIGH);
      do
      {
      delay(50);          
      pot_val = analogRead(pot) / 4;
      }
      while (pot_val < 220  );
      digitalWrite(motor_in1, HIGH);
      }
    }
  else
    {
    digitalWrite(motor_in1, LOW); // отключаем мотор  
    digitalWrite(motor_in2, LOW); // отключаем мотор
    }

   
}

Теперь 2 вопроса.

1. Я хочу добавить доп. кнопку опен, она должна закрывать монитор даже если поданы 12в, я добавил условие для нее через if , и такая проблема, при нажатии кнопки монитор закрывается, НО тут же открывается, потому что начинает выполняться условие if (acc_val == HIGH) { , т.е как мне сделать что бы ACC как бы отслеживал, если кнопка опен была нажата , то не начинал отслеживать значение потенциометра и выполнять свой цикл?) /Надеюсь понятно объяснил.

2. В блоке void tilt при нажатии кнопки меняться положение монитора, и я заметил такой момент, если зажать кнопку tilt то монитор начинает двигаться из начального положения в третье непрерывно, туда сюда.



Драйвер движка l293b если это имеет роль.



Заранее спасибо за подсказки.

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

Как же назвать кнопку, которая закрывает монитор? - очевидно "open" :)
А если серьезно - добавьте в программу переменную-флаг, которая будет указывать, можно ли открывать монитор. В начале программы у этой переменной значение "можно", а после нажатия кнопки опен - нельзя. И прежде чем открывать монитор по условию ACC ==HIGH
сначала смотрите значение этой переменной

simpl1k
Offline
Зарегистрирован: 06.06.2020

А, вы не могли бы в виде кусочка кода подсказать?) Я прекрасно понял вашу подсказку, понял смысл флага, но вот как это условие впихнуть, что то прям я уперся...

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

simpl1k пишет:

я добавил условие для нее через if , и такая проблема, при нажатии кнопки монитор закрывается, НО тут же открывается, потому что начинает выполняться условие if (acc_val == HIGH) { , т.е как мне сделать что бы ACC как бы отслеживал, если кнопка опен была нажата , то не начинал отслеживать значение потенциометра и выполнять свой цикл?) /Надеюсь понятно объяснил.

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

simpl1k
Offline
Зарегистрирован: 06.06.2020

Я ввел 2 переменные

bool btn_open_close_val = 1;   
bool btn_open_close;


btn_open_close = !digitalRead(btn_open);

if(btn_open_close==HIGH&&btn_open_close_val==1){ 
          btn_open_close_val = 0;
          digitalWrite(motor_in2, HIGH);
          do {
            btn_open_close_val = 0;
          delay(50);  
          pot_val = analogRead(pot) / 4; 
          } while (pot_val > 30); {
            digitalWrite(motor_in2, LOW);
            }
       }

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

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

simpl1k пишет:

Я ввел 2 переменные

bool btn_open_close_val = 1;   
bool btn_open_close;


btn_open_close = !digitalRead(btn_open);

if(btn_open_close==HIGH&&btn_open_close_val==1){ 
          btn_open_close_val = 0;
          digitalWrite(motor_in2, HIGH);
          do {
            btn_open_close_val = 0;
          delay(50);  
          pot_val = analogRead(pot) / 4; 
          } while (pot_val > 30); {
            digitalWrite(motor_in2, LOW);
            }
       }

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

выложите весь исправленный код, не пойму что значат эти переменные

simpl1k
Offline
Зарегистрирован: 06.06.2020

#include <Eeprom24C01_02.h>
#include <Wire.h>

// Программа управления монитором

// устанавливаем порты:
const uint8_t motor_in1 = 8;    // номер порта к которому подключен драйвер мотора с входом 1
const uint8_t motor_in2 = 9;    // номер порта к которому подключен драйвер мотора с входом 2
const uint8_t acc = 12;         // номер порта к которому подключен acc
const uint8_t btn_open = 11;    // номер порта к которому подключена кнопка OpenClose
const uint8_t btn_tilt = 10;    // номер порта к которому подключена кнопка Tilt
const uint8_t pot = 1;

// переменные:
bool acc_val = 0;               // переменная для хранения состояния ACC
bool btn_tilt_val = 1;          // переменная для чтения статуса кнопки Tilt
uint16_t pot_val = 0;           // переменная для хранения считываемого значения потенциометра с пересчетом
bool time_bool1 = 0;
bool time_bool2 = 0;

// Добавил 2 переменные для кнопки open
bool btn_open_close_val = 1;     
bool btn_open_close;


//блок времени
long previousMillis2 = 0;   // 
long currentMillis2 = 0;  //
long interval2 = 1000;      
long previousMillis3 = 0;   // 

void setup() 
{
  delay(200);
   //устанавливаем скорость 9600 бит/сек
  Serial.begin(9600);  
  
  // инициализировать порты драйвера электродвигателей:
  pinMode(motor_in1, OUTPUT);
  pinMode(motor_in2, OUTPUT);
  
 // инициализировать кнопки в качестве входа:
  pinMode(btn_open, INPUT_PULLUP);
  pinMode(btn_tilt, INPUT_PULLUP);

 // инициируем порт потенциометра
  pinMode(pot, INPUT);
}

// адреса eeprom 
const byte address = 0;

void loop() 
{
 
 acc_val = digitalRead(acc); 

 btn_tilt_val = digitalRead(btn_tilt);  

 btn_open_close = !digitalRead(btn_open); 

 pot_val = analogRead(pot) / 4; 
    
      // Вот это условие, но не пойму как его правильно применить относительно АСС, если я вообще правильно задаю его.

     if(btn_open_close==HIGH&&btn_open_close_val==1){ 
          btn_open_close_val = 0;
          digitalWrite(motor_in2, HIGH);
          do {
            btn_open_close_val = 0;
          delay(50);        
          pot_val = analogRead(pot) / 4; 
          Serial.println ("+flag");
          } while (pot_val > 30); {
            digitalWrite(motor_in2, LOW);
            }
       } 
     


 if (acc_val == HIGH) { // если на acc пришел сигнал 12+
   if (pot_val <= 30) {  
    digitalWrite(motor_in1, HIGH);
    do {
        Serial.println("motor up"); // 
        delay(50);         
        pot_val = analogRead(pot) / 4; 
        }
        while (pot_val < 220); 
        digitalWrite(motor_in1, LOW);
        Serial.println("Monitor open!"); 
      } 
        else {
          tilt();
          } 

   } else { // если acc выключен то 
    previousMillis3 = 0;
  time_bool2 = 0;
    if (pot_val >= 98) 
      {
    if (time_bool1 == 0)
    {
    previousMillis2 = millis();  
    time_bool1 = 1;
    Serial.println("5 seconds before shutdown");  
    delay(10);
    }
    else if (time_bool1 == 1)
    {
    currentMillis2 = millis();  
      if (currentMillis2 - previousMillis2 > interval2)
        {
          previousMillis2 = currentMillis2; 
          time_bool1 = 0;
          digitalWrite(motor_in2, HIGH); 
          do 
          {
          delay(50);        
          pot_val = analogRead(pot) / 4; 
          } 
          while (pot_val >= 30); 
          digitalWrite(motor_in2, LOW);
          Serial.println("Monitor closed!"); 
        }
      else
        {
        }
    }
      }
    else  //если монитор закрыт
    {
      digitalWrite(motor_in1, LOW);
      digitalWrite(motor_in2, LOW);   
    }
   }
 }
 
void tilt()
{
    if (btn_tilt_val == LOW && pot_val == constrain(pot_val, 180, 256)) 
    {
    if (pot_val >= 218) 
      {
      digitalWrite(motor_in2, HIGH); 
      do 
      {
      delay(50);        
      pot_val = analogRead(pot) / 4; 
      } 
      while (pot_val > 216); 
      digitalWrite(motor_in2, LOW); 
      Serial.println("Monitor in position 2!");
      }

      
    else if (pot_val == constrain(pot_val, 200, 216))
      {
      digitalWrite(motor_in2, HIGH);
      do 
      {
      delay(50);         
      pot_val = analogRead(pot) / 4; 
      } 
      while (pot_val > 198);
      digitalWrite(motor_in2, LOW); 
      Serial.println("Monitor in position 3!"); 
      }

      
      else if (pot_val == constrain(pot_val, 180, 190)) 
      {
      digitalWrite(motor_in1, HIGH);
      do
      {
      delay(50);         
      pot_val = analogRead(pot) / 4; 
      } 
      while (pot_val < 220  ); 
      digitalWrite(motor_in1, HIGH); 
      Serial.println("Monitor in position 1!"); 
    }

    
  else 
    {
    digitalWrite(motor_in1, LOW); // отключаем мотор    
    digitalWrite(motor_in2, LOW); // отключаем мотор
    } 

   
}

В коде отметил переменные и условие

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

в строке 81 в условие добавьте

&& btn_open_close_val==1

пробуйте.

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

Чтобы монитор можно было и открывать и закрывать когда угодно - нужно чуть сменить концепцию. Пусть нажатие на кнопку "опен" не включает мотор непосредственно, как у вас в коде сейчас - а только меняет переменную  btn_open_close_val.   А открывать или закрывать монитор при нажатии кнопки - программа должна решать не только по этой переменной, но и положению потенциометра

simpl1k
Offline
Зарегистрирован: 06.06.2020

b707 пишет:

в строке 81 в условие добавьте

&& btn_open_close_val==1

пробуйте.

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

Чтобы монитор можно было и открывать и закрывать когда угодно - нужно чуть сменить концепцию. Пусть нажатие на кнопку "опен" не включает мотор непосредственно, как у вас в коде сейчас - а только меняет переменную  btn_open_close_val.   А открывать или закрывать монитор при нажатии кнопки - программа должна решать не только по этой переменной, но и положению потенциометра

Я уже пробовал так делать) и да, абсолютно верно, монитор закрывается и более не открывается до перезапуска. Спасибо, буду сейчас пытаться завязать на потенциометр. А, само условие в целом я правильно внес с флагом? что бы я дальше его мог "развивать". 

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

вы движетесь правильно.

Из условия строки 66 уберите значение кнопки. оставьте только переменную ....val. А для нажатия кнопки сделайте отдельное условие. где только инвертируйте эту переменную val. больше ничего. Все должно получится

swatcool74
Offline
Зарегистрирован: 13.10.2022

хочу спросить. Могли бы вы поделиться схемой подключения для данного проекта очень хочется его повторить. Заранее спасибо.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

swatcool74 пишет:

хочу спросить. Могли бы вы поделиться схемой подключения для данного проекта очень хочется его повторить. Заранее спасибо.

да какая схема, бери да подключай, строки в начале скетча

swatcool74
Offline
Зарегистрирован: 13.10.2022

Я не знаю какой мотор использовался в данном проекте. И ещё вопрос по подключению драйвера двигателя.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

swatcool74 пишет:
Я не знаю какой мотор использовался в данном проекте. И ещё вопрос по подключению драйвера двигателя.

Драйвер движка l293b если это имеет роль.
Судя по скетчу - постоянного тока