From 46be4f24ce02a5e93d9fec3570fc450f880be64c Mon Sep 17 00:00:00 2001 From: Peter_Held Date: Sat, 25 Mar 2023 16:20:31 +0100 Subject: [PATCH] 1. Version --- TimerInterruptV1.ino | 201 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 TimerInterruptV1.ino diff --git a/TimerInterruptV1.ino b/TimerInterruptV1.ino new file mode 100644 index 0000000..33957eb --- /dev/null +++ b/TimerInterruptV1.ino @@ -0,0 +1,201 @@ +//#include +#include +#include + +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(); +}