Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <PID_v1.h>
- #include <PID_AutoTune_v0.h>
- #include <QTRSensors.h>
- #define NUM_SENSORS 5
- #define NUM_SAMPLES_PER_SENSOR 2
- #define EMITTER_PIN QTR_NO_EMITTER_PIN
- #define inA 2
- #define inB 4
- #define inC 6
- #define inD 7
- #define enA 3
- #define enB 5
- QTRSensorsAnalog qtra((unsigned char[]) {0, 1, 2, 3, 4}, NUM_SENSORS, NUM_SAMPLES_PER_SENSOR, EMITTER_PIN);
- unsigned int sensorValues[NUM_SENSORS];
- int baseSpeed = 150;
- int maxSpeed = 250;
- byte ATuneModeRemember=2;
- double input=80, output=50, setpoint=180;
- double kp=0.2,ki=0.5,kd=2.25;
- double kpmodel=1.5, taup=100, theta[50];
- double outputStart=5;
- double aTuneStep=50, aTuneNoise=1, aTuneStartValue=100;
- unsigned int aTuneLookBack=20;
- boolean tuning = true;
- unsigned long modelTime, serialTime;
- PID myPID(&input, &output, &setpoint,kp,ki,kd, DIRECT);
- PID_ATune aTune(&input, &output);
- //set to false to connect to the real world
- boolean useSimulation = false;
- void setup()
- {
- initializePins();
- calibrateSensors();
- if(useSimulation)
- {
- for(byte i=0;i<50;i++)
- {
- theta[i]=outputStart;
- }
- modelTime = 0;
- }
- //Setup the pid
- myPID.SetMode(AUTOMATIC);
- if(tuning)
- {
- tuning=false;
- changeAutoTune();
- tuning=true;
- }
- serialTime = 0;
- Serial.begin(9600);
- }
- void loop()
- {
- unsigned long now = millis();
- if(!useSimulation)
- { //pull the input in from the real world
- input = (int)qtra.readLine(sensorValues, QTR_EMITTERS_ON, true);
- }
- if(tuning)
- {
- byte val = (aTune.Runtime());
- if (val!=0)
- {
- tuning = false;
- }
- if(!tuning)
- { //we're done, set the tuning parameters
- kp = aTune.GetKp();
- ki = aTune.GetKi();
- kd = aTune.GetKd();
- myPID.SetTunings(kp,ki,kd);
- AutoTuneHelper(false);
- }
- }
- else myPID.Compute();
- if(useSimulation)
- {
- theta[30]=output;
- if(now>=modelTime)
- {
- modelTime +=100;
- DoModel();
- }
- }
- else
- {
- analogWrite(0,output);
- }
- //send-receive with processing if it's time
- if(millis()>serialTime)
- {
- SerialReceive();
- SerialSend();
- serialTime+=500;
- }
- wheel(baseSpeed + (int)(round(output)), baseSpeed - (int)(round(output)));
- }
- void changeAutoTune()
- {
- if(!tuning)
- {
- //Set the output to the desired starting frequency.
- output=aTuneStartValue;
- aTune.SetNoiseBand(aTuneNoise);
- aTune.SetOutputStep(aTuneStep);
- aTune.SetLookbackSec((int)aTuneLookBack);
- AutoTuneHelper(true);
- tuning = true;
- }
- else
- { //cancel autotune
- aTune.Cancel();
- tuning = false;
- AutoTuneHelper(false);
- }
- }
- void AutoTuneHelper(boolean start)
- {
- if(start)
- ATuneModeRemember = myPID.GetMode();
- else
- myPID.SetMode(ATuneModeRemember);
- }
- void SerialSend()
- {
- Serial.print("setpoint: ");Serial.print(setpoint); Serial.print(" ");
- Serial.print("input: ");Serial.print(input); Serial.print(" ");
- Serial.print("output: ");Serial.print(output); Serial.print(" ");
- if(tuning){
- Serial.println("tuning mode");
- } else {
- Serial.print("kp: ");Serial.print(myPID.GetKp());Serial.print(" ");
- Serial.print("ki: ");Serial.print(myPID.GetKi());Serial.print(" ");
- Serial.print("kd: ");Serial.print(myPID.GetKd());Serial.println();
- }
- }
- void SerialReceive()
- {
- if(Serial.available())
- {
- char b = Serial.read();
- Serial.flush();
- if((b=='1' && !tuning) || (b!='1' && tuning))changeAutoTune();
- }
- }
- void DoModel()
- {
- //cycle the dead time
- for(byte i=0;i<49;i++)
- {
- theta[i] = theta[i+1];
- }
- //compute the input
- input = (kpmodel / taup) *(theta[0]-outputStart) + input*(1-1/taup) + ((float)random(-10,10))/100;
- }
- void initializePins()
- {
- pinMode(inA, OUTPUT);
- pinMode(inB, OUTPUT);
- pinMode(inC, OUTPUT);
- pinMode(inD, OUTPUT);
- pinMode(enA, OUTPUT);
- pinMode(enB, OUTPUT);
- digitalWrite(inA, HIGH);
- digitalWrite(inB, HIGH);
- digitalWrite(inC, HIGH);
- digitalWrite(inD, HIGH);
- digitalWrite(enA, LOW);
- digitalWrite(enB, LOW);
- }
- void wheel(int lm, int rm)
- {
- if(lm>maxSpeed) lm=maxSpeed;
- if(lm<-maxSpeed) lm=-maxSpeed;
- if(rm>maxSpeed) rm=maxSpeed;
- if(rm<-maxSpeed) rm=-maxSpeed;
- analogWrite(enA,abs(rm));
- analogWrite(enB,abs(lm));
- if(lm==0)
- {
- digitalWrite(inC,HIGH);
- digitalWrite(inD,HIGH);
- }
- if(lm<0)
- {
- digitalWrite(inC,HIGH);
- digitalWrite(inD,LOW);
- }
- else if(lm>0)
- {
- digitalWrite(inC,LOW);
- digitalWrite(inD,HIGH);
- }
- if(rm==0)
- {
- digitalWrite(inA,HIGH);
- digitalWrite(inB,HIGH);
- }
- if(rm<0)
- {
- digitalWrite(inA,HIGH);
- digitalWrite(inB,LOW);
- }
- else if(rm>0)
- {
- digitalWrite(inA,LOW);
- digitalWrite(inB,HIGH);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement