MAL4X Научно-технический форум разработчиков симуляторов и автоматики


Симуляторы перегрузок. DIY электроника. ЭВМ. Компьютерные сети.
Up

Данные: что передавать и как регулировать

Строим реалистичный симулятор перегрузок своими руками. Рекомендации. Советы.

Модераторы: Death_Morozz, null, Ale

Re: Данные: что передавать и как регулировать

Сообщение kuzevan » 29 ноя 2012, 11:01

Выкладываю обещанную сервисную программу для теста мотора.
Код: Выделить всё
/*
Программа диагностики мотора
Вход:
1 - чтение потенциометра, прекращается вводом любого символа
2 - определение полярности
3 - расчет коэффициентов двигателя
*/
#define INA 8
#define INB 9
#define _PWM 10
#define AT 0
#define CNT 5
#define DEG 300.0

boolean serialIn;
char buf[8];
int pmin,pmax,pot;
int dir;
byte speed_pwm;
long sum;
float a1,a2,k1,k2;
boolean use_pot;

void setup()
{
  pmin=(int)(1024.0*((DEG-180.0)/2)/DEG);
  pmax=(int)(1024.0*((DEG-180.0)/2+180.0)/DEG);
  serialIn=false;
  dir=0;
  speed_pwm=0;
  use_pot=false;
  Serial.begin(9600);
}

void loop()
{
  int i,k;
  if(serialIn){
    serialIn=false;
    use_pot=false;
    switch(buf[0]){
      case '1':
        use_pot=true;
      break;
      case '2':
        pot=analogRead(AT);
        Go(1,255);
        delay(132);
        Go(0,0);
        delay(100);
        i=analogRead(AT);
        if((i-pot)>1)
          Serial.println("OK");
        else if((i-pot)<-1)
          Serial.println("Change pot polarity");
        else
          Serial.println("Error");
        Serial.print("pot=");Serial.println(i);
      break;
      case '3':
        pot=analogRead(AT);
        if(pot>512)
          k=-1;
        else
          k=1;
        sum=0;
        for(i=0;i<10;i++){
          pot=analogRead(AT);
          Go(k,255);
          delay(33*CNT);
          sum+=k*(analogRead(AT)-pot);
          Go(0,0);
          delay(1000);
          k=-k;
        }
        a1=2.0*(float)(map(sum/10,0,pmax-pmin,0,255))/(float)(CNT*CNT);
        pot=analogRead(AT);
       // Serial.println(sum/10);
        //Serial.println(map(sum/10,0,pmax-pmin,0,255));
        if(pot>512)
          k=-1;
        else
          k=1;
        sum=0;
        for(i=0;i<10;i++){
          pot=analogRead(AT);
          Go(k,127);
          delay(33*CNT);
          sum+=k*(analogRead(AT)-pot);
          Go(0,0);
          delay(1000);
          k=-k;
        }
        a2=2.0*(float)(map(sum/10,0,pmax-pmin,0,255))/(float)(CNT*CNT);
        k1=(255.0-127.0)/(a1-a2);
        k2=255.0-k1*a1;
        Serial.print("K1=");Serial.println(k1);
        Serial.print("K2=");Serial.println(k2);
      break;
      default:
      Serial.println("Command error");
    }
  }
  if(use_pot){
    Serial.println(analogRead(AT));
    delay(100);
  }
}

void serialEvent() {
  int i=0;
  while (Serial.available()) {
    // get the new byte:
    buf[i++] = (char)Serial.read();
    delay(2); //для 9600
  }
  serialIn=true;
}

void Go(int d,byte s)
{
  if(d!=dir){
    analogWrite(_PWM,0);
    speed_pwm=0;
    digitalWrite(INA, LOW);
    digitalWrite(INB, LOW);
    if(d==1)
      digitalWrite(INA, HIGH);
    else if(d==-1)
      digitalWrite(INB, HIGH);
    dir=d;
  }
  if(s!=speed_pwm){
    analogWrite(_PWM,s);
    speed_pwm=s;
  }
}

Инструкция для использования:
Программа позволяет провести 3 теста:
1. Проверка потенциометра. Побегут циферки значения потенциометра. Удобно, например, выставить пот на середину. Ввести со встроенной консоли (кнопка "Монитор порта" на окне Ардуино) символ '1'. Останавливает этот режим ввод любого символа.
2. Проверка полярности. Потенциометр должен быть уже связан с двигателем. Немного проворачивает двигатель вверх (в сторону подъема платформы). Если двигатель провернулся в обратном направлении - сменить полярность двигателя и провести тест еще раз. Если консоль отвечает "ОК", значит ОК. Если просит сменить полярность потенциометра, значит сменить. Тест проводится вводом символа '2'.
3. Определение коэффициентов двигателя. После ввода '3' двигатель дергается 20 раз и выдает К1 и К2. Холодный двигатель выдает неверные коэффициенты, поэтому тест надо провести раз 5, пока значения не начнут повторяться.
Аватара пользователя
kuzevan
Парторг
 
Сообщения: 60
Зарегистрирован: 25 окт 2011, 17:17
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Баллы репутации: -6

Re: Данные: что передавать и как регулировать

Сообщение kuzevan » 29 ноя 2012, 12:25

Выкладываю исправленную и дополненную версию программы для Ардуино управления мотором.
Исправлена ошибка, обнаруженная глазастым Ale. Спасибо ему.
В инициализацию добавлены объявления PinMode(), работает и так, но по мануалу положено.
Введена защита от дергания мотора в состоянии покоя.
Код: Выделить всё
/*
V0.2
Программа управления одним двигателем
от управляющей программы Ale
c kuzevan
*/
//ноги Ардуино
#define INA 8
#define INB 9
#define _PWM 10
#define AT 0

#define DEG 300.0
#define K1 84.21
#define K2 46.16
#define MAX_TIME 34

String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete

int pmax,pmin;//мин и макс потенциометра
int dest,last_dest,dest_p,pot,pos,last_pos,dir;
byte speed_pwm;
float acc,v0;
long pwm;
float max_acc;
int timer;
char outputString[]="[000000000000000000000000]";

void setup()
{
  pinMode(INA,OUTPUT);
  pinMode(INB,OUTPUT);
  pinMode(_PWM,OUTPUT);
  pmin=(unsigned int)(1024.0*((DEG-180.0)/2)/DEG);
  pmax=(unsigned int)(1024.0*((DEG-180.0)/2+180.0)/DEG);
  v0=0.0;
  max_acc=(255.0-K2)/K1;
  last_pos=map(analogRead(AT),pmin,pmax,0,255);
  dir=0;
  speed_pwm=0;
  inputString.reserve(32);
  Serial.begin(115200);
}

void loop()
{
  if(stringComplete){
    dest=(byte)inputString.charAt(3);
    timer=millis();
    if(dest==last_dest)
      Go(0,0);
    else{
      dest_p=map(dest,0,255,pmin,pmax);
      pos=map(analogRead(AT),pmin,pmax,0,255);
      acc=2.0*((float)(dest-pos)-v0);
      //вычисление ШИМ
      if(v0>=0)
        pwm=(long)(K1*acc+K2);//вверх
      else
        pwm=(long)(K1*acc-K2);//вниз
      //перезапуск двигателя
      Restart();//ограничивает pwm
      if(pwm==255)
        v0=(float)(pos-last_pos)+max_acc*1.5;
      else if(pwm==-255)
        v0=(float)(pos-last_pos)-max_acc*1.5;
      else
        v0=(float)(dest-pos)+acc/2.0;
      last_dest=dest;
    }
    last_pos=pos;
    inputString = "";
    stringComplete = false;
  }
  pot=analogRead(AT);
  if((millis()-timer)>MAX_TIME){
    Go(0,0);
  }
  ToString(2,outputString+1,dest);
  ToString(4,outputString+3,map(pot,pmin,pmax,0,255));
  ToString(4,outputString+7,pwm+255);
  Serial.print(outputString);
}

void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    delayMicroseconds(100);
  }
  if((byte)inputString.charAt(2)==0xFF){
    stringComplete = true;
  }
  else
    inputString = "";
}

void Restart(void)
{
  int d;
  if(pwm<0) d=-1;
  else d=1;
  if(pwm>255)
    pwm=255;
  else if(pwm<-255)
    pwm=-255;
  Go(d,(byte)(d*pwm));
}

void ToString(int n,char *buf, int val)
{
  int i,k;
  for(i=n-1;i>=0;i--){
    k=val%16;
    if(k>9) buf[i]=(char)k+'A'-10;
    else buf[i]=(char)k+'0';
    val/=16;
  }
}

void Go(int d,byte s)
{
  if(d!=dir){
    analogWrite(_PWM,0);
    speed_pwm=0;
    digitalWrite(INA, LOW);
    digitalWrite(INB, LOW);
    if(d==1)
      digitalWrite(INA, HIGH);
    else if(d==-1)
      digitalWrite(INB, HIGH);
    dir=d;
  }
  if(s!=speed_pwm){
    analogWrite(_PWM,s);
    speed_pwm=s;
  }
}

Описание применения Ардуино для чайников.
Контроллер Arduino Uno имеет 6 аналоговых входов, 10 бит (0-1023), обозначенных на плате A0 – A5. И 14 цифровых входов/выходов 0-13. Из них аппаратный ШИМ поддерживают 6 (3, 5, 6, 9, 10, 11).
На любой аналоговый вход подключаем движок потенциометра, один конец потенциометра – на +5 Ардуино, другой – на землю. Потенциометр может быть любым однооборотным, линейным, от 1к до 10к. Конечно, лучше использовать прецизионные, они меньше шумят и дольше живут. Для защиты от электрических наводок, Ale рекомендует использовать поты 1к и экранировать провода, причем экран подключить к земле только с одной стороны - на контроллере. Следует выяснить рабочий угол потенциометра в градусах, по даташиту, либо измерить. Например, у меня сейчас СП3-400, угол у него 300 градусов.
Драйвер двигателя (Н-мост) у меня управляется тремя цифровыми выходами Ардуино, INA, INB и _PWM. Если INA==1, INB==0, двигатель крутится в одну сторону с ШИМом _PWM. Если INA=0, INB=1 – в другую. Если оба равны 0 – стоит. Если оба единицы – не пробовал и не хочу.
Драйвер у меня, пока, Pololu. Я им сильно разочаровался, при перегреве срабатывает тепловая защита и он вырубается. Часто. Буду менять на китайский.
Возможно, другие драйверы управляются по-другому, не изучал этот вопрос, напишите, переделаю.
Мои программы рассчитаны на некоторые стандартные параметры. Используемый угол потенциометра – средние 180 градусов. Период прихода входных сигналов – 33 мсек, диапазон – 0-255, формат – 5 байт (AB FF a1 a2), скорость 115200.
Загрузка, правка и написание программ в Ардуино осуществляется с программы, которая скачивается с официального сайта. Предварительно надо установить драйверы и сконфигурировать на имеющуюся версию платы и нужный COM порт.
Программы, которые я выкладываю, копипастятся в окно Ардуино.
Но им требуется некоторая настройка под ваше оборудование, которую сделать легко.
В начале программы стоят определители:
#define INA 8 //нога 8
#define INB 9 //нога 9
#define _PWM 10 // ШИМ, нога 10
#define AT 0 //потенциометр, нога А0
#define DEG 300.0 //рабочий угол потенциометра
#define K1 84.21 //коэффициенты двигателя, получаемые от сервисной программы
#define K2 46.16
Вы должны заменить эти значения на те, которые имеются у вас. Не забывайте ставить десятичную точку, где она есть.
Далее, сохраняем файл и нажимаем кнопочку «Загрузить». Все. Программа работает.
Аватара пользователя
kuzevan
Парторг
 
Сообщения: 60
Зарегистрирован: 25 окт 2011, 17:17
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Баллы репутации: -6

Re: Данные: что передавать и как регулировать

Сообщение kuzevan » 29 ноя 2012, 13:26

Все молчат. Наверное, побежали покупать Ардуино.
Аватара пользователя
kuzevan
Парторг
 
Сообщения: 60
Зарегистрирован: 25 окт 2011, 17:17
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Баллы репутации: -6

Re: Данные: что передавать и как регулировать

Сообщение AlexVr » 29 ноя 2012, 14:14

Не знаю как все, но я с работы побегу домой - пробовать :lol:
Аватара пользователя
AlexVr
SIMER
 
Сообщения: 449
Зарегистрирован: 05 апр 2010, 20:48
Благодарил (а): 23 раз.
Поблагодарили: 32 раз.
Баллы репутации: 71
Технарь

Re: Данные: что передавать и как регулировать

Сообщение taran_ob » 29 ноя 2012, 15:08

Мне немного сложно разбираться в исходниках, но как я понял, если в расчет PWM подставить все переменные, то выражение включает в себя полученную, текущую и прошлую координаты и становится очень похожим на ПИ закон :) записанный как то, не в обиду, через попу.

А поддержку энкодера ты не планируешь? И сколько движков хочешь подключить?
taran_ob
Комсорг
 
Сообщения: 137
Зарегистрирован: 27 окт 2012, 22:05
Откуда: Ukraine
Благодарил (а): 5 раз.
Поблагодарили: 11 раз.
Баллы репутации: 19
Новичок

Re: Данные: что передавать и как регулировать

Сообщение kuzevan » 29 ноя 2012, 15:23

Вот. А я все думаю, что это Таран про ПИД не пишет...
Про ПИД я все сказал ранее, добавить нечего.
Энкодер не планирую. Движка будет два, но очень легко добавить еще.
Аватара пользователя
kuzevan
Парторг
 
Сообщения: 60
Зарегистрирован: 25 окт 2011, 17:17
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Баллы репутации: -6

Re: Данные: что передавать и как регулировать

Сообщение taran_ob » 29 ноя 2012, 15:42

kuzevan писал(а):Про ПИД я все сказал ранее, добавить нечего.

не смотря на то что ты не поддерживаешь ПИД, в своем алгоритме подобие ПИ сам реализовываешь не осознано...
taran_ob
Комсорг
 
Сообщения: 137
Зарегистрирован: 27 окт 2012, 22:05
Откуда: Ukraine
Благодарил (а): 5 раз.
Поблагодарили: 11 раз.
Баллы репутации: 19
Новичок

Re: Данные: что передавать и как регулировать

Сообщение kuzevan » 29 ноя 2012, 15:49

Объясняю в последний раз. Все пропорциональные системы управления так и называются, потому, что управляющий сигнал (ШИМ) внутри цикла пропорционально зависит от расстояния до цели. Чем это расстояние меньше, тем меньше сигнал. Для того, чтобы подойти к цели и остановиться. Я останавливаться не собираюсь, поэтому мой сигнал внутри одного цикла 33 мсек не изменяется от расстояния до цели, следовательно моя система не пропорциональная. Точка.
Аватара пользователя
kuzevan
Парторг
 
Сообщения: 60
Зарегистрирован: 25 окт 2011, 17:17
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Баллы репутации: -6

Re: Данные: что передавать и как регулировать

Сообщение taran_ob » 29 ноя 2012, 16:51

kuzevan писал(а):Объясняю в последний раз.

Подожди, не нервничай. Что же, ты хочешь, чтоб все сразу восприняли твой подход? Или код ты выложил для принятия к сведению?
У меня какое то полное недопонимание...

kuzevan писал(а):Все пропорциональные системы управления так и называются, потому, что управляющий сигнал (ШИМ) пропорционально зависит от расстояния до цели. Чем это расстояние меньше, тем меньше сигнал. Для того, чтобы подойти к цели и остановиться.


100% верно. Все это справедливо в случае если период получения координат намного больше периода расчета шим. На столько больше, что ко времени получения следующего задания, шим проинтегрируется до 0. А речь идет о том, чтоб от задания до задания двигаться с постоянным ШИМ(пропорциональным), и как следствие с постоянной скорость(мгновенной). А так как время между заданиями ооочень маленькое, то ускоренное передвижение сима за какое то время будет состоять из маааленьких передвижений с постоянной скоростью.
И где же здесь остановка???

Мало того, повторюсь, я записал на листике твое выражение для PWM, подставив в него V0 и ACC и в результате получил выражение ооочень похожее на ПИ закон только со своими, пока не понятными мне, коэффициентами k1 k2 1,5 2.

kuzevan писал(а):Я останавливаться не собираюсь, поэтому мой сигнал не зависит от расстояния до цели, следовательно моя система не пропорциональная.


Как это не зависит от расстояния до цели, если в твое выражение PWM ни чего не входит кроме координат. То что ты их разности обозвал V0 и ACC это ни о чем не говорит. И по графику видно как ты в траекторию попал замечательно. Так что очень даже пропорциональная...
taran_ob
Комсорг
 
Сообщения: 137
Зарегистрирован: 27 окт 2012, 22:05
Откуда: Ukraine
Благодарил (а): 5 раз.
Поблагодарили: 11 раз.
Баллы репутации: 19
Новичок

Re: Данные: что передавать и как регулировать

Сообщение taran_ob » 29 ноя 2012, 17:06

Ты не думай, что мне заняться больше нечем кроме как критиковать и умничать, просто у меня жаба, что твой потенциал программиста, коим я не обладаю, направлен не в то русло, имхо.
taran_ob
Комсорг
 
Сообщения: 137
Зарегистрирован: 27 окт 2012, 22:05
Откуда: Ukraine
Благодарил (а): 5 раз.
Поблагодарили: 11 раз.
Баллы репутации: 19
Новичок

Re: Данные: что передавать и как регулировать

Сообщение kuzevan » 29 ноя 2012, 17:26

Хорошо. Зайду с другой стороны.
Есть у нас задание. Любое. Нагреть воду в котле до 99 градусов за 2 часа, но не до 100, чтобы не закипела. Включаем нагреватель и периодически сравниваем температуру воды с заданной. Чем ближе к 99 градусам, тем ниже подаем мощность на нагреватель. За час нагрели и держим. Подостыла - чуть-чуть греем, нагрели - выключаем. Это пропорциональный регулятор, его цель - 99 градусов, период - 2 часа.
Теперь о нас. Пришел сигнал с новой целью, следующий поступит через 33 мсек. Включаем мотор. Внутри этих 33 мсек мы имеем несколько внутренних циклов, в которых измеряем расстояние до цели, если оно близко, уменьшаем ШИМ. Допустим, достигли цели за 20 мсек. Выключаем мотор. Стоим, ждем новой цели. Это тоже пропорциональный регулятор, точно такой же, как для воды.
Я поступаю совершенно иначе. При поступлении новой цели я вычисляю по простым формулам механики ускорение (и ШИМ), которые должны обеспечить прибытие в заданную цель через заданное время 33 мсек. И подаю этот ШИМ на двигатель. Внутри этого цикла я ничего не измеряю и не корректирую, просто жду новой цели. Зависит ли этот ШИМ от расстояния до цели? Конечно. Зависит ли от начальной скорости? Конечно. Но это совсем не означает, что это пропорциональный регулятор, не надо путать термины.
Еще раз. Внутри цикла у меня никаких коррекций нет, а это краеугольный камень пропорционального регулирования. А приходит новая цель - это новая работа.
А тебе, для домашнего задания, предлагаю написать программку управления через ПИД и потестить ее, это лучше, чем флудить своим ПИДом.
Мою-то можно потестить, а как известно - практика - критерий истины.
Аватара пользователя
kuzevan
Парторг
 
Сообщения: 60
Зарегистрирован: 25 окт 2011, 17:17
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Баллы репутации: -6

Re: Данные: что передавать и как регулировать

Сообщение taran_ob » 29 ноя 2012, 17:41

kuzevan писал(а):Теперь о нас. Пришел сигнал с новой целью, следующий поступит через 33 мсек. Включаем мотор. Внутри этих 33 мсек мы имеем несколько внутренних циклов, в которых измеряем расстояние до цели, если оно близко, уменьшаем ШИМ.


Ну, так я же предлагаю не иметь!!!! внутри этих 33мсек никаких внутренних циклов. Соответственно ШИМ уменьшаться не будет! Но лучше, чтоб это были не 33мс, а по меньше.

kuzevan писал(а):А тебе, для домашнего задания, предлагаю написать программку управления через ПИД и потестить ее, это лучше, чем флудить своим ПИДом.


всему свое время...
taran_ob
Комсорг
 
Сообщения: 137
Зарегистрирован: 27 окт 2012, 22:05
Откуда: Ukraine
Благодарил (а): 5 раз.
Поблагодарили: 11 раз.
Баллы репутации: 19
Новичок

Re: Данные: что передавать и как регулировать

Сообщение kuzevan » 29 ноя 2012, 17:47

Обхохочешься...
Аватара пользователя
kuzevan
Парторг
 
Сообщения: 60
Зарегистрирован: 25 окт 2011, 17:17
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Баллы репутации: -6

Re: Данные: что передавать и как регулировать

Сообщение taran_ob » 29 ноя 2012, 17:57

kuzevan писал(а):При поступлении новой цели я вычисляю по простым формулам механики ускорение (и ШИМ), которые должны обеспечить прибытие в заданную цель через заданное время 33 мсек.


Если ты в эту формулу учтешь внешнее воздействие, то в результате самостоятельно выведешь закон ПИД регулирования :D
taran_ob
Комсорг
 
Сообщения: 137
Зарегистрирован: 27 окт 2012, 22:05
Откуда: Ukraine
Благодарил (а): 5 раз.
Поблагодарили: 11 раз.
Баллы репутации: 19
Новичок

Re: Данные: что передавать и как регулировать

Сообщение AlexVr » 29 ноя 2012, 18:33

kuzevan писал(а):Выкладываю исправленную и дополненную версию программы для Ардуино управления мотором.


Загрузил, подцепил резистор, запустил прогу от Ale - РАБОТАЕТ!kuzevan, мои поздравления!
Аватара пользователя
AlexVr
SIMER
 
Сообщения: 449
Зарегистрирован: 05 апр 2010, 20:48
Благодарил (а): 23 раз.
Поблагодарили: 32 раз.
Баллы репутации: 71
Технарь

Пред.След.

Вернуться в X-SIMULATOR и RU-SIMULATOR & SimTools

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 151

cron
x

#{title}

#{text}