Тоже делаю роботизированную КПП на основе привода от Яриса (аналог Короллы, как у топикстартера).
Привод представляет из себя исполнительный механизм из двух коллекторных двигателей и датчиков их положений.
Приобрел контроллер для коллекторных двигателей
monster moto shield
http://pacpac.ru/product/dev-10182/
И решил его использовать для управления приводом.
Для каждого из двигателей нужно поймать три положения:
по датчикам это значения 450, 600 и 800
450 и 800 конечные положения с жесткими упорами их поймать проблем нет, а вот среднее положение 600 я или пролетаю или не дохожу.
Двигатели можут вращаться со скоростью 0...1023, линейный ход всего 16мм.
Замутил такой алгоритм: 0,5 пути который нужно пройти приводу он идет со скоростью 1023, дальше идет торможение и останов
Посоветуйте как быть..., вот моя функция из скетча:
int ChangeGear_P_135=450;//380;
int ChangeGear_P_N=600;
int ChangeGear_P_24R=800;//850;
float k1m1min=0.3; // коэф. общего пути до которого использовать полную скорость M1 при малом расстоянии (потеряно например)
float k2m1min=0.5; // коэф. общего пути с которого включать замедляющкю скорость M1
float k1m1=0.3; // коэф. общего пути до которого использовать полную скорость M1
float k2m1=0.5; // коэф. общего пути с которого включать замедляющкю скорость M1
float k1m1max=0.5; // коэф. общего пути до которого использовать полную скорость M1 при большом расстоянии (от линии 12 до 5R)
float k2m1max=0.6; // коэф. общего пути с которого включать замедляющкю скорость M1
// Функция привода переключения передач (2ой привод) M1
// В функцию передаются значения скорости (с любым знаком) и положения к которому нужно прийти (P_N12, P_N34, P_N5R)
byte Select_Gear_Motor_On(int Select_Gear_Start_Speed, int Select_Gear_End_Speed, int to_Position)//, boolean Search=false)
{
byte Rezult=0;
//int CurrentGearPosition=GetCurrentGearPosition();
boolean MotorToDo=false;
ReadSensors();
int znak_speed=1;
// определяемся со знаком скорости (т.е напралением вращения)
if (Select_Gear_Start_Speed<0){Select_Gear_Start_Spee d=-Select_Gear_Start_Speed;} //приводим к положительному знаку
if (Select_Gear_End_Speed<0){Select_Gear_End_Speed=-Select_Gear_End_Speed;} //приводим к положительному знаку
if (to_Position==P_N12)
{
if ((SelectGearSensor1>SelectGear_P_N12)||(SelectGear Sensor2>SelectGear_P_N12)) {znak_speed=1;}
if ((SelectGearSensor1<SelectGear_P_N12)||(SelectGear Sensor2<SelectGear_P_N12)) {znak_speed=-1;}
if ((IsValInRangeEx(SelectGearSensor1,SelectGear_P_N1 2, SensorPositionLimitForWork))||(IsValInRangeEx(Sele ctGearSensor1,SelectGear_P_N12, SensorPositionLimitForWork))) {znak_speed=0;} // дальше крутить не нужно - нужное положение
if (znak_speed!=0) {MotorToDo=true;}
}
if (to_Position==P_N34)
{
if ((SelectGearSensor1>SelectGear_P_N34)||(SelectGear Sensor2>SelectGear_P_N34)) {znak_speed=1;}
if ((SelectGearSensor1<SelectGear_P_N34)||(SelectGear Sensor2<SelectGear_P_N34)) {znak_speed=-1;}
if ((IsValInRangeEx(SelectGearSensor1,SelectGear_P_N3 4, SensorPositionLimitForWork))||(IsValInRangeEx(Sele ctGearSensor1,SelectGear_P_N34, SensorPositionLimitForWork))) {znak_speed=0;} // дальше крутить не нужно - нужное положение
if (znak_speed!=0) {MotorToDo=true;}
}
if (to_Position==P_N5R)
{
if ((SelectGearSensor1>SelectGear_P_N5R)||(SelectGear Sensor2>SelectGear_P_N5R)) {znak_speed=1;}
if ((SelectGearSensor1<SelectGear_P_N5R)||(SelectGear Sensor2<SelectGear_P_N5R)) {znak_speed=-1;}
if ((IsValInRangeEx(SelectGearSensor1,SelectGear_P_N5 R, SensorPositionLimitForWork))||(IsValInRangeEx(Sele ctGearSensor1,SelectGear_P_N5R, SensorPositionLimitForWork))) {znak_speed=0;} // дальше крутить не нужно - нужное положение
if (znak_speed!=0) {MotorToDo=true;}
}
float End_position=0;
float dystance=0;
float full_dystance=0;
boolean started=false;
boolean endingstarted=false;
boolean stopped=false;
float k1=k1m1;
float k2=k2m1;
if (MotorToDo)
{
Select_Gear_Start_Speed=Select_Gear_Start_Speed*zn ak_speed;
Select_Gear_End_Speed=Select_Gear_End_Speed*znak_s peed;
#if DEBUG
//Serial.println("***");
//Serial.println(SelectGear_P_N);
//Serial.println(SelectGearSensor1);
#endif
boolean stopMotor=false;
unsigned long now_timer=0;
unsigned long total_timer=0;
unsigned long control_timer=millis();
int cyclescount=0;
do {
now_timer=millis();
total_timer = now_timer - control_timer;
if (total_timer>=motor_check_timer) {SET_ERROR_MOTOR(ERROR_TOOLONGWORKINGM1); stopMotor=true;break;} // проверка на время длительности работы приводов
ReadSensors();
if (to_Position==P_N12)
{
if (((SelectGearSensor1>SelectGear_P_N12)||(SelectGea rSensor2>SelectGear_P_N12)) && (cyclescount>0)) {stopMotor=true;break;} // дальше крутить в эту сторону нельзя - конечное положение
if ((IsValInRangeEx(SelectGearSensor1,SelectGear_P_N1 2, SensorPositionLimitForRotate))||(IsValInRangeEx(Se lectGearSensor1,SelectGear_P_N12, SensorPositionLimitForRotate))) {stopMotor=true;break;} // дальше крутить не нужно - нужное положение
End_position=SelectGear_P_N12;
}
if (to_Position==P_N34)
{
if ((IsValInRangeEx(SelectGearSensor1,SelectGear_P_N3 4, SensorPositionLimitForRotate))||(IsValInRangeEx(Se lectGearSensor1,SelectGear_P_N34, SensorPositionLimitForRotate))) {stopMotor=true;break;} // дальше крутить не нужно - нужное положение
End_position=SelectGear_P_N34;
}
if (to_Position==P_N5R)
{
if (((SelectGearSensor1<SelectGear_P_N5R)||(SelectGea rSensor2<SelectGear_P_N5R)) && (cyclescount>0)) {stopMotor=true;break;} // дальше крутить в эту сторону нельзя - конечное положение
if ((IsValInRangeEx(SelectGearSensor1,SelectGear_P_N5 R, SensorPositionLimitForRotate))||(IsValInRangeEx(Se lectGearSensor1,SelectGear_P_N5R, SensorPositionLimitForRotate))) {stopMotor=true;break;} // дальше крутить не нужно - нужное положение
End_position=SelectGear_P_N5R;
}
dystance=abs(SelectGearSensor1-End_position);
if (full_dystance==0) {full_dystance=dystance;}
if (full_dystance<100) {Select_Gear_Start_Speed=M1MotorMidSpeed*znak_spee d;}
if (full_dystance<100){k1=k1m1min; k2=k2m1min;}
if (full_dystance>300){k1=k1m1max; k2=k2m1max;}
if (!started)// разгон
{
if (full_dystance-dystance<full_dystance*k1) {
//Pololuqik.setM1Speed(Select_Gear_Start_Speed);
if (znak_speed>0){motorGo(1, CCW, 1023);}
if (znak_speed<0){motorGo(1, CW, 1023);}
started=true;}
}
if (!endingstarted)//малая скорость
{
if ((full_dystance-dystance>=full_dystance*k1) && (full_dystance-dystance<=full_dystance*k2)) {
//Pololuqik.setM1Speed(Select_Gear_End_Speed);
//if (znak_speed>0){motorGo(1, CCW, 512);}
//if (znak_speed<0){motorGo(1, CW, 512);}
endingstarted=true;} //малая скорость
}
if (stopped==false) // торможение
{
if (full_dystance-dystance>full_dystance*k2) {
//Pololuqik.setM1Brake(127);
motorGo(1, BRAKEGND, 1023);
stopped=true;}
}
cyclescount++;
} while (stopMotor==false);
//Pololuqik.setM1Brake(127); //останов
motorGo(1, BRAKEGND, 1023);
motorOff(1);
}
Rezult=GetCurrentGearPosition();
if (Rezult!=0) {SetSuccessGearPosition_to_RAM(Rezult);}
//else {SetNotSuccessGearPosition_to_RAM(Rezult);}
return Rezult;
}




Ответить с цитированием