PID 제어를 이용해서
LED 밝기를 제어
구글링을 해서 잘 설명된 PDF가 있네..
참고참고!
모터 PID 제어를 위하여!!
ps. 모터 PID 제어를 위해선 Feedback을 받기 위한 장치가 있어야 하는데..
인코더 달린 모터는 왜이리 비싸냐는... ㅠㅠ
그러다가 어디서 언뜻 봤는데..
옛날 볼 마우스에 인코더가 달려 있다는 말을 듣고
얼른 볼 마우스를 구해서 보니
아앗!!
인코더가 있다!!
무려 3개씩이나!!
휠에 하나 볼마우스 X, Y축에 각각 하나씩!
다만 휠은 해상도가 좀 떨어지네 ㅎㅎ;;
#include <PID_v1.h>
const int photores = A5; // Photo resistor input
const int pot = A4; // Potentiometer input
const int led = 9; // LED output
double lightLevel; // variable that stores the incoming light level
// Tuning parameters
float Kp=0; //Initial Proportional Gain
float Ki=10; //Initial Integral Gain
float Kd=0; //Initial Differential Gain
double Setpoint, Input, Output; //These are just variables for storingvalues
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
// This sets up our PDID Loop
//Input is our PV
//Output is our u(t)
//Setpoint is our SP
const int sampleRate = 1; // Variable that determines how fast our PID loop runs
// Communication setup
const long serialPing = 100; //This determines how often we ping our loop
// Serial pingback interval in milliseconds
unsigned long now = 0; //This variable is used to keep track of time
// placehodler for current timestamp
unsigned long lastMessage = 0; //This keeps track of when our loop last spoke to serial
// last message timestamp.
void setup(){
lightLevel = analogRead(photores); //Read in light level
Input = map(lightLevel, 0, 1024, 0, 255); //Change read scale to analog out scale
Setpoint = map(analogRead(pot), 0, 1024, 0, 255);
//get our setpoint from our pot
Serial.begin(9600); //Start a serial session
myPID.SetMode(AUTOMATIC); //Turn on the PID loop
myPID.SetSampleTime(sampleRate); //Sets the sample rate
Serial.println("Begin"); // Hello World!
lastMessage = millis(); // timestamp
}
void loop(){
Setpoint = map(analogRead(pot), 0, 1024, 0, 255); //Read our setpoint lightLevel = analogRead(photores); //Get the light level
Input = map(lightLevel, 0, 900, 0, 255); //Map it to the right scale
myPID.Compute(); //Run the PID loop
analogWrite(led, Output); //Write out the output from the PID loop to our LED pin
now = millis(); //Keep track of time
if(now - lastMessage > serialPing) { //If it has been long enough give us some info on serial
// this should execute less frequently
// send a message back to the mother ship
Serial.print("Setpoint = ");
Serial.print(Setpoint);
Serial.print(" Input = ");
Serial.print(Input);
Serial.print(" Output = ");
Serial.print(Output);
Serial.print("\n");
if (Serial.available() > 0) { //If we sent the program a command deal with it
for (int x = 0; x < 4; x++) {
switch (x) {
case 0:
Kp = Serial.parseFloat();
break;
case 1:
Ki = Serial.parseFloat();
break;
case 2:
Kd = Serial.parseFloat();
break;
case 3:
for (int y = Serial.available(); y == 0; y--) {
Serial.read(); //Clear out any residual junk
}
break;
}
}
Serial.print(" Kp,Ki,Kd = ");
Serial.print(Kp);
Serial.print(",");
Serial.print(Ki);
Serial.print(",");
Serial.println(Kd); //Let us know what we just received
myPID.SetTunings(Kp, Ki, Kd); //Set the PID gain constants and start running
}
lastMessage = now;
//update the time stamp.
}
}