for(inti=0;i<8;i++){// Aplicamos curva de Calibracion de ADC a mm
if(measure>=ADCcal[i]&&measure<ADCcal[i+1]){dist=map(measure,ADCcal[i],ADCcal[i+1],dcal[i],dcal[i+1]);}
也就是说,当球距离中心小于 4 厘米且大于 8 毫米时,我们将取其与中心的距离,将其乘以 Ki 并将结果累积在 I 中。我们在那里呆的时间越多,我就会变得越大。
总之,积分项提供了更高的精度,但必须方便地限制其作用,否则会带来太多的不稳定性。
Arduino总程序
#include<Servo.h>//#include <Wire.h>
//#include "IICLiquidCrystal.h"
// Connect via i2c, default address #0 (A0-A2 not jumpered)
//LiquidCrystal lcd(0);
floatKp=3;//2
floatKd=1;//35
floatKi=0.5;//0.1
intRint=8;//
intRext=40;//
intaim=0;unsignedlongtime=0;//execution time of the last cycle
unsignedlongtimeSerial=0;intperiod=50;//Sampling period in ms
intsensorPin=0;//Analog Pin where the Distance Sensor signal is connected
intmeasure;//What the sensor measures. They are ADCs.
intdcal[]={//Remote ADC calibration
-193,-160,-110,-60,0,40,60,90,120};intADCcal[]={177,189,231,273,372,483,558,742,970};intlastDist;//Previous value of Distance to calculate Speed
intdist;//distance in mm with 0 in the center of the bar
intnvel=5;//number of velocity values over which we calculate the average
intv[5];intvel;//mean value of the last speed levels
floatI;//Integral Value
Servomyservo;//create servo object to control a servo
floatpos;floatreposo=1350;//value held by horizontal bar
intledPin=13;//Green led pin.
voidsetup(){analogReference(EXTERNAL);//AREF connected to 3.3V
myservo.attach(3);//attaches the servo on pin X to the servo object
Serial.begin(115200);pinMode(ledPin,OUTPUT);myservo.writeMicroseconds(reposo);delay(5000);//lcd.begin(16, 2);
}voidloop(){if(millis()>timeSerial+200){timeSerial=millis();// Kp = map(analogRead(A1), 0, 1023, 0, 5000) / 100.0;
// Kd = map(analogRead(A2), 0, 1023, 0, 400) / 100.0;
// Ki = map(analogRead(A3), 0, 1023, 0, 300) / 100.0;
//aim = map(analogRead(A5), 0, 1023, -20, 20);
Serial.println();Serial.print("Kp:");Serial.println(Kp);Serial.print("Kd:");Serial.println(Kd);Serial.print("Ki:");Serial.println(Ki);Serial.print("Aim:");Serial.println(aim);Serial.print("Pos:");Serial.println(dist);}if(millis()>time+period){//
time=millis();// lcd.setCursor(0, 0);
// lcd.print("Kp:");
// lcd.print(Kp);
//
// lcd.setCursor(8, 0);
// lcd.print("Kd:");
// lcd.print(Kd);
//
// lcd.setCursor(0, 1);
// lcd.print("Ki:");
// lcd.print(Ki);
//
// lcd.setCursor(8, 1);
// lcd.print("Pos:");
// lcd.print(dist);
//We measure DISTANCE
measure=analogRead(sensorPin);measure=constrain(measure,ADCcal[0],ADCcal[8]);lastDist=dist;//We save the previous value of dist to calculate the speed
for(inti=0;i<8;i++){//We apply Calibration curve from ADC to mm
if(measure>=ADCcal[i]&&measure<ADCcal[i+1]){dist=map(measure,ADCcal[i],ADCcal[i+1],dcal[i],dcal[i+1]);}}//Average SPEED calculation
for(inti=0;i<nvel-1;i++){//We all move to the left to free the last one.
v[i]=v[i+1];}v[nvel-1]=(dist-lastDist);//We put a new data
vel=0;for(inti=0;i<nvel;i++){//We calculate the mean
vel=vel+v[i];}vel=vel/nvel;// Integral
if(abs(dist-aim)>Rint&&abs(dist-aim)<Rext){//Only if it is inside (-Rext, Rext) and outside (-Rint, Rint)
I=I+dist*Ki;}else{I=0;}//We calculate servo position
pos=Kp*(dist-aim)+Kd*vel+I;myservo.writeMicroseconds(reposo+pos);if(abs(dist)<Rint){//If we are inside Rint turn on Led
digitalWrite(ledPin,HIGH);}else{digitalWrite(ledPin,LOW);}if(1){//Shipping for PROCESSING
Serial.print(dist+200);Serial.print(",");Serial.print(dist+200);Serial.print(",");Serial.print(vel);Serial.print(",");Serial.print(vel);Serial.print("$");}if(0){//Debug
Serial.print(millis());Serial.print(" ms|dist: ");Serial.print(dist);Serial.print("|vel: ");Serial.print(vel);Serial.print("|Kp*dist: ");Serial.print(Kp*dist);Serial.print("|Kd*vel: ");Serial.print(Kd*vel);Serial.print("|Int: ");Serial.print(I);Serial.print("|pos: ");Serial.println(pos);}if(0){//To calibrate Distance sensor
Serial.print(dist);Serial.print("mm ADC: ");Serial.println(measure);}if(0){//DeBug Speeds
for(inti=0;i<(nvel);i++){Serial.print(v[i]);Serial.print(",");}Serial.print(" vel:");Serial.println(vel);}}}
Processing总程序
// Arduino: _14_HV_logger_2Ch
// VOLTAGE IN PIN Analog0
// CURRENT IN PIN Analog1
importprocessing.serial.*;SerialUSB;Stringmessage=null;intjmax=100000;// Stored readings
int[]VminADC;// From 0 to jmax
int[]VmaxADC;// Raw values
int[]IminADC;int[]ImaxADC;float[]Vmin;// From 0 to jmax
float[]Vmax;// in kV and uA
float[]Imin;float[]Imax;intj=0;// Whole Register
intx=0;// On Screen
intxpant=1000;// Dimensions of the screen
intypant=800;intmSup=60;// Margin Sup and Inf of the trace
intmInf=50;intmLat=50;intxgraf=xpant-2*mLat;intxDisplay=30;// Beginning of the text
intyDisplay=30;floatCal0=1;floatCal1=1;floatCalVEL=300;//
floatCalPOS=400;//
PFontfontVerdana;String[]com=newString[3];voidsetup(){size(1000,800,P3D);println(Serial.list());StringportName=Serial.list()[0];// Puerto COM 14
USB=newSerial(this,portName,115200);VminADC=newint[jmax];VmaxADC=newint[jmax];IminADC=newint[jmax];ImaxADC=newint[jmax];Vmin=newfloat[jmax];Vmax=newfloat[jmax];Imin=newfloat[jmax];Imax=newfloat[jmax];com=newString[3];fontVerdana=loadFont("Verdana-20.vlw");}voiddraw(){background(190);// New Data ***************************************************************************
while(USB.available()>0){message=USB.readStringUntil(36);// 644,659,725,733$
if(message!=null){if(j<jmax-2){j++;}else{j=0;}message=message.substring(0,message.length()-1);// 644,659,725,733
String[]com=splitTokens(message,",");VminADC[j]=int(com[0])-200;// Stored in VminADC[j] as ADC
VmaxADC[j]=int(com[1])-200;IminADC[j]=int(com[2]);ImaxADC[j]=int(com[3]);print(VminADC[j]);print("\t");print(VmaxADC[j]);print("\t");print(IminADC[j]);print("\t");println(ImaxADC[j]);Vmin[j]=VminADC[j]*Cal0;// Stored in Vmin[j] as kV
Vmax[j]=VmaxADC[j]*Cal0;Imin[j]=IminADC[j]*Cal1;Imax[j]=ImaxADC[j]*Cal1;}}// Axis ********************************************************************************
stroke(255);strokeWeight(2);line(mLat-10,ypant-mInf,xpant-mLat,ypant-mInf);line(mLat,ypant-mInf+10,mLat,mSup);// Reference Axis *************************************************************************************
/* fill(#FF1C20); // Red
// text("500uA", 10, (ypant-mInf)-500*(ypant-mSup-mInf)/660+4);
stroke(#FF1C20, 20); // Red
line(mLat, (ypant-mInf)-500*(ypant-mSup-mInf)/660, xpant-mLat, (ypant-mInf)-500*(ypant-mSup-mInf)/660);
*/fill(#321CFF);// Blue
text("0",30,mSup+(ypant-mInf-mSup)/2+4);stroke(#321CFF,20);// Blue
line(mLat,mSup+(ypant-mInf-mSup)/2,xpant-mLat,mSup+(ypant-mInf-mSup)/2);// Draw before 1st scroll ********************************************************************************************
if(j<=xgraf){for(inti=0;i<j;i++){strokeWeight(1);stroke(#FF1C20);// Red VELOCIDAD
line(i+mLat,int(mSup+(ypant-mInf-mSup)/2)-Imin[i]*(ypant-mInf-mSup)/CalVEL-2,i+mLat,int(mSup+(ypant-mInf-mSup)/2)-Imax[i]*(ypant-mInf-mSup)/CalVEL+2);stroke(#321CFF);// Blue POSICIÓN
line(i+mLat,int(mSup+(ypant-mInf-mSup)/2)-Vmin[i]*(ypant-mInf-mSup)/CalPOS-2,i+mLat,int(mSup+(ypant-mInf-mSup)/2)-Vmax[i]*(ypant-mInf-mSup)/CalPOS+2);}}// Draw with scroll **************************************************************************************************************
if(j>xgraf){for(inti=0;i<=xgraf;i++){strokeWeight(1);stroke(#FF1C20);// Red
// line(i+mLat, int((ypant-mInf)-Imin [j-xgraf+i]*(ypant-mSup-mInf)/660), i+mLat, int((ypant-mInf)-Imax [j-xgraf+i]*(ypant-mSup-mInf)/660));
line(i+mLat,int(mSup+(ypant-mInf-mSup)/2)-Imin[j-xgraf+i]*(ypant-mInf-mSup)/CalVEL-2,i+mLat,int(mSup+(ypant-mInf-mSup)/2)-Imax[j-xgraf+i]*(ypant-mInf-mSup)/CalVEL+2);stroke(#321CFF);// Blue
// line(i+mLat, int((ypant-mInf)-Vmin [j-xgraf+i]*(ypant-mSup-mInf)/15), i+mLat, int((ypant-mInf)-Vmax [j-xgraf+i]*(ypant-mSup-mInf)/15));
line(i+mLat,int(mSup+(ypant-mInf-mSup)/2)-Vmin[j-xgraf+i]*(ypant-mInf-mSup)/CalPOS-2,i+mLat,int(mSup+(ypant-mInf-mSup)/2)-Vmax[j-xgraf+i]*(ypant-mInf-mSup)/CalPOS+2);}}// Text Channels Readings ***************************************************************
stroke(190);fill(190);// Blue
rect(30,12,330,20);textFont(fontVerdana,20);fill(#321CFF);// Blue
text(int(Vmin[j])+" mm",xDisplay,yDisplay);textFont(fontVerdana,10);// text("+/-" + nf((Vmax[j] - Vmin[j]), 0, 1) +" kV", xDisplay + 80, yDisplay);
textFont(fontVerdana,20);fill(#FF1C20);// Red
text(int(Imax[j])+" mm/s",xDisplay+200,yDisplay);textFont(fontVerdana,10);// text("+/-" + int((Imax[j] - Imin[j])) +" uA", xDisplay + 200 + 80, yDisplay);
}/*void keyPressed() {
if (key == 's' || key =='S') {
grabar();
}
if (key == 'v' || key =='V') {
Cal0 = 9.0/((VminADC [j]+VmaxADC [j])/2); // 9 kV equals 489 ADC
println("Calibración de Tensión: "+ Cal0);
}
if (key == 'i' || key =='I') {
Cal1 = 660.0/((IminADC [j]+ImaxADC [j])/2);
println("Calibración de Intensidad: "+ Cal1);
}
}
*/voidgrabar(){String[]lines=newString[j];for(inti=0;i<j;i++){lines[i]=str(Vmin[i+1])+"\t"+str(Vmax[i+1])+"\t"+str(Imin[i+1])+"\t"+str(Imax[i+1]);// Vmin Vmax Imin Imax
}saveStrings("Registro.txt",lines);exit();}
Thomas L. Floyd,1964年获得佛罗里达大学电气工程学士学位,同年在德州仪器公司开始职业生涯,1968年获得南卫理公会大学电气工程硕士学位,之后在马丁·玛丽埃塔公司任职高级工程师,从事导弹制导系统和数字通信系统的研发。1973年,他成为瓦伦西亚社区学院的全职教师,担任新电子科技计划项目主管,负责开发课程、设计实验室及授课。1977年,他撰写了第一本世界级畅销书《Digital Fundamentals》(现已更新至第11版),同年加入北卡罗来纳州美林社区学院,并出版了第二本畅销书《Electronics Fundamentals: Circuits, Devices & Applications》(现已更新至第8版)。1983年,他开始专职写作,先后出版了《Operational Amplifiers and Linear Integrated Circuits》(现已更新至第6版)和《Electric Circuits Fundamentals》(现已更新至第8版)。近年来,除了本书之外,Floyd还出版了另外两本世界著名教材:《DC/AC Fundamentals: A Systems Approach》和《Digital Fundamentals: A Systems Approach》。
Thomas L. Floyd,1964年获得佛罗里达大学电气工程学士学位,同年在德州仪器公司开始职业生涯,1968年获得南卫理公会大学电气工程硕士学位,之后在马丁·玛丽埃塔公司任职高级工程师,从事导弹制导系统和数字通信系统的研发。1973年,他成为瓦伦西亚社区学院的全职教师,担任新电子科技计划项目主管,负责开发课程、设计实验室及授课。1977年,他撰写了第一本世界级畅销书《Digital Fundamentals》(现已更新至第11版),同年加入北卡罗来纳州美林社区学院,并出版了第二本畅销书《Electronics Fundamentals: Circuits, Devices & Applications》(现已更新至第8版)。1983年,他开始专职写作,先后出版了《Operational Amplifiers and Linear Integrated Circuits》(现已更新至第6版)和《Electric Circuits Fundamentals》(现已更新至第8版)。近年来,除了本书之外,Floyd还出版了另外两本世界著名教材:《DC/AC Fundamentals: A Systems Approach》和《Digital Fundamentals: A Systems Approach》。
Automatic Control Systems provides engineers with a fresh new controls book that places special emphasis on mechatronics. It follows a revolutionary approach by actually including a physical lab. In addition, readers will find authoritative coverage of modern design tools and examples. Current mechatronics applications build motivation to learn the material. Extensive use of virtual lab software is also integrated throughout the chapters. Engineers will gain a strong understand of control systems with the help of modern examples and exercises.
Benjamin C. Kuo博士 是伊利诺伊大学厄巴纳 - 香槟分校电子与计算机工程系名誉教授。他是IEEE的会员,并在控制系统的理论和应用研究方面获得了许多奖项。他撰写了大量论文,并撰写了10多本有关控制系统的书籍。他在工业界广泛咨询过。
网友书评
The best general book about control engineering
I had to use this book for my last semester in electrical engineering. It is really interesting, well explained and complete for a concise introduction about control engineering and design of controllers.
All you need to follow the text are basic notions in engineer's mathematics (a bit of calculus and algebra). A few chapters offer reviews of important notions (transfert functions, state variable modeling, differential equations, ...) Then, you get to the essential, control theory.
The book is well divided. First chapters cover mathematical notions you have to master in order to succeed in the next part (signal flow diagrams, block diagrams, a bit of mechanic). Then, a few chapters introduce control loops, poles and zeros interpretation (explained very well with a lot of graphs examples). A single chapter covers root loci drawing. Great explanations about controllers are complete and easy to understand. The last chapter is kept for design only with A LOT of examples for PID, phase-lag, filters, etc.
Emphasis is made on computer design with examples all along the book. The CD included offers a few useful tools to use for design with Matlab.
The author knows his subject more than anyone else. He has good experience in design and the text is well written. A must for anyone studying the subject.
这本市场领先的教科书仍然是卓越和创新的标准。建立在Adel S. Sedra和Kenneth C. Smith的坚实教学基础之上,第七版微电子电路是最好的。除了旨在反映IC技术变化的更新内容和覆盖范围外,该文本还提供了当今可用的最全面,灵活,准确和面向设计的电子电路处理方法。通过丰富的实例充分说明,并辅以更多精心设计的章末问题和实践练习,微电子电路是教授明天工程师如何分析和设计电子电路的最新资源
Paul Horowitz 哈佛大学物理学教授。他在哈佛任教物理学与电子学的同时,首开了哈佛的实验电子学课程,迄今已有15年了。他的研究兴趣广泛,涉猎观测天体物理学、X射线与粒子显微技术、光干涉技术测量技术以及外星人探索等研究领域。作为已有60多篇技术文章与报告的作者,他也广泛地为工业和政府有关部门做咨询顾问工作,并且是大量电子与摄影仪器的设计者。