202 lines
4.4 KiB
C++
202 lines
4.4 KiB
C++
//#include <Arduino.h>
|
|
#include <math.h>
|
|
#include <U8g2lib.h>
|
|
|
|
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); //Andreas
|
|
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); //Leonhard
|
|
|
|
void TIM1_init();
|
|
void TIM2_init();
|
|
void LCD_printData();
|
|
double get_tempValue(int SensorValue);
|
|
void LCD_printGrid();
|
|
|
|
int Temperatur;
|
|
int TempSensor = 0;
|
|
float Voltage;
|
|
int Ausgangssignal = 0;
|
|
int status = 0;
|
|
int Stellsignal = 0;
|
|
int counterx=0;
|
|
int i=2;
|
|
|
|
|
|
//Variablen Regelung
|
|
|
|
//Eingangssignal
|
|
double Sollwert=70;
|
|
//Abtastzeit
|
|
double Ta=1;
|
|
//PIDT-Regler Zeitkonstanten (multiplikative Form)
|
|
double VR=2;
|
|
double TN=80;
|
|
double TV=1;
|
|
double TR=TV/10.0;
|
|
//PIDT-Regler Zeitkonstanten (additive Form)
|
|
double VR_Stern=VR*(1.0+(TV/TN));
|
|
double TN_Stern=TN*(1.0+(TV/TN));
|
|
double TV_Stern=TV/(1.0+(TV/TN));
|
|
double TI=TN_Stern/VR_Stern;
|
|
double TD=TV_Stern*VR_Stern;
|
|
//Eingangssignal Regler ek
|
|
double ek=0;
|
|
//Globale Variable für Zeitdiskrete Regelung
|
|
double yk1=0;
|
|
double yk1vorher=0;
|
|
double yk2=0;
|
|
double yk2vorher=0;
|
|
double yk3=0;
|
|
double yk3vorher=0;
|
|
double yk4=0;
|
|
double yk4vorher=0;
|
|
//Ausgangssignal Regler yk
|
|
double yk=0;
|
|
|
|
void setup()
|
|
{
|
|
pinMode(13, OUTPUT);
|
|
pinMode(3, OUTPUT);
|
|
digitalWrite(3, LOW);
|
|
u8g2.begin();
|
|
u8g2.clearBuffer();
|
|
LCD_printGrid();
|
|
cli(); //disable global interrupts
|
|
TIM1_init(); //Timer 1 für Ta=100ms
|
|
TIM2_init(); //Timer 2 für PWM
|
|
sei(); //enable global interrupts
|
|
}
|
|
|
|
void loop()
|
|
{
|
|
LCD_printData();
|
|
}
|
|
|
|
ISR(TIMER1_COMPA_vect)
|
|
{
|
|
status=1;
|
|
digitalWrite(13, !digitalRead(13)); // toggle LED with T=TA
|
|
TempSensor=analogRead(A0);
|
|
if(595<=TempSensor)
|
|
{
|
|
Temperatur=get_tempValue(TempSensor);
|
|
}
|
|
ek=Sollwert-Temperatur; //Eingangssignal
|
|
//PT1-Anteil:
|
|
yk1vorher=yk1vorher*(TR/(Ta+TR));
|
|
yk1=ek*(Ta/(Ta+TR))+yk1vorher;
|
|
yk1vorher=yk1;
|
|
//P-Anteil:
|
|
yk2=yk1*VR_Stern;
|
|
//I-Anteil:
|
|
yk3=yk1*(Ta/TI)+yk3vorher;
|
|
yk3vorher=yk3;
|
|
//D-Anteil:
|
|
yk4=yk1*(TD/Ta)-yk4vorher;
|
|
yk4vorher=(TD/Ta)*yk1;
|
|
//Addition P-, I-, und D-Anteil
|
|
yk=yk2+yk3+yk4;
|
|
//Begrenzung Ausgangssignal auf 100
|
|
if(yk>=100)
|
|
{
|
|
yk=100;
|
|
}
|
|
|
|
//PWM Ausgangssignal
|
|
Stellsignal=255*(yk/100);
|
|
if(yk>=100)
|
|
{
|
|
Stellsignal=255;
|
|
}
|
|
if(yk<=0)
|
|
{
|
|
Stellsignal=0;
|
|
}
|
|
OCR2B = Stellsignal; //PWM Duty Cycle
|
|
counterx++;
|
|
}
|
|
|
|
void TIM1_init()
|
|
{
|
|
TCNT1 = 0; //Timer Counter 1
|
|
TCCR1A = 0; //Timer Counter Controll Register A
|
|
TCCR1B = 0; //Timer Counter Controll Register B
|
|
OCR1A = 15625; //Output Compare Register A -> Interrupt each second (1/16*10^6)*1024*15625 = 1s
|
|
TCCR1B |= 0x5; //Prescaler = 1024
|
|
TCCR1B |= 0x8; //CTC Bit -> TOP of Counter = OCR1A
|
|
TIMSK1 |= 0x2; //Tim1 Interrupt @ Output Compare Match A
|
|
}
|
|
|
|
|
|
void TIM2_init()
|
|
{
|
|
TCNT2 = 0; //Timer Counter 2
|
|
TCCR2A = 0; //Timer Counter Controll Register A
|
|
TCCR2B = 0; //Timer Counter Controll Register B
|
|
TCCR2A |= 0x23; //Non Inverting Mode
|
|
TCCR2B |= 0x7; //Prescaler = 1024
|
|
OCR2B = 0; //PWM Duty Cycle
|
|
DDRD |= (1 << PD3); //Port Output
|
|
}
|
|
|
|
double get_tempValue(int SensorValue)
|
|
{
|
|
double a=0.0231;
|
|
double b=0.26;
|
|
double c=5.22;
|
|
double calculatedVoltage=5.0*(SensorValue/1023.0);
|
|
return log((c-calculatedVoltage)/b)*(1/a);
|
|
}
|
|
|
|
void LCD_printData()
|
|
{
|
|
if(status==1)
|
|
{
|
|
if(i>123)
|
|
{
|
|
LCD_printGrid();
|
|
i=2;
|
|
}
|
|
u8g2.setFontMode(1);
|
|
u8g2.setFont(u8g2_font_6x10_tf);
|
|
u8g2.setDrawColor(1);
|
|
u8g2.drawBox(0, 0, 127, 9);
|
|
u8g2.setDrawColor(2);
|
|
u8g2.drawBox(0, 0, 127, 9);
|
|
u8g2.setCursor(2,8);
|
|
u8g2.print(F("Ti:"));
|
|
u8g2.print(get_tempValue(TempSensor),0);
|
|
if(counterx%5==0) //each 5seconds new TempPlot
|
|
{
|
|
if(get_tempValue(TempSensor)>-5&&get_tempValue(TempSensor)<100)
|
|
{
|
|
u8g2.drawPixel(i++, 63-((get_tempValue(TempSensor)/100.0))*55);
|
|
}
|
|
}
|
|
u8g2.setCursor(42,8);
|
|
u8g2.print(F("Ts:"));
|
|
u8g2.print(Sollwert,0);
|
|
u8g2.setCursor(84,8);
|
|
u8g2.print(F("St:"));
|
|
u8g2.print(yk,0);
|
|
u8g2.sendBuffer();
|
|
status=0;
|
|
}
|
|
}
|
|
|
|
void LCD_printGrid()
|
|
{
|
|
u8g2.clearBuffer();
|
|
u8g2.setFontMode(1);
|
|
u8g2.drawLine(1, 63, 127, 63);
|
|
u8g2.drawLine(0, 10, 0, 63);
|
|
for(int a=10; a<=100; a=a+10)
|
|
{
|
|
u8g2.drawLine(0, (63-(a/100.0)*55), 2, (63-(a/100.0)*55));
|
|
}
|
|
for(int a=10; a<127; a=a+10)
|
|
{
|
|
u8g2.drawLine(a, 61, a, 63);
|
|
}
|
|
u8g2.sendBuffer();
|
|
}
|