下推式磁懸浮

float kpx=1 ; //比例

float kpy=1 ; //比例

float kdx=2 ; //微分

float kdy=2 ; //微分

int setx = 370 ; //設定點 (介於AnalogRead讀數範圍 0~1023之間)

int sety = 370 ; //設定點 (介於AnalogRead讀數範圍 0~1023之間)

int nowx, nowy ;

int px,dx,errx,oldx,outputx ;

int py,dy,erry,oldy,outputy ;

int erx,ery;

unsigned long t2,t1,t4,t3;

void setup() {

Serial.begin(115200);

pinMode(5,OUTPUT);

pinMode(6,OUTPUT);

pinMode(9,OUTPUT);

pinMode(10,OUTPUT);

}

void loop(){

nowx = analogRead(A1);

Serial.print("nowx=");

Serial.print(nowx);

Serial.print(" , ");

errx = nowx - setx ;

erx=abs(errx);

px = kpx * erx ;

Serial.print("px=");

Serial.print(px);

Serial.print(" , ");

t2=micros();

dx = kdx * (nowx - oldx)*1000/(t2-t1) ;

Serial.print("dx=");

Serial.print(dx);

Serial.print(" , ");

oldx = nowx ;

t1=t2;

outputx=int(constrain(px + dx ,0,255));

if(errx>0){

analogWrite(5,outputx);

analogWrite(6,0);

Serial.print("outputx=");

Serial.print(outputx);

Serial.print(" , ");

}

if(errx==0){

analogWrite(5,0);

analogWrite(6,0);

Serial.print("outputx=");

Serial.print(outputx);

Serial.print(" , ");

}

if(errx<0){

analogWrite(6,outputx);

analogWrite(5,0);

Serial.print("outputx=");

Serial.print(-1*outputx);

Serial.print(" , ");

}

delay(1);

nowy = analogRead(A0);

Serial.print("nowy=");

Serial.print(nowy);

Serial.print(" , ");

erry = nowy - sety ;

ery=abs(erry);

py = kpy * ery ;

Serial.print("py=");

Serial.print(py);

Serial.print(" , ");

t4=micros();

dy = kdy * (nowy - oldy)*1000/(t4-t3) ;

Serial.print("dy=");

Serial.print(dy);

Serial.print(" , ");

oldy = nowy ;

t3=t4;

outputy=int(constrain(py + dy ,0,255));

if(erry>0){

analogWrite(9,outputy);

analogWrite(10,0);

Serial.print("outputy=");

Serial.println(outputy);

}

if(erry==0){

analogWrite(9,0);

analogWrite(10,0);

Serial.print("outputy=");

Serial.println(outputy);

}

if(erry<0){

analogWrite(10,outputy);

analogWrite(9,0);

Serial.print("outputy=");

Serial.println(-1*outputy);

}

delay(1);

}

view plaincopy to clipboardprint?

  1. //PINs setting

  2. int adjust1Pin = 1; //用来调节A的电位器

  3. int adjust2Pin = 2; //用来调节B的电位器

  4. int read1Pin = 4; //用来连接输入A传感器

  5. int read2Pin = 3; //用来连接输入B传感器

  6. int i1Pin = 36; //连接电机驱动板的I1接口

  7. int i2Pin = 37; //连接电机驱动板的I2接口

  8. int i3Pin = 39; //连接电机驱动板的I3接口

  9. int i4Pin = 38; //连接电机驱动板的I4接口

  10. int power1Pin = 5; //连接电机驱动板的EA接口

  11. int power2Pin = 6; //连接电机驱动板的EB接口

  12. int rotatePin = 3; //用来控制磁场旋转的PMW接口

  13. boolean debug = false;

  14. boolean writeLog = false;

  15. double setKd1 = 0.55;

  16. double setKd2 = 0.55;

  17. double setKp = 22;

  18. int offset = 70;

  19. int delayMs = 1;

  20. int tick = 0;

  21. int myLog[3500];

  22. //PID structure

  23. typedef struct {

  24. double target;

  25. double aver;

  26. double Kp;

  27. double Kd;

  28. int preError;

  29. int power;

  30. boolean flag;

  31. double v;

  32. } PID;

  33. PID Pid1, Pid2;

  34. void setup()

  35. {

  36. pinMode(i1Pin, OUTPUT); //I1和I2都是数字信号

  37. pinMode(i2Pin, OUTPUT); //通过设置I1和I2来控制电流方向

  38. pinMode(i3Pin, OUTPUT); //I1和I2都是数字信号

  39. pinMode(i4Pin, OUTPUT); //通过设置I1和I2来控制电流方向

  40. pinMode(power1Pin, OUTPUT); //按占空比方式输出的模拟信号

  41. pinMode(power2Pin, OUTPUT); //按占空比方式输出的模拟信号

  42. pinMode(rotatePin, OUTPUT); //按占空比方式输出的模拟信号

  43. //analogWrite(rotatePin, 128);

  44. Serial.begin(9600); //设置波特率

  45. TCCR0B = 0x01; // Timer 0: PWM 5 & 6 @ 16 kHz

  46. TCCR1B = 0x01; // Timer 1: PWM 9 & 10 @ 32 kHz

  47. TCCR2B = 0x01; // Timer 2: PWM 3 & 11 @ 32 kHz

  48. Pid1.Kp = setKp;

  49. Pid1.preError = 0;

  50. Pid1.Kd = setKd1;

  51. Pid1.power = 0;

  52. Pid1.flag = true;

  53. Pid1.target = 300;

  54. Pid1.aver = 0;

  55. Pid1.v = 0;

  56. Pid2.Kp = setKp;

  57. Pid2.preError = 0;

  58. Pid2.Kd = setKd2;

  59. Pid2.power = 0;

  60. Pid2.flag = true;

  61. Pid2.target = 300;

  62. Pid2.aver = 0;

  63. Pid2.v = 0;

  64. tick = 0;

  65. }

  66. int tick2 = 0;

  67. //boolean rotateFlag = true;

  68. void loop()

  69. {

  70. //digitalWrite(rotatePin, rotateFlag);

  71. //rotateFlag = ! rotateFlag;

  72. //delay(16000);

  73. //return;

  74. if(debug) tick = 0;

  75. tick++;

  76. if(tick==500)

  77. {

  78. tick2++;

  79. if(tick2<50) {tick = 0;return;}

  80. tick2 = 0;

  81. if(writeLog)

  82. {

  83. for(int i=0;i<500;i++)

  84. {

  85. Serial.print(myLog[i*7 + 0]);

  86. Serial.print(" ");

  87. Serial.print(myLog[i*7 + 1]);

  88. Serial.print(" ");

  89. Serial.print(myLog[i*7 + 2]);

  90. Serial.print(" ");

  91. Serial.print(myLog[i*7 + 3]);

  92. Serial.print(" ");

  93. Serial.print(myLog[i*7 + 4]);

  94. Serial.print(" ");

  95. Serial.print(myLog[i*7 + 5]);

  96. Serial.print(" ");

  97. Serial.print(myLog[i*7 + 6]);

  98. Serial.println(" ");

  99. }

  100. Serial.println(Pid1.target);

  101. Serial.println(Pid1.preError);

  102. Serial.println(Pid2.target);

  103. Serial.println(Pid2.preError);

  104. }

  105. return;

  106. }

  107. else if(tick>500)

  108. {

  109. tick = 0;

  110. //delay(990000);

  111. return;

  112. };

  113. //=======第一组电位器和传感器========

  114. int readValue1 = 0;

  115. for(int i = 0; i < 4; i++) readValue1 += analogRead(read1Pin);

  116. readValue1 >>= 2;

  117. //readValue1 += (Pid1.flag ? 1 : -1) * Pid1.power / 17;

  118. int adjustValue1 = analogRead(adjust1Pin); //410 analogRead(adjust1Pin);

  119. Pid1.aver = Pid1.aver * 0.9995 + readValue1 * 0.0005;

  120. Pid1.target = Pid1.target + (Pid1.target - Pid1.aver) / 100.0;

  121. Pid1.target = max(0, max(adjustValue1 - offset, Pid1.target));

  122. Pid1.target = min(755, min(adjustValue1 + offset, Pid1.target));

  123. //=======第二组电位器和传感器=======

  124. int readValue2 = 0;

  125. for(int i = 0; i < 4; i++) readValue2 += analogRead(read2Pin);

  126. readValue2 >>= 2;

  127. //readValue2 += (Pid2.flag ? 1 : -1) * Pid2.power / 6;

  128. int adjustValue2 = analogRead(adjust2Pin); //240 analogRead(adjust2Pin);

  129. Pid2.aver = Pid2.aver * 0.9995 + readValue2 * 0.0005;

  130. Pid2.target = Pid2.target + (Pid2.target - Pid2.aver) / 1000.0;

  131. Pid2.target = max(0, max(adjustValue2 - offset, Pid2.target));

  132. Pid2.target = min(755, min(adjustValue2 + offset, Pid2.target));

  133. if(debug)

  134. {

  135. Serial.println(adjustValue1);

  136. Serial.println(adjustValue2);

  137. Serial.println(readValue1);

  138. Serial.println(readValue2);

  139. Pid1.flag = adjustValue1 > 512;

  140. Pid1.power = abs(adjustValue1 - 512) / 2;

  141. if(Pid1.power > 255) Pid1.power = 255;

  142. digitalWrite(i1Pin, Pid1.flag);

  143. digitalWrite(i2Pin, !Pid1.flag);

  144. analogWrite(power1Pin, Pid1.power);

  145. Pid2.flag = adjustValue2 > 512;

  146. Pid2.power = abs(adjustValue2 - 512) / 2;

  147. if(Pid2.power > 255) Pid2.power = 255;

  148. digitalWrite(i3Pin, Pid2.flag);

  149. digitalWrite(i4Pin, !Pid2.flag);

  150. analogWrite(power2Pin, Pid2.power);

  151. delay(32000);

  152. return;

  153. }

  154. //Calculate power values

  155. double v, error;

  156. error = readValue1 - Pid1.target;

  157. v = error - Pid1.preError;

  158. Pid1.v = (Pid1.v * 6 + v) / 7;

  159. Pid1.power = (int)error * Pid1.Kd + Pid1.v * Pid1.Kp;

  160. Pid1.flag = Pid1.power > 0;

  161. Pid1.power = abs(Pid1.power);

  162. if(Pid1.power>255) Pid1.power = 255;

  163. Pid1.preError = error;

  164. error = readValue2 - Pid2.target;

  165. v = error - Pid2.preError;

  166. Pid2.v = (Pid2.v * 6 + v) / 7;

  167. Pid2.power = (int)error * Pid2.Kd + Pid2.v * Pid2.Kp;

  168. Pid2.flag = Pid2.power < 0;

  169. Pid2.power = abs(Pid2.power);

  170. if(Pid2.power>255) Pid2.power = 255;

  171. Pid2.preError = error;

  172. //Write PMW to control the floa

  173. digitalWrite(i1Pin, Pid1.flag);

  174. digitalWrite(i2Pin, !Pid1.flag);

  175. analogWrite(power1Pin, Pid1.power);

  176. digitalWrite(i3Pin, Pid2.flag);

  177. digitalWrite(i4Pin, !Pid2.flag);

  178. analogWrite(power2Pin, Pid2.power);

  179. myLog[tick * 7 + 0] = tick;

  180. myLog[tick * 7 + 1] = (int)Pid1.target;

  181. myLog[tick * 7 + 2] = readValue1;

  182. myLog[tick * 7 + 3] = Pid1.power;

  183. myLog[tick * 7 + 4] = (int)Pid2.target;

  184. myLog[tick * 7 + 5] = readValue2;

  185. myLog[tick * 7 + 6] = Pid2.power;

  186. /*

  187. for(int i=0;i<8;i++)

  188. {

  189. digitalWrite(rotatePins[i] , 0);

  190. digitalWrite(rotatePins[(i + 1) % 8] ,1);

  191. delay(1);

  192. }

  193. digitalWrite(rotatePins[0] , 0);

  194. */

  195. delay(delayMs);

  196. }