//#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(); }