Управление приводом

egor-mav

И снова здравствуйте, и снова нужна ваша помощь.
к предыдущему скетчу пытаюсь добавить кнопку:

int motorPin = 10; // мотор подключен к цифровому выводу 10
int analogPin = A0; // потенциометр подключен к аналоговому выходу А0
int buttom1Pin = 22; // кнопка подключен к входу 22
int val = 0; // переменная для хранения считанного значения с потенциометра
int openn = 0; // переменная для хранения считанного значения с потенциометра

void setup() {

pinMode(motorPin, OUTPUT); // переключение вывода в режим “выход”

}

void loop() { // этот цикл выполняется бесконечное количество раз

val = analogRead(analogPin); // записываем в переменную показания с потенциометра
if (digitalRead(buttom1Pin) == HIGH) {
do {
if (val<500) {
analogWrite(motorPin, 255); // если переменная меньше 700 включаем ШИМ на полную
}
if (val>500&&val<1000) {
analogWrite(motorPin, 150); // если переменная меньше от 700 до 1000 убавляем ШИМ на некоторое значение
}
if (val>1000) {
analogWrite(motorPin, 0); // если переменная меньше больше 1000 отрубаем ШИМ
}
}while (val>1000);
}
}

Но, при симуляции в протеусе происходит следующее:

  1. начальные параметры, кнопка не нажата, переменник в нуле, мотор не крутится;
  2. при нажатии кнопки начинает вращатся мотор с максимальной скоростью;
  3. начинаю “крутить” переменник, скорость мотора изменяется согласно алгоритма скетча;
  4. при достижении переменника 100%, мотор останавливается.
    Вроде все хорошо, но…
    Если я правильно понимаю свой скетч, то после всех этих действий, изменении положения резистора и повторного нажатия кнопки цикл (do-while) должен запустится заново, и мотор снова должен вращатся по алгоритму, но этого почему-то не происходит…
    В чем проблема?
22 days later
egor-mav

Не знаю, смотрит кто нибудь эту тему или нет…
Переделал предыдущий скетч теперь все работает.

int motorPin1 = 10; // мотор подключен к цифровому выводу 10
int motorPin2 = 11; // мотор подключен к цифровому выводу 11 (реверс)
int analogPin = A0; // потенциометр подключен к аналоговому выходу А0
int buttom1Pin = 22; // АЦЦ
int buttom2Pin = 23; // кнопка подключен к входу 22
int val = 0; // переменная для хранения считанного значения с потенциометра
int openn = 0; // переменная фиг знает для чего

void setup() {

pinMode(motorPin1, OUTPUT); // переключение вывода в режим “выход”
pinMode(motorPin2, OUTPUT); // переключение вывода в режим “выход”

}

void loop() { // этот цикл выполняется бесконечное количество раз
val = analogRead(analogPin);
if (digitalRead(buttom2Pin)==HIGH && val<500 && openn == 0) {
openn = 1;
}
if (digitalRead(buttom2Pin)==HIGH && val>500 && openn == 0) {
openn = 2;
}

if (openn == 1) {
if (val < 250) {
analogWrite(motorPin1, 255); // если переменная меньше 700 включаем ШИМ на полную
}
if (val>250 && val < 1000) {
analogWrite(motorPin1, 150); // если переменная меньше от 700 до 1000 убавляем ШИМ на некоторое значение
}
if (val > 1000) {
analogWrite(motorPin1, 0); // если переменная меньше больше 1000 отрубаем ШИМ
openn = 0;
}
}

if (openn == 2) {
if (val > 500) {
analogWrite(motorPin2, 255); // если переменная меньше 700 включаем ШИМ на полную
}
if (val > 100 && val < 500) {
analogWrite(motorPin2, 150); // если переменная меньше от 700 до 1000 убавляем ШИМ на некоторое значение
}
if (val < 100) {
analogWrite(motorPin2, 0); // если переменная меньше больше 1000 отрубаем ШИМ
openn = 0;
}
}
}

Но теперь появились другие проблемы и новые исходные данные. Но это уже совсем другая история 😁

10 days later
egor-mav

Продолжаю тему сам с собой 😁
В качестве контроллера выбрал Arduino Mega 2560 R3 (продавали в моем городе, не хотелось долго ждать с Али).
В качестве драйвера двигателя взята плата L298, спасибо за совет leons.
драйвер пока не пришел с алика, так что пока все тестирую в протеусе.

Схема которую собрал в протеусе (во вложении).
Далее код который написал:

// ----------------------------------------------------------------управления приводом
int motorPin1 = 24; // мотор подключен к цифровому выводу 10
int motorPin2 = 25; // мотор подключен к цифровому выводу 11 (реверс)
int motorPin3 = 10; // мотор подключен к цифровому выводу 10 (PWM)
int analogPin = A0; // потенциометр подключен к аналоговому выходу А0
int buttom1Pin = 22; // АЦЦ
int buttom2Pin = 23; // кнопка подключен к входу 23
int val = 0; // переменная для хранения считанного значения с потенциометра
int openn = 0; // переменная для хранения открытия по кнопке
int opennacc = 0; // переменная для хранения открытия по АСС

int led1 = 51;
int led2 = 52;
int led3 = 53;

unsigned long currentTime;
unsigned long loopTime;

//------------------------------------------------------------------------------------------------------

void setup() {
// ----------------------------------------------------------------управления приводом
pinMode(motorPin1, OUTPUT); // переключение вывода в режим “выход”
pinMode(motorPin2, OUTPUT); // переключение вывода в режим “выход”
pinMode(motorPin3, OUTPUT); // переключение вывода в режим “выход”
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);

currentTime = millis(); // считываем время, прошедшее с момента запуска программы
loopTime = currentTime;

//------------------------------------------------------------------------------------------------------

}

void loop() { // этот цикл выполняется бесконечное количество раз
// ----------------------------------------------------------------управления приводом
val = analogRead(analogPin);
currentTime = millis();

if (digitalRead(buttom1Pin) == HIGH && opennacc == 0 && currentTime >= (loopTime + 10000)) {
opennacc = 1;
loopTime = currentTime;
}

if (digitalRead(buttom1Pin) == LOW && currentTime >= (loopTime + 10000)) {
opennacc = 0;
loopTime = currentTime;
}

if (digitalRead(buttom2Pin) == HIGH && val < 500 && openn == 0 && opennacc == 2) {
openn = 1;
}

if (digitalRead(buttom2Pin) == HIGH && val > 500 && openn == 0 && opennacc == 2) {
openn = 2;
}

if (opennacc == 1) { // открытия привода по АСС
if (val < 700) {
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin1, HIGH);
analogWrite(motorPin3, 255); // если переменная меньше 250 включаем ШИМ на полную
}
if (val >= 700 && val <= 1000) {
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin1, HIGH);
analogWrite(motorPin3, 150); // если переменная меньше от 250 до 1000 убавляем ШИМ на некоторое значение
}
if (val > 1000) {
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin1, LOW);
analogWrite(motorPin3, 0); // если переменная меньше больше 1000 отрубаем ШИМ
opennacc = 2; // открыт по АСС
}
}

if (opennacc == 0) { // Закрытие привода по АСС

if (val > 300) {
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, HIGH);
analogWrite(motorPin3, 255); // если переменная меньше 500 включаем ШИМ на полную
}
if (val >= 20 && val <= 300) {
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, HIGH);
analogWrite(motorPin3, 150); // если переменная от 100 до 500 убавляем ШИМ на некоторое значение
}
if (val < 20) {
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
analogWrite(motorPin3, 0); // если переменная меньше больше 100 отрубаем ШИМ
opennacc = 0;
}
}

if (openn == 1 && opennacc == 2) { //Открытие привода по кнопке
if (val < 700) {
digitalWrite(motorPin1, HIGH);
analogWrite(motorPin3, 255); // если переменная меньше 250 включаем ШИМ на полную
}
if (val >= 700 && val <= 1000) {
digitalWrite(motorPin1, HIGH);
analogWrite(motorPin3, 150); // если переменная меньше от 250 до 1000 убавляем ШИМ на некоторое значение
}
if (val > 1000) {
digitalWrite(motorPin1, LOW);
analogWrite(motorPin3, 0); // если переменная меньше больше 1000 отрубаем ШИМ
openn = 0;
}
}

if (openn == 2) { // Закрытие привода по кнопке
if (val > 300) {
digitalWrite(motorPin2, HIGH);
analogWrite(motorPin3, 255); // если переменная больше 500 включаем ШИМ на полную
}
if (val >= 20 && val <= 300) {
digitalWrite(motorPin2, HIGH);
analogWrite(motorPin3, 150); // если переменная от 100 до 500 убавляем ШИМ на некоторое значение
}
if (val < 20) {
digitalWrite(motorPin2, LOW);
analogWrite(motorPin3, 0); // если переменная меньше меньше 100 отрубаем ШИМ
openn = 0;
}
}

//-------------------------индикация переменной opennacc временно
if (opennacc == 0){
digitalWrite(led1, HIGH);
}else {digitalWrite(led1, LOW);
}

if (opennacc == 1){
digitalWrite(led2, HIGH);
}else {digitalWrite(led2, LOW);
}

if (opennacc == 2){
digitalWrite(led3, HIGH);
}else {digitalWrite(led3, LOW);
}
}
//------------------------------------------------------------------------------------------------------

Вроде все работает… Если не сложно, оцените пожалуйста, может чего лишнего понаписал…

We-BEER
egor-mav:

Если не сложно, оцените пожалуйста, может чего лишнего понаписал…

Номера пинов принято указывать дефайнами, нет смысла хранить их в переменных.

#define MOTOR_PIN1 24; // мотор подключен к цифровому выводу 10
#define MOTOR_PIN2 25; // мотор подключен к цифровому выводу 11 (реверс)
...

соответственно в коде написать

...
pinMode(MOTOR_PIN1, OUTPUT); // переключение вывода в режим "выход"
...

я не большой специалист, но кажется такое:

  if (opennacc == 1) { // открытия привода по АСС
    if (val < 700) {
      digitalWrite(motorPin2, LOW);
      digitalWrite(motorPin1, HIGH);
      analogWrite(motorPin3, 255); // если переменная меньше 250 включаем ШИМ на полную
    }
    if (val >= 700 && val <= 1000) {
      digitalWrite(motorPin2, LOW);
      digitalWrite(motorPin1, HIGH);
      analogWrite(motorPin3, 150); // если переменная меньше от 250 до 1000 убавляем ШИМ на некоторое значение
    }
    if (val > 1000) {
      digitalWrite(motorPin2, LOW);
      digitalWrite(motorPin1, LOW);
      analogWrite(motorPin3, 0); // если переменная меньше больше 1000 отрубаем ШИМ
      opennacc = 2; // открыт по АСС
    }
  }

можно упростить до такого:

  if (opennacc == 1) { // открытия привода по АСС
    digitalWrite(MOTOR_PIN1 HIGH);
    digitalWrite(MOTOR_PIN2, LOW);
    if (val < 700) analogWrite(MOTOR_PIN3, 255);                  // если переменная меньше 250 включаем ШИМ на полную
    if (val >= 700 && val <= 1000) analogWrite(MOTOR_PIN3, 150);  // если переменная меньше от 250 до 1000 убавляем ШИМ на некоторое значение
    if (val > 1000) {
      analogWrite(MOTOR_PIN3, 0);                                 // если переменная меньше больше 1000 отрубаем ШИМ
      digitalWrite(MOTOR_PIN1, LOW);
      opennacc = 2; // открыт по АСС
    }
  }

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

Обычно для обработки кнопок пишут отдельную функцию типа getBTN(), которая фильтрует дребезг и возвращает их состояние, а основная программа уже вызывает эту функцию и действует согласно её ответа. На истину не претендую, просто мысли 😃

egor-mav

ОГО! Спасибо большое за советы! Можно поподробнее насчет функции getBTN()?

We-BEER
egor-mav:

Можно поподробнее насчет функции getBTN()?

схематично как-то так:

void setup() {
  // начальные настройки
}

void loop() {
  // основной код
  switch (getBTN()) {
    case 0:
      // действия еcли ничего не нажато
      break;
    case 1:
      // действия еcли нажата кнопка 1
      break;
    case 2:
      // действия еcли нажата кнопка 2
      break;
  }
}

byte getBTN() {
  byte btn_state;
  // опрос кнопок и фильтрация дребезга
  return btn_state;
}

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

А для борьбы с дребезгом самое простое делать два опроса кнопки с небольшой задержкой, сравнивать результаты и фискировать нажатие только при их совпадении. Примеров в интернетах вагон arduinomaster.ru/…/ustranenie-drebezg-kontaktov-kn…