Вот исправленный код. Не работает.
// 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 --; } }
|