Aloin päätä seinään hakkaamalla ratkoa ongelmaa niin, että otin toimivan tasapainottelurobotin koodin toiseen ruutuun auki ja aloin päivittämään omaa ohjelmaani… No… Ohjelmassa ei ainakaan virheitä ole, mutta ei se kyllä oikein toimikkaan…
Mihin mun pitäs tota PIDiä oikein käyttää? No helppo vastaus: tasottamaan moottorin liikettä, no mites?
Käytänkö PID lausekkeessa ulkolämpötilaa, patteriverkon veden lämpötilaa, servon asentoa, haluttua lämpötilaa tietylle ulkolämpötilalle vai pitääkö erikseen lisätä vielä jokin potikka tuohon servon kaveriksi joka kertoo asentoa?
Mistä mä keksin kP, kI ja kD arvot? entä servon mistä tekasen sen arvon jolla säädetään?
Hohhoijaa…
No tässä viritys jonka tein:
[code]#include <Servo.h>
Servo shuntti;
int ulkoMittaus = 0;
int vesiMittaus = 0;
int asento;
double ulkolampoYHT = 0;
double vesilampoYHT = 0;
int ulkolampoKA = 0;
int vesilampoKA = 0;
int EDvesilampoKA = 0;
int EDasento = 0;
int ulkoanturi = A0;
int vesianturi = A1;
int vikaled = 13;
int powerled =12;
//PIDiä varten
float time = 0;
float P = 0;
float I = 0;
float D = 0;
float kP = 10;
float kI = 0;
float kD = 0;
void setup()
{
pinMode(vikaled, OUTPUT);
pinMode(ulkoanturi, INPUT);
pinMode(vesianturi, INPUT);
shuntti.attach(9);
Serial.begin(9600);
}
void mittaus()
{
digitalWrite(12, HIGH);
for (int toisto=0; toisto < 600; toisto++)
{
ulkoMittaus = analogRead(ulkoanturi);
double ulkolampo = ulkoMittaus * (4950.00 / 1024); // 4720 on mitattu jännite anturin nastoista, eli 4.72V
ulkolampoYHT = ulkolampoYHT + ulkolampo;
delay(20);
vesiMittaus = analogRead(vesianturi);
double vesilampo = vesiMittaus *(4950.00 / 1024);
vesilampoYHT = vesilampoYHT + vesilampo;
delay(20);
}
}
void KAlaskenta(){
ulkolampoKA = ulkolampoYHT / 10 / 600; // ensimmäinen jako muuttaa asteiksi, toinen jako laskee keskiarvon
vesilampoKA = vesilampoYHT / 10 / 600;
if (ulkolampoKA > 45){
digitalWrite(13, HIGH); // vikavalo syttyy jos lämpötilamittaus totaalisen pielessä / anturia ei tunnisteta
ulkolampoKA = 0;
}
}
void loop(){
mittaus();
KAlaskenta();
float previousTime = time;
time = millis();
float interval = time - previousTime;
P = vesilampoKA / kP;
I = I + (P * interval) / kI;
D = (vesilampoKA - EDvesilampoKA) / interval / kD;
float PID = P + I + D;
shuntti.write(100 - PID); //tänne laitettu arvoksi vaan rannetta ravistamalla 100, ei perustu mihinkään
Serial.print("TEMP: ");
Serial.print(ulkolampoKA);
Serial.println("c");
Serial.print("TEMP_v: ");
Serial.print(vesilampoKA);
Serial.println("c");
Serial.print("P: ");
Serial.println(P);
Serial.print("I: ");
Serial.println(I);
Serial.print("D: ");
Serial.println(D);
Serial.print("interval: ");
Serial.println(interval);
Serial.print("Servon asento: ");
Serial.println(asento);
Serial.print("PID: ");
Serial.println(PID);
Serial.println("");
Serial.println("");
ulkolampoYHT = 0;
vesilampoYHT = 0;
ulkolampoKA = 0;
vesilampoKA = 0;
EDvesilampoKA = vesilampoKA;
}
[/code]
–
Tuomo