roboforum.ru

Технический форум по робототехнике.

Точное позиционирование коллекторного двигателя

Как собрать и запрограммировать робота на Arduino(Freeduino, Roboduino, Seeduino ...). Используем Wiring и Processing.

Re: Точное позиционирование коллекторного двигателя

Сообщение nefilim » 02 окт 2011, 14:47

так сколько нужно?
nefilim
 
Сообщения: 24
Зарегистрирован: 16 июл 2011, 17:55

Re: Точное позиционирование коллекторного двигателя

Сообщение Grem » 02 окт 2011, 17:07

зачем вам ПИД-регулятор на частоте 1КГц?

Прикольно же :D
так сколько нужно?

Можно 490Гц и сделать.
"There is nothing better than sliding down snow and flying through the air" (с) Shane McConkey.
Lieber ein Brett am Fuß als eins vorm Kopf, aber lieber ein Brett vorm Kopf als zwei am Fuß.
Аватара пользователя
Grem
 
Сообщения: 1530
Зарегистрирован: 16 май 2009, 12:50
Откуда: Россия
прог. языки: Java, C

Re: Точное позиционирование коллекторного двигателя

Сообщение Duhas » 02 окт 2011, 17:10

а лучше бы, имхо, поднять частоту ШИМ
«Как сердцу выразить себя? … Мысль изреченная есть ложь!»
В этом мире меня подводит доброта и порядочность...
"двое смотрят в лужу, один видит лужу, другой отраженные в ней звезды"
Аватара пользователя
Duhas
 
Сообщения: 6338
Зарегистрирован: 15 сен 2007, 13:03
Откуда: Красноярск
прог. языки: ASM(МК), C(PC)
ФИО: Гагарский Андрей Александрович

Re: Точное позиционирование коллекторного двигателя

Сообщение nefilim » 03 окт 2011, 14:42

Вот исправленный код.
Не работает.

// spinMotor(),
int pinMotor1 = 8; // пин для подключения мотора
int pinMotor2 = 9; // пин для подключения мотора
int pinMotorSpeed = 10; // пин для подключения мотора (ШИМ) управление скоростью

// pid ()
float kP = 1.25;
float kI = .5;
float kD = .2;
int iMax = 100;
int iMin = 0;
volatile int error = 0;
volatile int lastError = 0;
volatile int sumError = 0;
int minSpeed = 100;
int maxSpeed = 255;
volatile int correct = 0;

// loop()
int potVal = 0; // значение потенциометра, полученное из Serial
int inTimeStep = 0; // количество шагов на которое нужно повернуть мотор (+ или - выбирает направление)

// encoder()
int interruptPin = 2; // номер порта для энкодеа (прерывания) А канал
int buttonDir = 3; // номер порта для энкодера (направление) Б канал
volatile int steping = 0; // текущее количество шагов энкодера

void setup() {
Serial.begin(9600);
// motor
pinMode(pinMotor1, OUTPUT); // инициализируем порт для мотора
pinMode(pinMotor2, OUTPUT); // инициализируем порт для мотора
pinMode(pinMotorSpeed, OUTPUT); // инициализируем порт для мотора (управление скоростью)
// encoder
pinMode(interruptPin, INPUT); // инициализируем порт для прерывания (энкодера) А канал
pinMode(buttonDir, INPUT); // инициализируем порт для энкодера (направление) Б канал
digitalWrite(interruptPin, HIGH); // включаем подтягивающий резистор
digitalWrite(buttonDir, HIGH); // включаем подтягивающий резистор
attachInterrupt(0, encoder, RISING); // инициализируем прерываение

MsTimer2::set(10, pid); // 10ms period Таймер вызываем PID
MsTimer2::start();

}

void loop() {
if (Serial.available()>0) potVal = readPotSerial();
spinMotor (correct);
}


// speedR - скорость вращения от 0 до 255 (положительное значение вращаем в одну сторону, отрицательное - в другую)
void spinMotor (int speedR) {
if (speedR > 0)
{
digitalWrite(pinMotor1,HIGH);
digitalWrite(pinMotor2,LOW);
}
else if (speedR < 0)
{
digitalWrite(pinMotor1,LOW);
digitalWrite(pinMotor2,HIGH);
speedR = speedR * -1;
}
int motorSpeed = map(speedR, 0, 1024, minSpeed, maxSpeed);

if (steping == potVal ) {
digitalWrite(pinMotor1,LOW);
digitalWrite(pinMotor2,LOW);
}

analogWrite(pinMotorSpeed, motorSpeed);
}

// основной алгоритм подсчета
// расчет скорости и направления движения двигателя (ПИД алгоритм)
void pid() {
error = steping - potVal;
correct = kP * error + kD * (error - lastError) + kI * (sumError);
lastError = error;
sumError += error;
if(sumError > iMax){
sumError = iMax;
}
else if(sumError < iMin){
sumError = iMin;
}
}

// читает значение с энкодера через прерывание и инкрементирует или декрементирует значение steping
void encoder() {
if (digitalRead(interruptPin) == digitalRead(buttonDir)) {
steping ++;
}
else {
steping --;
}
}
nefilim
 
Сообщения: 24
Зарегистрирован: 16 июл 2011, 17:55

Re: Точное позиционирование коллекторного двигателя

Сообщение =DeaD= » 03 окт 2011, 15:04

Какая детальная информация. Тогда совет будет заключаться в "сделайте чтобы работало!".

PS: Я бы spinMotor(correct) внёс в pid()
Проект [[Open Robotics]] - Универсальные модули для построения роботов
Аватара пользователя
=DeaD=
 
Сообщения: 24218
Зарегистрирован: 06 окт 2004, 18:01
Откуда: Ебург
прог. языки: C++ / PHP / 1C
ФИО: Антон Ботов

Re: Точное позиционирование коллекторного двигателя

Сообщение nefilim » 04 окт 2011, 19:03

Ув. Антон. Я новичок. Мне очень сложно понять некоторые детали. К тому-же в ТАУ я вообще не разбираюсь. Поэтому пришел на форум за помощью.
Свой код я предоставил. Проблема как я понимаю в коэффициентах.
Не работает? Это значит тот -же результат. Дергает в разные стороны и не может стабилизироваться
nefilim
 
Сообщения: 24
Зарегистрирован: 16 июл 2011, 17:55

Re: Точное позиционирование коллекторного двигателя

Сообщение =DeaD= » 04 окт 2011, 20:26

Ну и что мы тут сделаем с коэффициентами без реального железа? Как в целом настраивать регулятор - описано в статье, ссылку на которую я приводил. Угадать коэффициенты нереально, даже если представить, что проблема именно в них (кстати, почему вы так решили?)

В пределах скольки единиц колеблется? Какая частота колебаний? Почему minSpeed именно 100, а не 50 или 20?
Если снизить пропорциональную и интегральную часть и вообще убрать дифференциальную - что получится по колебаниям?
Проект [[Open Robotics]] - Универсальные модули для построения роботов
Аватара пользователя
=DeaD=
 
Сообщения: 24218
Зарегистрирован: 06 окт 2004, 18:01
Откуда: Ебург
прог. языки: C++ / PHP / 1C
ФИО: Антон Ботов

Пред.

Вернуться в Arduino и другие Xduino

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

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