' Version 1.0 der Audine-Controller-Software ' Unterstütztung von 2 x LM76 und Temperatur Regler ' ' Stefan Haas. 18.10. 2002 ' ' Ports define Display_RS port[10] ' 2. Bit des 2. Portes define Display_RW port[11] define Display_EN port[12] define Display_D4 port[13] define Display_D5 port[14] define Display_D6 port[15] define Display_D7 port[16] define Display_Full BytePort[2] 'D7,D6,D5,D4,EN,RW,RS,NC define LCDLightnessPort DA[2] define ADBatt AD[3] ' Im CControl-Handbuch als AD 2 Beschriftet define PeltierPowerDA DA[1] define I2C_sda port[8] ' Datenleitung des I2C Bus zu den Temperatur-Sensoren LM75 define I2C_scl port[7] ' Dito Takt define BtnUp Port[1] ' Rechter Button, negative Logik define BtnSelect Port[2] ' Mittlerer Button, negative Logik define BtnDown Port[3] ' Linker Button, negative Logik ' Variablen define x byte ' Universelle Byte Var define y word ' Universelle Word Var define z word ' Universelle Word Var define PowerPercent byte ' Kühlleistung in % define LCDLightness byte ' Helligkeits Wert der LCD Beleuchtung 0..9 define CurrCCDTemp word ' Aktuelle Kalt Temperatur in 0.1 Grad mit Vorzeichen define LastCCDTemp word ' Temperatur bei letzter Regler Iteration (alle 90s) define TempRegDelay byte ' counter reduziert die Regler Frequenz auf 1/90s define SollTemp word ' Soll Temp in 0.1 Grad mit Vorzeichen define FuehrungsTemp word ' Temp in 0.1 Grad mit Vorzeichen die der Regler ' versucht zu erreichen um eine maximale Steigung ' nicht zu überscheiten (Stichwort abkühl Rampe) ' "Hinkt" ggf der SollTemp hinter her define IsRegelMode byte ' Bei RegelModus = 0; bei SteuerModus = 0; define lastRTCSecond byte ' Letzter gelesener Sekunden Wert der der RTC ' Konstanten define defaultCoolTemp -250 ' default kühl-Temperatur in zehntel Grad goto MainProgram ' ------------------------------------------------------------------------------------------- ' Funktion zur Temperatur Regelung ' muß alle 1 s aufgerufen werden ' die Funktion berechnet und setzt den Peltier Strom alle 90 s neu ' um die vorgegebene Temperatur in SollTemp zu halten ' verändert: ' z, y, PowerPercent, LastCCDTemp, TempRegDelay ' ------------------------------------------------------------------------------------------- #CalcAndSetPowerForTemp ' --------------------------------------------- TempRegDelay = TempRegDelay + 1 if TempRegDelay < 90 then return ' nur alle 90 s Strom neu berechnen TempRegDelay = 0 gosub read_temp_cold ' Temp nach y lesen CurrCCDTemp = y ' kopieren für regler ' --------------------------------------------- ' Plausibilität der Messung prüfen ' --------------------------------------------- y = abs(CurrCCDTemp - LastCCDTemp) ' wie viel geändert seit letztem mal? if Y < 150 then goto TempPlausiOK ' weniger als 15 °C in den letzten 90s gosub read_temp_cold ' im Zweifelsfall Temp noch mal nach y lesen CurrCCDTemp = y ' kopieren für regler y = abs(CurrCCDTemp - LastCCDTemp) ' wie viel geändert seit letztem mal? if Y < 150 then goto TempPlausiOK ' weniger als 15 °C in den letzten 90s IsRegelMode = 0 ' Regel Modus abschalten da Temp Messung ' unsicher oder Regler schwingt return #TempPlausiOK ' --------------------------------------------- ' max Rampen Steigung limitieren ' 170 = RampenSteigung (durch Simulation ermittelt. ergibt ca 6°C / Min) ' --------------------------------------------- FuehrungsTemp = SollTemp ' Erst mal als Vorgabe denn das ist ' der letztlich angestrebte Wert if FuehrungsTemp < CurrCCDTemp - 170 then FuehrungsTemp = CurrCCDTemp - 170 if FuehrungsTemp > CurrCCDTemp + 170 then FuehrungsTemp = CurrCCDTemp + 170 ' --------------------------------------------- y = CurrCCDTemp - LastCCDTemp ' CCD Temp Änderung während der letzten 1.5 Min => Tendenz z = CurrCCDTemp - FuehrungsTemp ' Wie weit sind wir vom Soll weg? => RestFehler z = z + y ' ApproxFutureErr = RestFehler + Tendenz ' Geschätzter Restfehler wenn es noch 1,5 min so weiter geht ' also die Leistung gleich bleibt ' Steigung der Kühlung ist ca: Delta 45°C bei delta 50% also ca. 1°C pro 1% ' (Wert aus Messdiagramm entnommen.) ' exakt wäre damit: z = z * 1.11 oder: KorrVal = ApproxFutureErr * 1.11 ' wir nähern an mit z = z * 1.0 d.h. "z" bleibt wie es ist ' z ist damit der Korrektur Wert für die Leistung die ' vermutlich in 1,5 Min, von jetzt an, benötigt wird. (Voraus Schätzung) ' --------------------------------------------- ' --------------------------------------------- z = (z / 10) ' jetzt noch z / 10 da alle Temperaturen auf zehntel Grad gemessen werden ' PowerPercent = PowerPercent + KorrVal z = z + PowerPercent ' nicht in PowerPercent addieren da byte => underflow gefahr if z < 0 then z = 0 if z > 99 then z = 99 PowerPercent = z Gosub setPowerPercent 'Prozent in 255 Digits umrechnen und anlegen (hat auch limiter) ' --------------------------------------------- ' --------------------------------------------- LastCCDTemp = CurrCCDTemp ' merken return ' ------------------------------------------------------------------------------------------- ' kommando in byte-Var x an display schreiben ' Verändert: ' Keine Var ' ------------------------------------------------------------------------------------------- #WriteDispCommand Display_Full = (x and &HF0) or 8 'D7,D6,D5,D4,EN,RW,RS,NC (high nibble) tog Display_EN 'senden Display_Full = (x shl 4) or 8 'low nibble tog Display_EN 'senden return ' ------------------------------------------------------------------------------------------- ' Cursor auf Stelle in x setzen ' Das Display-Ram hat 64 Zeichen pro Zeile auch wenn nur 16 sichtbar sind. ' Zeile 1 beginnt mit Adresse 0 ' Zeile 2 beginnt mit Adresse 64d ' Verändert: ' x ' ------------------------------------------------------------------------------------------- #Display_SetCursPos x = &B10000000 or x : gosub WriteDispCommand ' Adresse des Display-Rams (DD-Ram) setzen Return ' ------------------------------------------------------------------------------------------- 'display initialisieren (auf 4 bit bus) ' Verändert: ' x ' ------------------------------------------------------------------------------------------- #InitDisplay Display_Full = off pause 20 ' min 30 ms warten (hier 400) x = &B00100010 : gosub WriteDispCommand ' Function set (2 Kommandos) Display_Full = &B11001000 'D7,D6,D5,D4,EN,RW,RS,NC tog Display_EN 'senden 2 Zeilig, 5 x 7 Dots pause 1 ' > 39 us x = &B00001100 : gosub WriteDispCommand ' Display an, Cursor, Blink pause 1 ' > 39 us #Clear_LCD x = &B00000001 : gosub WriteDispCommand ' Display löschen pause 1 ' > 1,53 ms x = &B00000110 : gosub WriteDispCommand ' Entry Mode set pause 1 ' > 39 us return ' ------------------------------------------------------------------------------------------- ' Ein ASCII Zeichen aus x ins display schreiben ' Verändert: ' Keine Var ' ------------------------------------------------------------------------------------------- #WriteDispChar Display_Full = (x and &HF0) or &B00001010 'D7,D6,D5,D4,EN,RW,RS,NC (high nibble) tog Display_EN 'senden Display_Full = (x shl 4) or &B00001010 'low nibble tog Display_EN 'senden return ' ------------------------------------------------------------------------------------------- ' den numerischen Wert in y 2-stelling mit einer Nachkomma-Stelle ausgeben ' Verändert: ' x,y ' ------------------------------------------------------------------------------------------- #PlotFloat2_1Digit x = (y / 100) + 48 : Gosub WriteDispChar ' Zehner 48 ist zeichen "0" y = y mod 100 x = (y / 10) + 48 : Gosub WriteDispChar ' Einer y = y mod 10 x = 44 : Gosub WriteDispChar ' Komma x = y + 48 : Gosub WriteDispChar ' Dezi return ' ------------------------------------------------------------------------------------------- ' den numerischen Wert in y 2-stelling oder 5-Stellig ohne Nachkomma-Stelle ausgeben ' Verändert: ' x,y ' ------------------------------------------------------------------------------------------- #PlotInt5Digit ' 5 Stellig x = (y / 10000) + 48 : Gosub WriteDispChar ' Zehntausender 48 ist zeichen "0" y = y mod 10000 x = (y / 1000) + 48 : Gosub WriteDispChar ' Tausender y = y mod 1000 #PlotInt3Digit ' 3-Stellig x = (y / 100) + 48 : Gosub WriteDispChar ' Hunderter y = y mod 100 #PlotInt2Digit ' 2-Stellig if y > 99 then y = 99 ' überlauf verhindern x = (y / 10) + 48 : Gosub WriteDispChar ' Zehner 48 ist zeichen "0" y = y mod 10 x = y + 48 : Gosub WriteDispChar ' Einer return ' ------------------------------------------------------------------------------ ' Temperatur in y auf Display mit Vorzeichen und ohne Nachkomma Stelle ausgeben ' Wert in Y muß in zehntel Grad vorliegen ' Verändert: ' x,y ' ------------------------------------------------------------------------------ #PlotTemp_NoDecimal ' Vorzeichen behandeln und ausgeben if Y < 0 then goto NegativTemp_ND ' ------ positive temp vz behandeln x = 43 : Gosub WriteDispChar ' vorzeichen "+" ausgeben goto TempSignDone_ND #NegativTemp_ND ' ------ negative temp vz behandeln x = 45 : Gosub WriteDispChar ' vorzeichen "-" ausgeben y = -y ' ------ vz ausgegeben und y ggf. nach positiv berichtigt #TempSignDone_ND y = y / 10 ' Anzeige umrechnen in ganze Grad. gosub PlotInt2Digit ' Wert in Y ausgeben (Proc verändert x,y) x = 223 : Gosub WriteDispChar ' ° x = 67 : Gosub WriteDispChar ' C return ' ------------------------------------------------------------------------------ ' Temperatur in y auf Display mit Vorzeichen und einer Nachkomma Stelle ausgeben ' Wert in Y muß in zehntel Grad vorliegen ' Verändert: ' x,y ' ------------------------------------------------------------------------------ #PlotTemp ' Vorzeichen behandeln und ausgeben if Y < 0 then goto NegativTemp ' ------ positive temp vz behandeln x = 43 : Gosub WriteDispChar ' vorzeichen "+" ausgeben goto TempSignDone #NegativTemp ' ------ negative temp vz behandeln x = 45 : Gosub WriteDispChar ' vorzeichen "-" ausgeben y = -y ' ------ vz ausgegeben und y ggf. nach positiv berichtigt #TempSignDone gosub PlotFloat2_1Digit ' Wert in Y ausgeben (Proc verändert x,y) x = 223 : Gosub WriteDispChar ' ° x = 67 : Gosub WriteDispChar ' C return ' ------------------------------------------------------------------------------ ' temperatur in 16 Bit y-Var einlesen ' es werden der Warmseiten- und der Kaltseiten-Fühler unterschieden ' Das Ergebnis ist in Y in zehntel Grad ' Adresse Warm: 1001001 ' Adresse kalt: 1001011 ' Verändert: ' x,y ' ------------------------------------------------------------------------------ #read_temp_cold y = 1 ' Hilfs Flag für kalt Fühler goto do_read_temp #read_temp_warm y = 0 ' Hilfs Flag für warm #do_read_temp I2C_sda = off 'Start by Master I2C_scl = off ' ----------------------------- ' Achtung: SDA nie auf on setzen da SDA bidirektional (Kurzschluß möglich) ' beide Partner ziehen SDA nur auf Masse, ein Widerstand zieht die Leitung ' auf Plus. Deshalb immer nur: ' sda = off <=> low ' deact sda <=> high ' ----------------------------- ' LM76 Baustein adressieren Deact I2C_sda : gosub I2c_clock ' A6 = 1 10010 = ist im LM76 voreingestellt I2C_sda = off : gosub I2c_clock ' A5 = 0 I2C_sda = off : gosub I2c_clock ' A4 = 0 Deact I2C_sda : gosub I2c_clock ' A3 = 1 I2C_sda = off : gosub I2c_clock ' A2 = 0 if y = 1 then Deact I2C_sda ' kalt Fühler A1 = 1 if y <> 1 then I2C_sda = off ' warm Fühler A1 = 0 gosub I2c_clock ' A1 takten Deact I2C_sda : gosub I2c_clock ' A0 = 1 Deact I2C_sda : gosub I2c_clock ' 1 1=read 0=write DEACT I2C_sda ' ACK by LM75 erwarten I2C_scl = on 'if I2C_sda then print "kein LM76 Ack !!! " 'if I2C_sda = 0 then print "korrektes LM75 Ack nach Adressierung" I2C_scl = off ' MSB vom I2C Bus lesen (8Bit) y = 0 'Temperatur-Wert der eingelesen werden soll 16 Bit for x=0 to 7 I2C_scl = on y = y shl 1 'die Stellen von rechts nach links füllen if I2C_sda then y = y or 1 I2C_scl = off next I2C_sda = off 'Ack by Master absenden gosub I2C_clock DEACT I2C_sda ' LSB vom I2C Bus lesen (8Bit) for x=0 to 7 I2C_scl = on y = y shl 1 'die Stellen von rechts nach links füllen if I2C_sda then y = y or 1 I2C_scl = off next DEACT I2C_sda ' No Ack by Master gosub I2C_clock I2C_sda = off ' Stop Cond by Master I2C_scl = on DEACT I2C_sda ' Ergebnis in zehntel Grad umrechnen => y = y / 12.8 ' beim Fühler entsprechen -60°C... + 40°C = -7680...+5120 digits y = y / 10 ' => -768...+512 digits y = y * 25 y = y / 32 ' -600... +400 = zehntel Grad return ' ------------------------------------------------------------------------------ ' Subroutine clock erzeug eine Puls an scl ' Verändert: ' Keine Var ' ------------------------------------------------------------------------------ #I2C_clock I2C_scl = on I2C_scl = off return ' ------------------------------------------------------------------------------ ' Peltier Leistung anlegen ' dazu Prozent aus PowerPercent in 255 Digits umrechnen und anlegen ' Verändert: ' PowerPercent ' ------------------------------------------------------------------------------ #setPowerPercent if PowerPercent < 0 then PowerPercent = 0 ' limiter wichtig da aufrufer nicht prüfen if PowerPercent > 99 then PowerPercent = 99 ' limiter PeltierPowerDA = 255 - (PowerPercent * 255)/100 ' Prozent in 255 Digits umrechnen und anlegen return ' ------------------------------------------------------------------------------ ' Peltier Leistung anzeigen '42%' ' Verändert: ' x,y ' ------------------------------------------------------------------------------ #PlotPeltierPower y = PowerPercent ' Wert in Display-Ausgabe-Register Gosub PlotInt2Digit ' y auf Display ausgeben (Proc verändert x,y) x = 37 : Gosub WriteDispChar ' % return ' ------------------------------------------------------------------------------ ' Anwender hat im Hauptmenü Button up oder down gedrückt ' je nach modus wird entweder die Leistung PowerPercent oder die Solltemp verändert ' Verändert: ' x,y, PowerPercent ' ------------------------------------------------------------------------------ #ChangeSollwert if IsRegelMode = 1 then goto ChangeSollwertTemp ' ------------------------------------------- ' Leistung einstellen ' ------------------------------------------- if PowerPercent < 1 then goto MinLim if BtnDown = off then PowerPercent = PowerPercent - 1 ' off ist gedrückt #MinLim if PowerPercent > 99 then goto MaxLim if BtnUp = off then PowerPercent = PowerPercent + 1 ' off ist gedrückt #MaxLim Gosub setPowerPercent 'Prozent in 255 Digits umrechnen und anlegen x = 76 : Gosub Display_SetCursPos ' Cursor auf Zeichen 13 von Zeile 2 goto PlotPeltierPower ' Peltier Leistung anzeigen (Proc verändert x,y) ' ACHTUNG kein Gosub => Kehrt nicht hier her zurück return #ChangeSollwertTemp ' ------------------------------------------- ' Temperatur einstellen ' ------------------------------------------- if SollTemp < -599 then goto MinLimT ' Wert in zehntel Grad if BtnDown = off then SollTemp = SollTemp - 10 ' off ist gedrückt => 1 Grad weniger #MinLimT if SollTemp > 399 then goto MaxLimT if BtnUp = off then SollTemp = SollTemp + 10 ' off ist gedrückt #MaxLimT x = 4 : Gosub Display_SetCursPos ' Cursor auf Zeichen 5 von Zeile 1 y = SollTemp ' Neuen Wert anzeigen, dazu Soll Temp nach y goto PlotTemp_NoDecimal ' Temp von y auf LCD ausgeben ohne Nachkomma Stellen ' ACHTUNG kein Gosub => Kehrt nicht hier her zurück return ' ------------------------------------------------------------------------------ ' Batterie Spannung messen und anzeigen => Anzeige "12.5V" ' Verändert: ' x, y ' ------------------------------------------------------------------------------ #ReadAndShowBattVoltage y = (ADBatt * 10) / 17 ' 255 = 15 V wegen Teiler 1/3 und Referenz = 5 V ' in 100 mV umrechnen ' Korrekturwert dazu addieren da durch den Verpolungsschutz ' die Messung niedriger ist als dei Klemmen Spannung y = y + 2 + (PowerPercent / 33) ' 200 mV bei 0%, 500mV bei 100% Peltier Strom Gosub PlotFloat2_1Digit ' y ausgeben (Proc verändert x,y) x = 86 : Gosub WriteDispChar ' V return ' ------------------------------------------------------------------------------ ' Anwender hat im Helligkeits-Menü Button up oder down gedrückt ' Verändert: ' x,y, LCDLightness ' ------------------------------------------------------------------------------ #ProcessLightnessBtn if LCDLightness < 1 then goto MinLim_1 if BtnDown = off then LCDLightness = LCDLightness - 1 ' off ist gedrückt #MinLim_1 if LCDLightness > 7 then goto MaxLim_1 ' Bereich ist 0..8 if BtnUp = off then LCDLightness = LCDLightness + 1 ' off ist gedrückt #MaxLim_1 ' neuen DA Wert mit exponentialer Wertigkeit ermitteln x = 8 - LCDLightness LCDLightnessPort = 255 shr x ' neuen Wert anlegen x = 13 : Gosub Display_SetCursPos ' Cursor auf Zeichen 14 von Zeile 1 y = LCDLightness : Gosub PlotInt2Digit ' wert anzeigen (Proc verändert x,y) pause 30 ' warten bis Button wieder los gelassen return ' ------------------------------------------------------------------------------ ' Untermenü Helligkeit der Beleuchtung einstellen ' Verändert: ' x,y, LCDLightness ' Lightness 05 ' [-] [Ok] [+] ' ------------------------------------------------------------------------------ #LightnessMenue Gosub Clear_LCD x = 76 : Gosub WriteDispChar ' L x = 105 : Gosub WriteDispChar ' i x = 103 : Gosub WriteDispChar ' g x = 104 : Gosub WriteDispChar ' h x = 116 : Gosub WriteDispChar ' t x = 110 : Gosub WriteDispChar ' n x = 101 : Gosub WriteDispChar ' e x = 115 : Gosub WriteDispChar ' s x = 115 : Gosub WriteDispChar ' s x = 64 : Gosub Display_SetCursPos ' Anfang von Zeile 2 x = 91 : Gosub WriteDispChar ' [ x = 45 : Gosub WriteDispChar ' - x = 93 : Gosub WriteDispChar ' ] x = 32 : Gosub WriteDispChar ' x = 32 : Gosub WriteDispChar ' x = 32 : Gosub WriteDispChar ' x = 91 : Gosub WriteDispChar ' [ x = 79 : Gosub WriteDispChar ' O x = 75 : Gosub WriteDispChar ' K x = 93 : Gosub WriteDispChar ' ] x = 32 : Gosub WriteDispChar ' x = 32 : Gosub WriteDispChar ' x = 32 : Gosub WriteDispChar ' x = 91 : Gosub WriteDispChar ' [ x = 43 : Gosub WriteDispChar ' + x = 93 : Gosub WriteDispChar ' ] pause 30 Gosub ProcessLightnessBtn ' aktuellen Wert anzeigen (Proc verändert x,y) #LightnessMenueLoop #waitForSecondLM ' Warten auf Eingabe oder bis eine Sekunden um ist if BtnUp = off then Gosub ProcessLightnessBtn ' off ist gedrückt (negative logik) if BtnDown = off then Gosub ProcessLightnessBtn ' ändern und neu anzeigen if BtnSelect = off then return ' SelectBtn gedrückt => zurück zum Hauptmenü if lastRTCSecond = Second then goto waitForSecondLM if IsRegelMode = 1 then gosub CalcAndSetPowerForTemp ' Temp Regler 1 mal pro Sekunde aufrufen lastRTCSecond = Second ' Sekunden Wert der RTC merken goto LightnessMenueLoop ' ------------------------------------------------------------------------------ ' Auswahlmenü für ' -Modus Temp Regler / Leistungssteller ' -Zugang zum Helligkeitsmenü ' ---------------- ' Cool Dew ' -25°C [OK] Ta ' ------------------------------------------------------------------------------ #SelectCoolMenue Gosub Clear_LCD x = 67 : Gosub WriteDispChar ' C x = 111 : Gosub WriteDispChar ' o x = 111 : Gosub WriteDispChar ' o x = 108 : Gosub WriteDispChar ' l x = 13 : Gosub Display_SetCursPos ' zeichen 14 von Zeile 1 x = 68 : Gosub WriteDispChar ' D x = 101 : Gosub WriteDispChar ' e x = 119 : Gosub WriteDispChar ' w x = 64 : Gosub Display_SetCursPos ' Anfang von Zeile 2 y = defaultCoolTemp ' Define Konstante z.B. 25 °C gosub PlotTemp_NoDecimal ' 25 °C ausgeben x = 32 : Gosub WriteDispChar ' x = 32 : Gosub WriteDispChar ' x = 91 : Gosub WriteDispChar ' [ x = 79 : Gosub WriteDispChar ' O x = 75 : Gosub WriteDispChar ' K x = 93 : Gosub WriteDispChar ' ] x = 32 : Gosub WriteDispChar ' x = 32 : Gosub WriteDispChar ' x = 84 : Gosub WriteDispChar ' T x = 97 : Gosub WriteDispChar ' a pause 30 #SelectCM_Loop if BtnDown = on then goto SelectCM_NoLeftBtn ' sonst linker Button gedrückt ' abkühlen auf Standard Temperatur SollTemp = defaultCoolTemp ' konstante z.b. -25°C TempRegDelay = 80 ' Regler Reaktion auf neue Vorgabe forcieren => ' Berechnet Strom neu bei 90 also in 10 s if IsRegelMode = 1 then return IsRegelMode = 1 LastCCDTemp = CurrCCDTemp ' damit regler Ausgangsbedingung hat return #SelectCM_NoLeftBtn if BtnSelect = on then goto SelectCM_NoCenterBtn ' sonst mittlerer Button gedrückt ' zurück zum Hauptmenü return #SelectCM_NoCenterBtn if BtnUp = on then goto SelectCM_NoRightBtn ' sonst rechter Button gedrückt ' Kontrolliert auftauen auf Ta (Rampe) SollTemp = 400 ' + 40°C TempRegDelay = 80 ' Regler Reaktion auf neue Vorgabe forcieren => ' Berechnet Strom neu bei 90 also in 10 s if IsRegelMode = 1 then return IsRegelMode = 1 LastCCDTemp = CurrCCDTemp ' damit regler Ausgangsbedingung hat return #SelectCM_NoRightBtn if lastRTCSecond = Second then goto SelectCM_Loop if IsRegelMode = 1 then gosub CalcAndSetPowerForTemp ' Temp Regler 1 mal pro Sekunde aufrufen lastRTCSecond = Second ' Sekunden Wert der RTC merken goto SelectCM_Loop ' ------------------------------------------------------------------------------ ' Auswahlmenü für ' -Modus Temp Regler / Leistungssteller ' -Zugang zum Helligkeitsmenü ' ---------------- ' Mode Light ' [°C] [OK] [+/-] ' ---------------- ' Mode Light ' [P%] [OK] [+/-] ' ------------------------------------------------------------------------------ #SelectMenue Gosub Clear_LCD x = 77 : Gosub WriteDispChar ' M x = 111 : Gosub WriteDispChar ' o x = 100 : Gosub WriteDispChar ' d x = 101 : Gosub WriteDispChar ' e x = 11 : Gosub Display_SetCursPos ' zeichen 12 von Zeile 1 x = 76 : Gosub WriteDispChar ' L x = 105 : Gosub WriteDispChar ' i x = 103 : Gosub WriteDispChar ' g x = 104 : Gosub WriteDispChar ' h x = 116 : Gosub WriteDispChar ' t x = 64 : Gosub Display_SetCursPos ' Anfang von Zeile 2 x = 91 : Gosub WriteDispChar ' [ ' ------------------------------------------- ' Aktuellen Modus anzeigen if IsRegelMode = 0 then goto sm_IsFixMode #sm_IsRegelMode x = 223 : Gosub WriteDispChar ' ° x = 67 : Gosub WriteDispChar ' C goto sm_ModeSelDone #sm_IsFixMode x = 80 : Gosub WriteDispChar ' P x = 37 : Gosub WriteDispChar ' % #sm_ModeSelDone ' ------------------------------------------- x = 93 : Gosub WriteDispChar ' ] x = 32 : Gosub WriteDispChar ' x = 32 : Gosub WriteDispChar ' x = 91 : Gosub WriteDispChar ' [ x = 79 : Gosub WriteDispChar ' O x = 75 : Gosub WriteDispChar ' K x = 93 : Gosub WriteDispChar ' ] x = 32 : Gosub WriteDispChar ' x = 91 : Gosub WriteDispChar ' [ x = 43 : Gosub WriteDispChar ' + x = 47 : Gosub WriteDispChar ' / x = 45 : Gosub WriteDispChar ' - x = 93 : Gosub WriteDispChar ' ] pause 30 #SelectMenueLoop if BtnDown = on then goto NoPwrRegModeSelected ' sonst linker Button gedrückt ' Modus umgeschaltet IsRegelMode = 1 - IsRegelMode ' 0 oder 1 toggeln if IsRegelMode = 1 then LastCCDTemp = CurrCCDTemp ' damit regler Ausgangsbedingung hat goto SelectMenue ' neue auswahl anzeigen #NoPwrRegModeSelected if BtnSelect = on then goto sm_NoSelBtn ' sonst mittlerer Button gedrückt ' nächstes unter Menu aufrufen Goto SelectCoolMenue ' ACHTUNG kein gosub kehrt nicht hier her zurück return #sm_NoSelBtn if BtnUp = off then goto LightnessMenue ' rechter Button gedrückt ' ACHTUNG: kein Gosub => kehrt also nicht hier her zurück if lastRTCSecond = Second then goto SelectMenueLoop if IsRegelMode = 1 then gosub CalcAndSetPowerForTemp ' Temp Regler 1 mal pro Sekunde aufrufen lastRTCSecond = Second ' Sekunden Wert der RTC merken goto SelectMenueLoop ' ------------------------------------------------------------------------------ ' Hauptmaske Leistungs einstell Modus darstellen ' Ta +15.4°C 12.5V ' Ti -20.3°C [42%] ' ------------------------------------------------------------------------------ #PaintPwrCtrlScreen x = 0 : Gosub Display_SetCursPos ' Anfang von Zeile 1 x = 84 : Gosub WriteDispChar ' T x = 97 : Gosub WriteDispChar ' a x = 32 : Gosub WriteDispChar ' gosub read_temp_warm ' Temp nach y lesen gosub PlotTemp ' Temp von y auf LCD ausgeben x = 32 : Gosub WriteDispChar ' gosub ReadAndShowBattVoltage ' Batt Spannung Messen und anzeigen ' ------------------------------- x = 64 : Gosub Display_SetCursPos ' Anfang von Zeile 2 x = 84 : Gosub WriteDispChar ' T x = 105 : Gosub WriteDispChar ' i x = 32 : Gosub WriteDispChar ' gosub read_temp_cold ' Temp nach y lesen CurrCCDTemp = y ' kopieren für regler falls umgeschaltet wird gosub PlotTemp ' Temp von y auf LCD ausgeben x = 32 : Gosub WriteDispChar ' x = 91 : Gosub WriteDispChar '[ Gosub PlotPeltierPower ' Peltier Leistung anzeigen (Proc verändert x,y) x = 93 : Gosub WriteDispChar '] return ' ------------------------------------------------------------------------------ ' Hauptmaske Temperatur Regel Modus darstellen ' Ts [-20°C] 12.5V ' Ti -20.3°C 42% ' ------------------------------------------------------------------------------ #PaintTempCtrlScreen x = 0 : Gosub Display_SetCursPos ' Anfang von Zeile 1 x = 84 : Gosub WriteDispChar ' T x = 115 : Gosub WriteDispChar ' s x = 32 : Gosub WriteDispChar ' x = 91 : Gosub WriteDispChar ' [ y = SollTemp ' Soll Temp nach y gosub PlotTemp_NoDecimal ' Temp von y auf LCD ausgeben ohne Nachkomma Stellen x = 93 : Gosub WriteDispChar '] x = 32 : Gosub WriteDispChar ' gosub ReadAndShowBattVoltage ' Batt Spannung Messen und anzeigen ' ------------------------------- x = 64 : Gosub Display_SetCursPos ' Anfang von Zeile 2 x = 84 : Gosub WriteDispChar ' T x = 105 : Gosub WriteDispChar ' i x = 32 : Gosub WriteDispChar ' gosub read_temp_cold ' Temp nach y lesen CurrCCDTemp = y ' kopieren für regler gosub PlotTemp ' Temp von y auf LCD ausgeben x = 32 : Gosub WriteDispChar ' x = 32 : Gosub WriteDispChar ' x = 32 : Gosub WriteDispChar ' Gosub PlotPeltierPower ' Peltier Leistung anzeigen (Proc verändert x,y) return ' ------------------------------------------------------------------------------ ' ------------------------------------------------------------------------------ ' Hauptprogramm ' {mode=Regelung, soll=Ta, light=127} ' | ' __________ | __________ <---------------| ' | V V V | | ' | [Regel oder Steuer Screen] | | ' | | | | ' | <+> <-> | ' | | | ' V V | ' ------------------------------>------ ' ' ------------------------------------------------------------------------------ ' Layout Leistungs Steuerung ' ---------------- ' Ta +15.4°C 12.5V ' Ti -20.3°C [42%] ' ------------------------------------------------------------------------------ ' Layout Temp Regelung ' ---------------- ' Ts [-20°C] 12.5V ' Ti -20.3°C 42% ' ------------------------------------------------------------------------------ ' Layout Lightness Setup ' ---------------- ' Lightness 05 ' [-] [Ok] [+] ' ------------------------------------------------------------------------------ ' Layout Mode Select ' ---------------- ' Pwr. Reg. Light ' [ ] [x] [+/-] ' ------------------------------------------------------------------------------ #MainProgram ' Initialisierung des I2C-Bus I2C_scl = on I2C_sda = on LCDLightness = 8 ' LCD Helligkeit einstellen 0..8 LCDLightnessPort = 255 ' nicht direkt LCDLightness PowerPercent = 20 ' Basis Wert für 0 A Gosub setPowerPercent 'Prozent in 255 Digits umrechnen und anlegen TempRegDelay = 0 IsRegelMode = 1 pause 100 Gosub InitDisplay Gosub Clear_LCD gosub read_temp_cold ' Temp nach y lesen (Proc Verändert x,y) gosub read_temp_cold ' Temp nach y lesen (Proc Verändert x,y) CurrCCDTemp = y ' kopieren für regler LastCCDTemp = CurrCCDTemp SollTemp = CurrCCDTemp #MainLoop ' -------------------------------------------- ' Maske für Regelmode darstellen ' Ts [-20°C] 12.5V ' Ti -20.3°C 42% ' -------------------------------------------- if IsRegelMode = 1 then gosub PaintTempCtrlScreen ' -------------------------------------------- ' Maske für Leistungs stell-Modus (Steuer Modus) darstellen ' Ta +15.4°C 12.5V ' Ti -20.3°C [42%] ' -------------------------------------------- if IsRegelMode = 0 then gosub PaintPwrCtrlScreen ' -------------------------------------------- ' Warten auf Eingabe oder bis genau eine Sekunde um ist ' -------------------------------------------- #waitForOneSecondLoop x = 0 ' flag ob ChangeSollwert nötig if BtnUp = off then x = 1 ' off ist gedrückt (negative logik) ' (Proc verändert x,y, PowerPercent) if BtnDown = off then x = 1 ' ändern und neu anzeigen ' (Proc verändert x,y, PowerPercent) if x = 0 then goto noChangeSollwert Gosub ChangeSollwert TempRegDelay = 80 ' Regler Reaktion auf neue Vorgabe forcieren => ' Berechnet Strom neu bei 90 also in 10 s pause 5 goto waitForOneSecondLoop ' solagen button down nicht komplett neu zeichnen ' damit keien Verzögerung spürbar ist #noChangeSollwert if BtnSelect = on then Goto SelectBtnNotPressed gosub SelectMenue ' SelectBtn gedrückt Gosub Clear_LCD ' Reste von SelectMenue löschen lastRTCSecond = 100 ' Haupt-Menü sofort neu zeichnen pause 1 #SelectBtnNotPressed if lastRTCSecond = Second then goto waitForOneSecondLoop if IsRegelMode = 1 then gosub CalcAndSetPowerForTemp ' Temp Regler 1 mal pro Sekunde aufrufen lastRTCSecond = Second ' Sekunden Wert der RTC merken goto MainLoop ' end