Stupid 发表于 2013-12-22 22:59:11

PID电机调速求探讨

原帖地址:http://blog.solutions-cubed.com/pid-motor-control-with-an-arduino/
电路接线图,电路板原理图见附件。
程序:/*
Firstbot PID code:Implements a PID controller using
analog inputs for actual and desired positions.

The circuit:
* RX is digital pin 2 (connect to TX of other device)
* TX is digital pin 3 (connect to RX of other device)

*/
#include <SoftwareSerial.h>

// define some constants
int ActPos = A0;    // select the input pin for feedback signal
int DesPos = A1;    // select the input pin for control signal

byte PWMOutput;
long Error;
long Accumulator;
long PID;
int PTerm;
int ITerm;
int DTerm;
byte Divider;

/*
The FIRSTBOT has a PIC16F1829 controller that controls the
two MC33926 H-bridges on the board.A oftware serial interface
is used to control that part.
*/
SoftwareSerial mySerial(2, 3); // Receive data on 2, send data on 3
byte SerialTXBuffer;
byte SerialRXBuffer;

void setup()
{

// Open serial communications and wait for port to open:
Serial.begin(9600);
mySerial.begin(9600);
}

/* GetError():
Read the analog values, shift the Error array down
one spot, and load the new error value into the
top of array.
*/
void GetError(void)
{
byte i = 0;
// read analogs
word ActualPosition = analogRead(ActPos);
// comment out to speed up PID loop
//Serial.print("ActPos= ");
//Serial.println(ActualPosition,DEC);

word DesiredPosition = analogRead(DesPos);
// comment out to speed up PID loop
//Serial.print("DesPos= ");
//Serial.println(DesiredPosition,DEC);

// shift error values
for(i=0;i<10;i++)
    Error = Error;
// load new error into top array spot
Error = (long)DesiredPosition-(long)ActualPosition;
// comment out to speed up PID loop
//Serial.print("Error= ");
//Serial.println(Error,DEC);

}

/* CalculatePID():
Error is used for latest error, Error with the DTERM
*/
void CalculatePID(void)
{
// Set constants here
PTerm = 2000;
ITerm = 25;
DTerm = 0;
Divider = 10;

// Calculate the PID
PID = Error*PTerm;   // start with proportional gain
Accumulator += Error;// accumulator is sum of errors
PID += ITerm*Accumulator; // add integral gain and error accumulation
PID += DTerm*(Error-Error); // differential gain comes next
PID = PID>>Divider; // scale PID down with divider

// comment out to speed up PID loop
//Serial.print("PID= ");
//Serial.println(PID,DEC);

// limit the PID to the resolution we have for the PWM variable

if(PID>=127)
    PID = 127;
if(PID<=-126)
    PID = -126;

//PWM output should be between 1 and 254 so we add to the PID   
PWMOutput = PID + 127;

// comment out to speed up PID loop
//Serial.print("PWMOutput= ");
//Serial.println(PWMOutput,DEC);

}

/* WriteRegister():
Writes a single byte to the PIC16F1829,
"Value" to the register pointed at by "Index".
Returns the response
*/
byte WriteRegister(byte Index, byte Value)
{
byte i = 0;
byte checksum = 0;
byte ack = 0;

SerialTXBuffer = 210;
SerialTXBuffer = 1;
SerialTXBuffer = 3;
SerialTXBuffer = Index;
SerialTXBuffer = Value;

for (i=0;i<6;i++)
{
if (i!=5)
    {
    mySerial.write(SerialTXBuffer);
    checksum += SerialTXBuffer;   
    }
else
    mySerial.write(checksum);   
}
delay(5);

if (mySerial.available())
    ack = mySerial.read();

return ack;
}

void loop() // run over and over
{
   GetError();       // Get position error
   CalculatePID();   // Calculate the PID output from the error
   WriteRegister(9,PWMOutput);// Set motor speed
}
      刚刚接触PID这块,我把设计的文件都看了一遍,这个项目用了2个单片机,uno和PIC16F1829-I/ML,uno用于电机位置的检测和电机状态的控制,而pic这块对uno发出的指令进行处理从而对电机驱动给出控制,达到电机调速并且回复uno,带到串口通信的作用。我这样理解不知道对不对,在这个项目里我没有找到pic程序是怎么写的,还有一点就是可以通过软件实现电机调速和正反转。在里我提出第一个问题:就是pic的作用和功能是如何实现的,还有文章中涉及的就是固件这块的作用是什么?本人学生一枚第一次接触单片机,想把这个东西先照着这个做出来,已经打了电路板,就是想把这些都弄懂。
      另外一个问题就是uno程序部分。首先对于电路接线图有一个问题,为什么分别通过模拟脚去接滑动变阻器和编码器,为什么这样就是PID的偏差Error?Error这个为什么是Error【10】不是很懂。









页: [1]
查看完整版本: PID电机调速求探讨