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 --;
}
}