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

eNOT

✩✩✩✩✩✩✩
11 Май 2020
20
0
Добрый день. Возможно кто-либо сталкивался с данным вопросом.
Имеется мотор редуктор 12в 0.3А примерно в нагрузке(нужен взамен китайского сервопривода). Внутри редуктора есть плата и потенциометр для обратной связи,на шестерне контакты, на плате дорожки, аналогично, как в мультиметре.(данный мотор управляет климатконтролем на микрухе тошиба(других обозначений нет на ней,да и не нужна она) и ручкой аля газовая плита "САРАТОВ".
Суть в том чтоб ручку заменить двумя кнопками.
Итак,дано:
Моторредуктор с обратной связью в виде потенциометра внутри корпуса.
Шилд L293D.
2 тактовых NO кнопки.
Ардуино уно от дядюшки Мадэинчина.


Код:
#include <AFMotor.h>     // подключаем библиотеку для шилда

AF_DCMotor motor1(1); // подключаем мотор к клеммникам M1

#define POT A0 //центральный провод встроенного потенциометра, крайние подключены на GND и 5v

#include <GyverButton.h> // библиотека кнопок

GButton BUT1(5);

GButton BUT2(6); // назначение пинов кнопок



//при нажатии BUT1 в сериал выводится значение от 234 до 29

//при нажатии BUT2 в сериал выводится значение от 29 до 234



int val = 0; // переменная потенциометра





void setup()

{

  motor1.setSpeed(255); // задаем максимальную скорость мотора

  motor1.run(RELEASE);   // останавливаем мотор

  Serial.begin(9600);

}



void loop()

{

  BUT1.tick();

  BUT2.tick();

  val = analogRead(POT);           // Читаем значения с потенциометра

  val = map(val, 0, 1023, 0, 255); // диапазон значений от 0 до 255



  Serial.println(val); // вывод значений в порт





  if (BUT1.isPress())

  {

    motor1.run(FORWARD);  // задаем движение вперед

    motor1.setSpeed(255);   // задаем скорость движения



delay (6000); // 6 секунд от крайнего до крайнего положения при 10в на моторе

    motor1.run(RELEASE); // остановка мотора

  }



  if (BUT2.isPress())

  {

    motor1.run(BACKWARD);  // задаем движение вперед

    motor1.setSpeed(255);   // задаем скорость движения



delay (6000); // 6 секунд от крайнего до крайнего положения при 10в на моторе

    motor1.run(RELEASE); // остановка мотора

  }

}
Все в принципе работает, но хочу уйти от delay, что немаловажно, после motor1.run(RELEASE) на клеммах шилда , куда подключен мотор напруга пропадает(как и положено).
Пытаюсь использовать val для установки значения при котором происходит событие motor1.run(RELEASE), но все бестолку. Либо вообще отказывается работать, либо поворачивается от крайнего до крайнего положения (29 и 234) и напруга не отключается.
При работе с обычной сервой добился еще некоего промежуточного(центрального положения). То есть нажал на BUT1серва повернулась с 0 до 90, нажал еще раз и повернулась с 90 до 180, вторая кнопка делает все тоже самое, но в обратную сторону. С данным моторредуктором такое вряд ли проканает(Если это возможно, подскажите как).

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

Пытался приростить от старой китайской сервы начинку на этот мотор, худо бедно он стронулся с места от 5вольт, но плата управления сервой нагрелась так, что на второй эксперимент не рискнул.
Возможно ли использовать данные моторредукторы с тем функционалом , который описан в скетче ниже для обычных китайских серв? Если да, то подскажите как именно.
Код с нормальными сервами ардуино:


Код 2:
#define PIN 0        // кнопка подключена сюда (PIN --- КНОПКА --- GND)

#define PIN 1        // кнопка подключена сюда (PIN --- КНОПКА --- GND)

#define PIN 7        // кнопка подключена сюда (PIN --- КНОПКА --- GND)

#define PIN 6        // кнопка подключена сюда (PIN --- КНОПКА --- GND)

#define PIN 14        // кнопка подключена сюда (PIN --- КНОПКА --- GND)

#define PIN 15        // кнопка подключена сюда (PIN --- КНОПКА --- GND)

#define PIN 16        // кнопка подключена сюда (PIN --- КНОПКА --- GND)

#define PIN 17        // кнопка подключена сюда (PIN --- КНОПКА --- GND)

#define MODE_AM 5    // количество режимов (от 0 до указанного)

#include <GyverButton.h> //библиотека кнопок

#include <Servo.h>  //библиотека серво





Servo servo1;

Servo servo2;                 //добавляем сервы

GButton button1(14);

GButton button2(15);

GButton button3(16);

GButton button4(17);// кнопки серво 1 (А0-А3)

GButton button5(0);

GButton button6(1); // кнопки серво2

GButton button7(6);

GButton button8(7); // кнопки переключения реле



int relay1 = 2;

int relay2 = 3;

int relay3 = 5;

int relay4 = 4; // пины реле



byte Mode = 0; // переменная положения серво2

byte rel = 0;  // переменная режима реле



void setup()



{

  servo1.attach(9);

  servo1.write(45);

  servo2.attach(8);

  servo2.write(45); // определение пинов серво1 и серво2, указание начального угла



  pinMode(relay1, OUTPUT);

  pinMode(relay2, OUTPUT);

  pinMode(relay3, OUTPUT);

  pinMode(relay4, OUTPUT); // определение пинов реле, как выход



  digitalWrite(2, HIGH);

  digitalWrite(3, HIGH);

  digitalWrite(5, HIGH);

  digitalWrite(4, HIGH); // стартовое состояние реле. NO контакты разомкнуты

}



void loop()

{

  button1.tick();

  button2.tick();

  button3.tick();

  button4.tick();

  button5.tick();

  button6.tick();

  button7.tick();

  button8.tick();// опрос кнопок постоянный







  //нажатие кнопки 1

  if (button1.isPress())

  {

    servo1.write(120); // поворот серво1 на 120

  }





  //нажатие кнопки 2

  if (button2.isPress())

  {

    servo1.write(0); // поворот серво1 на 0

  }





  //нажатие кнопки 3

  if (button3.isPress())

  {

    servo1.write(30); // поворот серво1 на 30

  }





  //нажатие кнопки 4

  if (button4.isPress())

  {

    servo1.write(60); // поворот серво1 на 60

  }





  //нажатие кнопки 5

  if (button5.isPress())

  {

    Mode++;

    if (Mode > 2) Mode = 2; // поворот серво 2 в одном направлении на 2 шага

    servo2.write(Mode * 45); // угол поворота серво2 при нажатии кнопки

  }







  //нажатие кнопки 6

  if (button6.isPress())

  {

    Mode--;

    if (Mode > 2) Mode = 0;// поворот серво 2 в обратном направлении на 2 шага

    servo2.write(Mode * 45); // угол поворота серво2 при нажатии кнопки

  }





  //нажатие кнопки 7



  if (button7.isPress()) //кнопка выбора режима реле

  {

    if (--rel >= MODE_AM) rel = 0; //декремент режима

    switchTask(); //переключение

  }



  //нажатие кнопки 8

  if (button8.isPress()) //кнопка выбора режима реле

  {

    if (++rel >= MODE_AM) rel = 5; //инкремент режима , количество режимов =5 , включая режим all off

    switchTask();

  }

}

  void switchTask()

  {

    switch (rel)

    {

      case 0: task_0();

        break;

      case 1: task_1();

        break;

      case 2: task_2();

        break;

      case 3: task_3();

        break;

      case 4: task_4();

        break;

    }

  }



// Переключение реле

void task_0()

{

  digitalWrite(2, HIGH);

  digitalWrite(3, HIGH);

  digitalWrite(5, HIGH);

  digitalWrite(4, HIGH);

}

void task_1()

{

  digitalWrite(2, LOW);

  digitalWrite(3, HIGH);

  digitalWrite(5, HIGH);

  digitalWrite(4, HIGH);

}

void task_2()

{

  digitalWrite(2, HIGH);

  digitalWrite(3, LOW);

  digitalWrite(5, HIGH);

  digitalWrite(4, HIGH);

}

void task_3()

{

  digitalWrite(2, HIGH);

  digitalWrite(3, HIGH);

  digitalWrite(5, LOW);

  digitalWrite(4, HIGH);

}

void task_4()

{

  digitalWrite(2, HIGH);

  digitalWrite(3, HIGH);

  digitalWrite(5, HIGH);

  digitalWrite(4, LOW);

}

Если данный пост противоречит правилам форума, прошу удалить его. За ранее спасибо, всем ответившим. Скажу сразу, с ардуино я не то , чтоб на " Вы", а скажем так, на "Ваше величество". Очень прошу в ответах не использовать сленг , абривиатуры и оскорбления с посыланием в гугл. Буду безмерно признателен за развернутые ответы.
 
Последнее редактирование:

kostyamat

★★★★★★✩
29 Окт 2019
1,604
775
Для начала, отредактируйте свое сообщение, поместив весь код в теги для кода, а то читать неудобно, аж глаза слезяться. 2020-05-11_23.51.55.jpg
Таким образом больше народу захотят вам помогать.

Второе: в первом скетче я не вижу, что вы каким то образом обрабатываете значения переменной val. Вы ее просто читаете и все. И зачем вы ее мапите к 255, таким образом уменьшая точность?
Delay() в вашем скетче вообще не нужны. Таким образом вы останавливаете вращение loop, соответственно analogRead() работает единственный раз от начала вашего алгоритма, и до конца. Вы уж определитесь, вам нужно крутить мотор по задержке, или по значению переменной?
 
  • Лойс +1
Реакции: eNOT и Shalom

eNOT

✩✩✩✩✩✩✩
11 Май 2020
20
0
Спасибо за замечания.
1)Пост отредактировал.
2)Я пробовал считывать val от 0 до 1023 без map. Ситуация была такая же.
Точный код не вспомню,т.к. черновик не сохранил, но вроде было вот так:


Код:
 if (BUT1.isPress() && val > 200)

  {

    motor1.run(FORWARD);  // задаем движение вперед

    motor1.setSpeed(255);   // задаем скорость движения

}

if (val = 30)
{

    motor1.run(RELEASE); // остановка мотора

  }



  if (BUT2.isPress() && val > 50)

  {

    motor1.run(BACKWARD);  // задаем движение вперед

    motor1.setSpeed(255);   // задаем скорость движения

  }

if (val = 230 ) {

    motor1.run(RELEASE); // остановка мотора
}
 
Последнее редактирование:

kostyamat

★★★★★★✩
29 Окт 2019
1,604
775
if (BUT1.isPress() && val > 200)
А зачем тут дополнительное условие val>200? А если другие значения val, отличные от 200. То что, мотор должен стоять как вкопанный? Потом вы проверяете val == 30, но вместо сравнивания == делаете приравнивание =. Должно быть if (val == 30) - это жёсткий залёт. На который нарываются новички. Вон и ниже тоже самое, val=230.

Вы бы вставили Serial.println(val), и смотрели бы как ваш val меняется. Может у вас ещё и переменный резистор не в ту сторону крутиться.
 
Последнее редактирование:
  • Лойс +1
Реакции: eNOT

eNOT

✩✩✩✩✩✩✩
11 Май 2020
20
0
Спасибо Вам за ответ. Я не отрицаю того, что я новичок, поэтому и обратился.

Подскажите, как лучше организовать условия при нажатии. Если кнопка1 поворачивает привод пока тот с отметки 234 не достигнет отметки 29. Кнопка2 с 29 до 234. Но хочу слегка ограничить эти значения например 30 и 230
 

kostyamat

★★★★★★✩
29 Окт 2019
1,604
775
Надеюсь разберетесь, если нет - обращайтесь. (в железе не проверял, могут быть опечатки и упущения, но код компилируется чисто)
C++:
#include <AFMotor.h>     // подключаем библиотеку для шилда

AF_DCMotor motor1(1); // подключаем мотор к клеммникам M1

#define POT A0 //центральный провод встроенного потенциометра, крайние подключены на GND и 5v

#include <GyverButton.h> // библиотека кнопок

GButton BUT1(5);
GButton BUT2(6); // назначение пинов кнопок





void setup() {
   motor1.run(RELEASE);   // останавливаем мотор
  Serial.begin(9600);

}



void loop() {
  uint16_t val = 0;              // Переменная для считывания значения потенциометра
  static bool running = false;    // Флаг, указывающий на то, что мотор в движении. static делает так, что переменная сохраняет свое значение каждый оборот loop
  static byte speed = 0;

  if (!running) {                 // Блокируем по флагу кнопки, пока мотор в движении.
    BUT1.tick();
    BUT2.tick();
  }

  if (running) {         // А тут наоборот, читаем потенциометр по флагу, то-есть пока мотор в движении
    val = analogRead(POT);           // Читаем в цикле loop значения с потенциометра
    Serial.println(val); // вывод значений в порт
  }

  if (BUT1.isClick()) {    // Если был клик по кнопке 1
    motor1.run(FORWARD);  // задаем движение вперед
    Serial.println(F("Forward"));
    running = true;
  }

  if (BUT2.isClick()) {    // Если был клик по кнопке 2
    motor1.run(BACKWARD);  // задаем движение назад
    Serial.println(val); // вывод значений в порт
    Serial.println(F("Backward"));
    running = true;
  }

  if (running and speed < 255) {   // стоит флаг, что мы в движении, медленно разганяем мотор. пока не достигли значения 255,
    speed++;                                     // увеличиваем скорость на 1
    motor1.setSpeed(speed);        // устанавливаем скорость мотора
    delay(2);                 // пока мотор будет разганятся, loop будет подтормаживаться на время разгона, Это 255*delay ~ 0.5сек.
  }

  if ((val >= 100 and val <= 110) or (val >= 900 and val <= 910)) {             // если достигли одного или другого крайнего положения 
                                      // (слишком точное значение ставить не стоит, легко проскочить). Тут можно свои значения поставить. 
                                      // Мапить к 255 не стоит, точность позиции падает
    running = false;  // приехали, сбрасываем флаг, соответственно кнопки разблокируются
    speed = 0;
    motor1.run(RELEASE); // остановка мотора
    Serial.println(val); // вывод значений в порт
    Serial.println(F("Stop"));
  }
}
 
Последнее редактирование:
  • Лойс +1
Реакции: eNOT

kostyamat

★★★★★★✩
29 Окт 2019
1,604
775
@eNOT, и что, работает как задумывалось?
Там походу не хватает начального позиционирования при старте с выключенного состояния, а так же защиты от дурака, когда мотор уже стоит в крайнем положение, а юзер снова жмёт кнопку для движения в то же направление.
 
Последнее редактирование:

kostyamat

★★★★★★✩
29 Окт 2019
1,604
775
Вот сейчас только подумалось, там ошибка у меня. ((
Ок, исправлю потом.
 
  • Лойс +1
Реакции: eNOT

eNOT

✩✩✩✩✩✩✩
11 Май 2020
20
0
Попробовал код. При достижении крайних положений двигатель отказывается ехать по нажатию кнопок. С заданием этих условий для движения и остановки у меня серьезные проблемы. если нет похожего примера под рукой. Скрин из порта прилагаю. Еще раз спасибо Вам за помощь. Попробую методом тыка поиграть с условиями.

PS:в своем коде по Вашему замечанию поставил == и вроде как заработало. По достижению крайних заданных положений питание на шилде отрубается. Но не могу разобраться с флагами в Вашем скетче.
.моторредуктор.jpg
 
Последнее редактирование:

kostyamat

★★★★★★✩
29 Окт 2019
1,604
775
При достижении крайних положений двигатель отказывается ехать по нажатию кнопок.
По условию, что я создал, мотор не хочет ехать, потому как уже приехал. 🤣
Это и есть та ошибка, о которой я и сказал. Было бы железо под рукой, сразу бы понял, что ошибся. А так, прозрение чуть погодя пришло. ))
Чуть позже поправлю.
 

kostyamat

★★★★★★✩
29 Окт 2019
1,604
775
поправил, разнес условия, теперь флаг еще указывает и на направление движения:
#include <AFMotor.h>     // подключаем библиотеку для шилда

AF_DCMotor motor1(2); // подключаем мотор к клеммникам M1

#define POT A0 //центральный провод встроенного потенциометра, крайние подключены на GND и 5v

#include <GyverButton.h> // библиотека кнопок

GButton BUT1(2, LOW_PULL, NORM_OPEN);

GButton BUT2(3, LOW_PULL, NORM_OPEN); // назначение пинов кнопок



//при нажатии BUT1 в сериал выводится значение от 234 до 29

//при нажатии BUT2 в сериал выводится значение от 29 до 234





void setup() {
  motor1.run(RELEASE);   // останавливаем мотор
  Serial.begin(115200);

}



void loop() {
  uint16_t val = 0;              // Переменная для считывания значения потенциометра
  static byte running = 0;    // Флаг, указывающий на то, что мотор в движении. static делает так, что переменная сохраняет свое значение каждый оборот loop
  static byte speed = 0;

  if (running == 0) {                 // Блокируем кнопки, пока мотор в движении
    BUT1.tick();
    BUT2.tick();
  }

  if (running > 0) {   // если флаг указывает на то, что мотор должен двигаться в направлении 1 или 2, 1 = вперед, 2 = назад.
    val = analogRead(POT);           // Читаем в цикле loop значения с потенциометра
    Serial.println(val); // вывод значений в порт
  }

  if (BUT1.isClick()) {    // Если был клик по кнопке 1
    motor1.run(FORWARD);  // задаем движение вперед
    Serial.println(F("Forward"));
    running = 1;
  }

  if (BUT2.isClick()) {    // Если был клик по кнопке 2
    motor1.run(BACKWARD);  // задаем движение назад
    Serial.println(val); // вывод значений в порт
    Serial.println(F("Backward"));
    running = 2;
  }

  if (running > 0 and speed < 255) {   // стоит флаг, что мы в движении, медленно разганяем мотор. пока не достигли значения 255, увеличиваем скорость на 1
    speed++;
    motor1.setSpeed(speed);    // устанавливаем скорость мотора
    delay(2);                 // пока мотор будет разганятся, loop будет подтормаживаться на время разгона, Это 255*delay ~ 0.5сек.
  }

  if ((val >= 100 and val <= 110) and running == 2) { // если достигли одного или другого крайнего положения (слишком точное значение ставить не стоит
    // легко проскочить). Тут можно свои значения поставить. Мапить к 255 не стоит, точность позиции падает
    running = 0;  // приехали, сбрасываем флаг, соответственно кнопки разблокируются, потенциометр не читается.
    speed = 0;
    motor1.run(RELEASE); // остановка мотора
    Serial.println(F("Stop"));
    Serial.println(val); // вывод значений в порт
  }

  if ((val >= 900 and val <= 910) and running == 1) { // если достигли одного или другого крайнего положения (слишком точное значение ставить не стоит
    // легко проскочить). Тут можно свои значения поставить. Мапить к 255 не стоит, точность позиции падает
    running = 0;  // приехали, сбрасываем флаг, соответственно кнопки разблокируются, потенциометр не читается.
    speed = 0;
    motor1.run(RELEASE); // остановка мотора
    Serial.println(F("Stop"));
    Serial.println(val); // вывод значений в порт
  }

}
 
  • Лойс +1
Реакции: eNOT

kostyamat

★★★★★★✩
29 Окт 2019
1,604
775
@eNOT, ну тут вроде есть где-то "лучший ответ" или через модератора, кнопка "жалоба"
 
  • Лойс +1
Реакции: eNOT