 nefilim » 03 окт 2011, 14:42
 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 --;
  }
}