РЕШЕНО Колебания привода.

Тема в разделе "Моторы, сервоприводы, робототехника", создана пользователем arhangel, 27 мар 2020.

  1. arhangel

    arhangel Нерд

    Доброго времени суток. Хотелось бы чтобы меня толкнули в нужном направлении а именно. Хочу собрать себе в машину системку управления заслонками распределения и регулировки температурой подачи воздушного потока в салон. Сама системка собрана (один канал пока), но есть неприятный момент, когда ротор привода устанавливается в заданное положение, он начинает совершать колебательные движения. Роль исполнительного устройства выполняет привод печки ВАЗ МРЗО-1(имеется обратная связь, внутри переменный резистивный элемент). Роль задатчика положения исполнительного механизма выполняет переменный резистор. Приводом управляет ардуина посредством "моста".
    Ну и сам код.
    Код (C++):
    int sensorPin0 = A0; // Пин к которому подключен регулирующий резитор
    int sensorValue0 = 0;
    int sensorPin1 = A1; // Пин к которому подключен измерительный резитор
    int sensorValue1 = 0;

    int sensorPin2 = A2; // Пин к которому подключен регулирующий резитор
    int sensorValue2 = 0;
    int sensorPin3 = A3; // Пин к которому подключен измерительный резитор
    int sensorValue3 = 0;

    int sensorPin4 = A4; // Пин к которому подключен регулирующий резитор оборотов двигателя печки
    int sensorValue4 = 0;

    int val_0=0;         // Приведенное значение регулирующего резистора серводвигатель1
    int val_1=0;         // Приведенное значение измерительного резистора серводвигатель1
    int val_2=0;         // Приведенное значение регулирующего резистора серводвигатель2
    int val_3=0;         // Приведенное значение измерительного резистора серводвигатель2
    int val_4=0;         // Приведенное значение регулирующего резитора оборотов двигателя печки

    int Serv_0 = 7;      // Пин к которому подключен серводвигатель1
    int Serv_1 = 8;      // Пин к которому подключен серводвигатель1
    int Motor = 9;       // Пин к которому подключен двигатель печки
    //int Serv_2 = 7;      // Пин к которому подключен серводвигатель2
    //int Serv_3 = 8;      // Пин к которому подключен серводвигатель2
    int Led_0 = 13;
    //int Led_1 = 13;

    void setup(){
     
      TCCR1A = 0b00000001; // 8bit // Пины D9 и D10 - 62.5 кГц
      TCCR1B = 0b00001001; // x1 fast pwm
      pinMode(Serv_0, OUTPUT); // назначаем пин серводвигатель1 выходом
      pinMode(Serv_1, OUTPUT); // назначаем пин серводвигатель1 выходом
      pinMode(Led_0, OUTPUT);  // назначаем пин  выходом
    //  pinMode(Led_1, OUTPUT);  // назначаем пин  выходом
      pinMode(Motor, OUTPUT);  // назначаем пин  выходом к которому подключен двигатель печки
      digitalWrite(Serv_0,LOW);// установливаем выход в состояние 0
      digitalWrite(Serv_1,LOW);// установливаем выход в состояние 0
      digitalWrite(Led_0,LOW);// установливаем выход в состояние 0
    //  digitalWrite(Led_1,LOW);// установливаем выход в состояние 0  
    }
    void loop(){
      ServLevt();
      ServRiht();
      ServStop();
      LedLevel();
      sensorValue0 = analogRead(sensorPin0);       // Значение с регулирующего резитора
      sensorValue1 = analogRead(sensorPin1);       // Значение с измерительного резитора
    // sensorValue2 = analogRead(sensorPin2);     // Значение с регулирующего резитора
    // sensorValue3 = analogRead(sensorPin3);     // Значение с измерительного резитора
      sensorValue4 = analogRead(sensorPin4);       // Значение с регулирующего резитора печки
      val_0 = map(sensorValue0, 0, 1023, 0, 255);
      val_1 = map(sensorValue1, 270, 600, 0, 255);
    // val_2 = map(sensorValue2, 0, 1023, 0, 255);
    // val_3 = map(sensorValue3, 270, 600, 0, 255);
      val_4 = map(sensorValue4, 0, 1023, 0, 255);
      digitalWrite(Motor,val_4);
    }

    void ServLevt(){
      if ( val_0 >= val_1 ){
    digitalWrite(Serv_0,HIGH);
    digitalWrite(Serv_1,LOW);
    }
      }
    void ServRiht(){
      if(val_0 <= val_1 ) {
    digitalWrite(Serv_0,LOW);
    digitalWrite(Serv_1,HIGH);
    }
      }
    void ServStop(){
      if (val_0 == val_1 ) {
    digitalWrite(Serv_1,LOW);
    digitalWrite(Serv_0,LOW);
    }
      }
    void LedLevel(){
      if (Serv_1>0){
        digitalWrite(Led_0,HIGH);
      }
       else if (Serv_0>0){
      digitalWrite(Led_0,HIGH);
      }
      else{
        digitalWrite(Led_0,LOW);
      }
    }
     
  2. vvr

    vvr Инженерище

    потенциометры шумят , вот у вас и дергается.
    нужно , как минимум, сделать мёртвую зону в условиях изменения положения.
     
  3. parovoZZ

    parovoZZ Гуру

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

    vvr Инженерище

    Ну да, в атмеле этого не знают...
     
  5. arhangel

    arhangel Нерд

    Странно, у меня электронное зажигание на меге8 собрано и работает без вопросов.
     
  6. arhangel

    arhangel Нерд

    а можно меня носом туда сунуть? или примерчик какойто.
     
  7. parovoZZ

    parovoZZ Гуру

    Разве Atmel ардуину проектировал?
     
  8. vvr

    vvr Инженерище

    С паровозами что то обсуждать не возможно.
    Все знает, всегда прав, дуню не любит, но сидит круглосуточно здесь)))))
    В общем всегда дартаньян....
     
    SergeiL нравится это.
  9. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Код (C++):
    void ServStop(){
      if (val_0 == val_1 ) {
    digitalWrite(Serv_1,LOW);
    digitalWrite(Serv_0,LOW);
    }
      }
    В реале так практически не бывает. Тем более в механизмах. Всегда есть погрешность (Poh), на которую надо "ложить" -
    Код (C++):
    if ((val_0 > (val_1  - Poh) ) && (val_0 < (val_1  + Poh))) {
    digitalWrite(Serv_1,LOW);
    digitalWrite(Serv_0,LOW);
    }
      }
    как-то так...
    Можете произвести над неравенствами элементарные арифметические операции, (школа в классе 5м-6м) которые не изменяют неравенств, а только вид записи.. //;>))))))))))))))))))))))
    Это реализация "мертвой зоны" шириной 2 * Poh-уя.
    ПС. Не забудьте про возможную ситуацию с отрицательными числами...
     
    Последнее редактирование: 28 мар 2020
  10. arhangel

    arhangel Нерд

    Благодарю за подсказку. Об отрицательных значениях не забыл. А вот математику 5 - 6 класса забыл :)
     
  11. Ariadna-on-Line

    Ariadna-on-Line Гуру

    1. Зеркальное отображение сторон - неравенства не меняет - типа а > b == b < a
    2. Если к обеим сторонам неравенства прибавит одно и то же число - неравенство сохраняется - типа а > b == (a + c) > (b + c)
    3. Если обе стороны неравенства умножить на одно и то же число не равное нулю ... сохраняется.
    Ну и тд.
    Ничего не меняется, тем не менее часто оченно улучшает "доходчивость" алгоритмов.
     
    Последнее редактирование: 28 мар 2020
  12. Daniil

    Daniil Гуру

    больше нуля*
     
    Ariadna-on-Line нравится это.
  13. arhangel

    arhangel Нерд

    Еще раз Благодарю! Работает. Нашёл еще одну причину, но она аппаратная и связана с питанием.