home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1994 February
/
CHIP0294.ISO
/
digital
/
praxis
/
hwtip
/
laden.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1994-04-21
|
90KB
|
2,165 lines
PROGRAM NiCd_Lader;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ LADESTEUERUNG VON NI-CD-AKKUS VERSION 2.0 + Graphik │
│ PROGRAMMIERER : CARSTEN STELLING │
│ PASCAL VERSION : 6.01 │
│ MS-DOS VERSION : 6.02 │
│ LETZTE ÄNDERUNG : 15.04.1994 15:37 │
└────────────────────────────────────────────────────────────────────────┘ }
USES DOS, GRAPH, CRT, PRINTER; { Standard-Units einbinden }
LABEL START, LADEN, ENTLADEN, EINTRAG,
LEER, VOLL, DEFEKT; { Sprungmarken }
CONST
Akku_Datei : STRING [25] = 'C:\AKKULAD\EINST.NCL'; { Einstellungen }
Akku_Pdatei: STRING [25] = 'C:\AKKULAD\PORTS.NCL'; { Schnittstellen }
Mess_Datei : STRING [25] = 'C:\AKKULAD\MESS_1.NCL'; { Meßdatenerfassung }
Widst_Datei: STRING [25] = 'C:\AKKULAD\SETUP.NCL'; { Widerstandswerte }
Grfk_Pfad : STRING [30] = 'C:\AKKULAD'; { BGI-Grafiktreiber-Suchpfad }
Ref : REAL = 5.0; { Wert der Referenzspannung }
TYPE Akku_rec = RECORD { Akku - Daten }
Kap : REAL; { Nennkapazität }
Spg : REAL; { Nennspannung }
Algor : BYTE; { Ladealgorithmus }
Laden : BOOLEAN; { Status Laden }
Entladen : BOOLEAN; { Status Entladen }
Defekt : BOOLEAN; { Status Defekt }
Online : BOOLEAN; { Akku im Ladeprozeß }
V_Summe : REAL; { Spannungssumme }
V_Mittel : REAL; { Mittelwert der Spannung }
V_Vorher : REAL; { Vorheriger Wert der Spannung }
Proben : LONGINT; { Anzahl der Meßproben/Minute }
Zyklus : BYTE; { Anzahl der Lade-/Entladezyklen }
END;
Akku_str = STRING [8]; { String für Dateizuweisungen }
Akku_arr = ARRAY [1..4] OF Akku_rec; { Array der Akku-Daten }
Messen = ARRAY [1..4] OF REAL; { Array der Messwerte }
Wid = ARRAY [1..4] OF REAL; { Array der Widerstandswerte aus SETUP }
VAR Regs : REGISTERS; { DOS Registertypen }
Akku : Akku_arr; { Akku - Speichervariablen }
Akku_Dat : FILE OF Akku_str; { Speichert Akku-Informationen }
Akku_Port : FILE OF Akku_str; { Speichert eingest. Ports }
Akku_Wid : FILE OF Wid; { Liest Widerstandswerte }
Mess_Daten : FILE OF Messen; { Speichert Meßdaten }
Messwert : Messen; { String für Meßwertumwandlung }
R : Wid; { Widerstandswerte 1..4 }
Pruef : REAL; { Ablagevar. für 1. Wandlung }
Mess1 : ARRAY [1..4] OF REAL; { Zwischenspeicher für Messwert Hi-Pot. }
Mess2 : ARRAY [1..4] OF REAL; { Zwischenspeicher für Messwert Lo-Pot. }
Portadr : WORD; { COM1, COM2 Portadresse }
Akku_Nr : BYTE; { Akkunummer 1..4 }
Zaehler : BYTE; { Umlaufzaehler während des Ladens }
Z : BYTE; { Zaehler Hilfsvariable }
Taste : CHAR; { für Tastendruck }
Maust : WORD; { Maustasten-Status }
Mausx : WORD; { Maus X-Position }
Mausy : WORD; { Maus Y-Position }
Exit_Adr: POINTER; { Programmabbruchadresse }
Bed_Abr : BOOLEAN; { Bediener-Abbruch }
Drucken : BOOLEAN; { Protokoll Drucken }
Dr_OK : BOOLEAN; { Druck Fehlerhaft }
Zoom : BYTE; { Zeitauflösung fein=2, grob=1 }
CurAnf : BYTE; { Cursorposition }
CurEnd : BYTE;
AD_Init_Err : BOOLEAN; { Initialisierungsfehler A/D-Wandler }
std, min, sek, s100 : WORD; { akt. Uhrzeit }
stdalt, minalt, sekalt, s100alt : WORD; { alte Uhrzeit }
jahr, mon, tag, wtag : WORD; { Datum }
AdrLPT : WORD; { nimmt aktive LPT-Adresse auf }
{ zeigen auf BIOS-Kommunikationsbereich }
AdrLPT1 : WORD ABSOLUTE $40:$08; { Adr. der 1. parallelen Schnittstelle }
AdrLPT2 : WORD ABSOLUTE $40:$0A; { Adr. der 2. parallelen Schn. }
AdrLPT3 : WORD ABSOLUTE $40:$0F; { Adr. der 3. parallelen Schn. }
AdrCOM1 : WORD ABSOLUTE $40:$00; { Adr. der 1. seriellen Schn. }
AdrCOM2 : WORD ABSOLUTE $40:$02; { Adr. der 2. seriellen Schn. }
AdrCOM3 : WORD ABSOLUTE $40:$04; { Adr. der 3. seriellen Schn. }
AdrCOM4 : WORD ABSOLUTE $40:$06; { Adr. der 4. seriellen Schn. }
Ser : Akku_str; { serielle Schnittstelle }
Par : Akku_str; { parallele Schnittstelle }
{ ┌────────────────────────────────────────────────────────────────────────┐
│ CURSORPOSITION UND ERSCHEINUNGSBILD ERMITTELN │
│ EINGABEN : KEINE │
│ AUSGABE : CURSORPOSITION │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE CursorErmitteln;
BEGIN
Regs.AH := $0F; { Auslesen des Video-Modus }
INTR ($10, Regs); { AL = Video-Modus-Kennung }
{ AH = Anzahl der Zeichen / Zeile }
{ BH = Nr. der Bildschirmseite }
Regs.AH := $03; { Auslesen der Cursor Position }
INTR ($10, Regs); { Eing. BH = Nr. der Bildschirmseite }
CurAnf := Regs.CH;
CurEnd := Regs.CL;
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ CURSOR AUSSCHALTEN │
│ EINGABEN : KEINE │
│ AUSGABE : CURSOR UNSICHTBAR │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE CursorAus;
BEGIN
Regs.AH := $01; { Erscheinungsbild des Cursors }
Regs.CH := $20; { Außerhalb der Startzeile pos. }
Regs.CL := $00; { Endzeile 0 }
INTR ($10, Regs);
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ CURSOR EINSCHALTEN │
│ EINGABEN : KEINE │
│ AUSGABE : CURSOR SICHTBAR │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE CursorEin;
BEGIN
Regs.AH := $01; { Erscheinungsbild }
Regs.CH := CurAnf; { Startzeile = alter Wert }
Regs.CL := CurEnd; { Endzeile = alter Wert }
INTR ($10, Regs);
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ UMWANDELN EINER 16-BIT-DEZIMALZAHL IN EINE HEXADEZIMALE ZAHL │
│ EINGABEN : DEZIMALZAHL, ANZAHL DER AUSGABESTELLEN │
│ AUSGABE : HEXADEZIMALZAHL │
└────────────────────────────────────────────────────────────────────────┘ }
FUNCTION HexZahl (DezZahl : WORD; Stellen: BYTE):STRING;
VAR Wandeln : BYTE; { Variablendeklaration }
Zeichen : STRING [1];
Zeichenkette : STRING [5];
Puffer : STRING [5];
PROCEDURE Eintragen (Ganzzahl : WORD); { Zeichen in den String eintragen }
VAR Asciinr : BYTE; { ASCII-Nr. des Zeichens }
BEGIN
IF Ganzzahl > 9 THEN Asciinr := Ganzzahl + 55 { ASCII-Nr. für Zahlen }
ELSE Asciinr := Ganzzahl + 48; { ASCII-Nr. für Buchstaben }
Zeichenkette := Zeichenkette + CHR (Asciinr);
END;
BEGIN
Zeichenkette := ''; { Zeichenkette löschen }
FOR Wandeln := 1 TO Stellen DO { x Stellen umwandeln }
BEGIN
Eintragen (DezZahl MOD 16); { Rest der Division eintragen }
DezZahl := DezZahl DIV 16; { ganzzahliger Anteil wird gespeichert }
END;
Puffer := '$'; { $-Zeichen vorweg }
FOR Wandeln := 1 TO Stellen DO { x Stellen umwandeln }
BEGIN
Zeichen := COPY (Zeichenkette, Stellen + 1 - Wandeln, 1);
Puffer := Puffer + Zeichen; { Zeichenkette herstellen }
END;
HexZahl := Puffer; { Zuweisung }
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ FORMATIERTE ZEITAUSGABE │
│ EINGABEN : STUNDEN, MINUTEN ODER SEKUNDEN │
│ AUSGABEN : ZWEISTELLIGE AUSGABE OHNE UNTERDRÜCKUNG VON F. NULLEN │
└────────────────────────────────────────────────────────────────────────┘ }
FUNCTION TFormat (Zeit : WORD) :STRING;
VAR Zehner : CHAR; { Variablendeklaration }
Einer : CHAR;
BEGIN;
Zehner := CHR (Zeit DIV 10 + 48); { ASCII-Zeichen der Zehner-Stelle }
Einer := CHR (Zeit MOD 10 + 48); { ASCII-Zeichen der Einer-Stelle }
TFormat := Zehner + Einer; { FORMAT = Zehner + Einer }
END;
{┌────────────────────────────────────────────────────────────────────────┐
│ FENSTER FÜR FEHLERAUSGABE, WARNUNG │
│ EINGABEN : KEINE │
│ AUSGABEN : OFFNET EIN NEUES FENSTER │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE Fehler_Fenster;
BEGIN
WINDOW (17, 10, 66, 16);
TEXTBACKGROUND (12);
TEXTCOLOR (15);
CLRSCR;
WRITELN ('╔═════ WARNUNG ═════════════════════════════════╗');
WRITELN ('║ ║');
WRITELN ('║ ║');
WRITELN ('║ ║');
WRITELN ('║ ║');
WRITELN ('║ ║');
WRITE ('╚═══════════════════════════════════════════════╝');
SOUND (1200);
DELAY (100);
NOSOUND;
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ WIDERSTANDSWERTE AUS DATEI SETUP ERMITTELN │
│ EINGABEN : KEINE │
│ AUSGABEN : KEINE │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE Wid_Werte;
VAR OK : BOOLEAN;
BEGIN
ASSIGN (Akku_Wid, Widst_Datei);
{$I-}
RESET (Akku_Wid);
{$I-}
OK := IORESULT=0;
IF NOT OK THEN
BEGIN
Fehler_Fenster;
GOTOXY (3, 3);
WRITE ('Datei ',Widst_Datei, ' nicht gefunden.');
GOTOXY (3, 4);
WRITE ('Starten Sie das Programm SETUP.EXE !');
GOTOXY (3, 6);
WRITE ('Taste zum Ausführen drücken. >');
REPEAT UNTIL KEYPRESSED;
Taste := READKEY;
WINDOW (1, 1, 80, 25);
TEXTBACKGROUND (0);
CLRSCR;
TEXTCOLOR (7);
WRITELN ('Programm beendet.');
WRITELN ('Starten Sie SETUP.EXE !');
HALT;
END;
READ (Akku_Wid, R);
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ MAUSTREIBER INITIALISIEREN │
│ EINGABEN : AX-REGISTER │
│ AUSGABEN : DOS INTERRUPT $33 FUNKT. 0 ERGEBNIS IN AX │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE Mausinit;
BEGIN
Regs.ax := 0; { Funktionsnummer in AX }
INTR ($33, Regs); { DOS-Interrupt nr. 33h }
IF Regs.ax = 0 THEN { Rückmeldung in AX }
BEGIN { wenn 0 - Fehlermeldung }
Fehler_Fenster;
GOTOXY (3, 3);
WRITE ('Maustreiber konnte nicht initialisiert werden.');
GOTOXY (3, 4);
WRITE ('Falscher oder fehlender Maustreiber.');
GOTOXY (3, 6);
WRITE ('Taste zum Quittieren betätigen. >');
REPEAT UNTIL KEYPRESSED;
Taste := READKEY;
END;
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ MAUSCURSOR IM TEXTMODUS AN/AUS-SCHALTEN │
│ EINGABEN : AX-REGISTER (1=AN, 2=AUS) │
│ AUSGABEN : MAUSCURSOR SICHTBAR/UNSICHTBAR │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE Mausein (Schalter : BYTE);
BEGIN
Schalter := 2 - Schalter; { Normierung auf 0 / 1 }
IF Schalter > 2 THEN Schalter := 2; { Sicherheit }
IF Schalter < 1 THEN Schalter := 1;
Regs.ax := Schalter; { AX=2 - Cursor aus }
{ AX=1 - Cursor an }
INTR ($33, Regs); { DOS-Interrupt Nr. 33h }
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ MAUSSTATUS VIA DOS INERRUPT $33 FUNKTION 3 │
│ EINGABEN : KEINE │
│ AUSGABEN : X-, Y-KOORDINATEN, TASTENSTATUS │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE Mausstatus;
BEGIN
Regs.ax := 3; { Funktion 3 }
INTR ($33, Regs); { DOS-Interrupt Nr. 33h }
Maust := Regs.bx; { Status der Maustasten }
Mausx := Regs.cx; { Maus X-Position }
Mausy := Regs.dx; { Maus Y-Position }
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ MAUSBEWEGUNGSBEREICH FESTLEGEN VIA DOS INERRUPT $33 FUNKTION 7, 8 │
│ EINGABEN : X1, Y1, X2, Y2 │
│ AUSGABEN : BEWEGUNGSBEREICH DES MAUSCURSORS │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE Mausbereich (X1, Y1, X2, Y2 : WORD);
BEGIN
Regs.AX := 7;
Regs.CX := X1;
Regs.DX := X2;
INTR ($33, Regs);
Regs.AX := 8;
Regs.CX := Y1;
Regs.DX := Y2;
INTR ($33, Regs);
END;
{┌────────────────────────────────────────────────────────────────────────┐
│ AUF TASTENDRUCK ODER MAUSTASTE WARTEN │
│ EINGABEN : TASTATUR, MAUS │
│ AUSGABE : KEINE │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE Warten;
VAR Taste : CHAR;
BEGIN
Mausein (1);
REPEAT;
Mausstatus;
UNTIL (KEYPRESSED) OR (Maust <> 0);
IF KEYPRESSED THEN
BEGIN
Taste := READKEY;
Taste := ' ';
END;
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ TAKTUNABHÄNGIGE WARTESCHLEIFE FÜR MIKROSEKUNDEN │
│ EINGABEN : VERZÖGERUNGSZEIT IN µs │
│ AUSGABEN : PROGRAMMUNTERBRECHUNG │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE Microdelay (del : LONGINT); { Taktunabhängige Verzögerung }
VAR T8, T8s : LONGINT; { Hilfsvariablen }
lb1, hb1, lb2, hb2 : BYTE; { Lobyte, Hibyte des PIT }
BEGIN
IF del > 50000000 THEN DELAY ((del + 500) div 1000)
ELSE
BEGIN
T8 := 0;
T8s := (del * 16) div 27; { 16 /27 /4 * 6.704 = 0.993 }
PORT [$43]:= 0; { Lese Timer }
lb1 := port [$40]; { Lese Lowbyte }
hb1 := port [$40]; { Lese Highbyte }
REPEAT; { Je Durchgang 6.704 us }
INC (T8 ,4);
REPEAT;
PORT [$43] := 0;
lb2 := PORT [$40];
hb2 := PORT [$40];
UNTIL (( WORD (lb1) + WORD (hb1) SHL 8) AND $FFFC) <>
(( WORD (lb2) + WORD (hb2) SHL 8) AND $FFFC);
{ Änderung der letzten 2 Bits = 3.352 us }
REPEAT
PORT [$43] := 0;
lb1 := PORT [$40];
hb1 := PORT [$40];
UNTIL (( WORD (lb1) + WORD (hb1) SHL 8) AND $FFFC) <>
(( WORD (lb2) + WORD (hb2) SHL 8) AND $FFFC);
{ Änderung der letzten 2 Bits = 3.352 us }
UNTIL T8 >= T8s;
END;
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ ANALOGMESSWERTKARTE PROGRAMMIEREN UND SIGNALE AUSWERTEN │
│ EINGABEN : SCHNITTSTELLENNUMMER │
│ AUSGABEN : SPANNUNG DER 8 MESSKANÄLE IM BEREICH 0V BIS 5V │
└────────────────────────────────────────────────────────────────────────┘ }
FUNCTION AD_Messwert (Kanal : BYTE) : REAL; { Aufruf mit Kanalnummer 1 bis 8 }
{ Kontrollsequenzen für LT1090 }
CONST Auswahl : ARRAY [1..8] OF WORD = ($F71+0, $F71+2, $F71+8, $F71+$A, $F71+4, $F71+6, $F71+$C, $F71+$E);
VAR Control : WORD; { Kontroll-Register }
pout : WORD; { COM Modemkontrollregister-Adresse }
pin : WORD; { COM Modemstatusregister-Adresse }
Z : BYTE; { Schleifenzähler }
skal : INTEGER; { Skalierung }
BEGIN { Ansteuerung des A/D Wandlers Conrad Best.-Nr. 97 97 67 }
pout := Portadr + 4; { MCR = COM Basisadresse + 4 }
pin := Portadr + 6; { MSR = COM Basisadresse + 6 }
Control := Auswahl [Kanal]; { Kontrollregister laden }
PORT [pout] := PORT [pout] AND $FD OR $01;
Microdelay (5);
PORT [pout] := PORT [pout] OR $02;
FOR Z := 1 TO 12 DO { 12 Bit an A/D-Wandler }
BEGIN
Microdelay (5);
PORT [pout] := $FE AND PORT [pout];
Microdelay (5);
PORT [pout] := PORT [pout] OR $02;
IF NOT ODD (Control) THEN
BEGIN
Microdelay (5);
PORT [pout] := port [pout] AND $FD;
END;
Microdelay (5);
PORT [pout] := PORT [pout] OR $01;
Control:= Control SHR 1;
END;
Microdelay (5);
PORT [pout] := PORT [pout] AND $FD OR $01;
Microdelay (5);
PORT [pout] := PORT [pout] OR $02;
Microdelay (250);
skal:=0;
Control := Auswahl [Kanal];
FOR z:= 1 TO 12 DO { 12 Bits lesen und skalieren }
BEGIN
Microdelay (5);
PORT [pout] := $FE AND PORT [pout];
Microdelay (5);
PORT [pout] := PORT [pout] OR $02;
Microdelay (5);
PORT [pout] := PORT [pout] OR $01;
IF z < 11 THEN
BEGIN
skal := skal SHL 1;
Microdelay (5);
IF NOT (( PORT [pin] AND $10) = $10) THEN INC (skal);
END;
Control := Control SHR 1;
END;
AD_Messwert := skal / 1023.0 * ref; { Umrechnen auf Volt }
END; { Ende der Funktion }
{ ┌────────────────────────────────────────────────────────────────────────┐
│ ANALOGMESSWERTKARTE INITIALISIEREN UND PRÜFEN │
│ EINGABEN : ADRESSE COM X │
│ AUSGABEN : FEHLERMELDUNG WENN MESSWERT 5V │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE AD_Wandler_Init;
VAR Antw : CHAR;
BEGIN
Pruef := AD_Messwert (2); { 1. Messung ist falsch }
DELAY (50); { 50 ms warten }
Pruef := AD_Messwert (1); { 2. Messung ist auswertbar }
IF Pruef = 5.0 THEN { wahrscheinlich falscher Port }
BEGIN
Fehler_Fenster;
GOTOXY (3, 2);
WRITE ('AD-Wandlerkarte an Port: ',ser,' nicht entdeckt!');
GOTOXY (3, 3);
WRITE ('Prüfen Sie die "GRUNDEINSTELLUNGEN"');
GOTOXY (3, 4);
WRITE ('oder die A/D-Wandlerkarte am seriellen Port.');
GOTOXY (3, 6);
WRITE ('Zurück zum Hauptmenü mit Tastendruck. >');
REPEAT UNTIL KEYPRESSED;
Antw := READKEY;
Antw := ' ';
AD_Init_err := TRUE;
END;
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ LADETRANSISTOR DUCHSTEUERN │
│ EINGABEN : LADEPLATZ-NUMMER │
│ AUSGABE : SETZT BIT 1 (3, 5, 7) AM PARALLELPORT AUF "1" │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE Laden_ein (Platz : BYTE);
BEGIN
PORT [AdrLPT] := PORT [AdrLPT] OR 1 SHL ((Platz - 1 ) * 2);
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ LADETRANSISTOR SPERREN │
│ EINGABEN : LADEPLATZ-NUMMER │
│ AUSGABE : SETZT BIT 1 (3, 5, 7) AM PARALLELPORT AUF "0" │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE Laden_aus (Platz : BYTE);
BEGIN
PORT [AdrLPT] := PORT [AdrLPT] AND NOT 1 SHL ((Platz - 1) * 2);
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ ENTLADE-MOSFET DURCHSTEUERN │
│ EINGABEN : LADEPLATZ-NUMMER │
│ AUSGABE : SETZT BIT 0 (2, 4, 6) AM PARALLELPORT AUF "1" │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE Entladen_ein (Platz : BYTE);
BEGIN
PORT [AdrLPT] := PORT [AdrLPT] OR 2 SHL ((Platz - 1) * 2);
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ ENTLADE-MOSFET SPERREN │
│ EINGABEN : LADEPLATZ-NUMMER │
│ AUSGABE : SETZT BIT 0 (2, 4, 6) AM PARALLELPORT AUF "0" │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE Entladen_aus (Platz : BYTE);
BEGIN
PORT [AdrLPT] := PORT [AdrLPT] AND NOT 2 SHL ((Platz - 1) * 2);
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ GITTERNETZLINIEN ZEICHNEN │
│ EINGABEN : LADEPLATZ-NUMMER │
│ AUSGABE : LADEKURVE IN EIN KOORDINATENSYSTEM SCHREIBEN │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE Gitternetz;
VAR X, Y : WORD; { Zeichenkoordinaten }
BEGIN
SETCOLOR (8); { Farbe grau }
SETLINESTYLE (DOTTEDLN, 0, 1); { Punktierte Linie }
X := 70; { Startwert }
REPEAT
LINE (X, 400, X, 60); { Linie zeichnen }
INC (X, 20); { X-Position erhöhen }
UNTIL X > 600; { bis 600 überschritten }
Y := 80; { Prozedur mit Y wiederholen }
REPEAT
LINE (50, Y, 600, Y);
INC (Y, 20);
UNTIL Y > 380;
SETLINESTYLE (SOLIDLN, 0, 1); { Durchgezogene Linie, dünn }
SETCOLOR (4); { Farbe rot }
LINE (50 ,240 ,595 ,240); { 1.2V-Bezugslinie zeichnen }
SETLINESTYLE (SOLIDLN, 0, 2); { normale Linienstärke }
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ PLOTTEN DER LADEKURVEN │
│ EINGABEN : X1, Y1, OFFSET, LÖSCHEN │
│ AUSGABE : 4 LADEKURVEN IN DAS KOORDINATENSYSTEM SCHREIBEN │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE Plotten (Offs : LONGINT; Clr : BOOLEAN; Anf_std : WORD; Anf_min : WORD);
LABEL PLOT_ENDE;
VAR X1 : WORD; { X-Koordinaten }
X2 : WORD; { X1=Anfang, X2=Ende }
Y1 : ARRAY [1..4] OF WORD; { Y-Koordinaten }
Y2 : ARRAY [1..4] OF WORD; { Y1=Anfang, Y2=Ende }
Ze : ARRAY [1..4] OF BOOLEAN; { Zeichnen erlaubt }
End_std : WORD; { Zeit Ende }
Dummy : WORD; { Hilfsvar. für 24 Std. }
Puffer : STRING;
D_Zeiger : WORD; { Datei-Zeigervariable }
Z : BYTE; { Zählvariable }
Err : INTEGER; { Fehler }
OK : BOOLEAN; { IO-RESULT Var. }
BEGIN
X1 := 52; { Start bei X-Pos. 52 }
X2 := X1 + Zoom;
D_Zeiger := 6; { Element 0 = Datum }
{ Element 1 = Zeit }
{ Element 2 = Kapazität }
{ Element 3 = Spannung }
{ Element 4 = Algorithmus }
{ Element 5 = 1. Messwert }
Anf_std := Anf_Std + (Offs DIV 60);
Dummy := Anf_Std DIV 24;
DEC (Anf_std, Dummy * 24);
Puffer := TFormat (Anf_std) + ':' + TFormat (Anf_min);
IF Clr = TRUE THEN SETCOLOR (0) ELSE SETCOLOR (9);
OUTTEXTXY (30, 410, Puffer);
FOR Z := 1 TO 4 DO
BEGIN
End_std := Anf_std + (Z * Zoom);
Dummy := End_Std DIV 24;
DEC (End_Std, Dummy * 24);
Puffer := TFormat (End_std) + ':' + Tformat (Anf_min);
IF CLR = TRUE THEN SETCOLOR (0) ELSE SETCOLOR (9);
OUTTEXTXY (30 + 120 * Z, 410, Puffer);
END;
FOR Z := 1 TO 4 DO { Initialisieren }
BEGIN
Ze [Z] := TRUE;
END;
RESET (Mess_Daten); { Zeiger auf Anfang }
SEEK (Mess_Daten, D_Zeiger + Offs); { neues Element suchen }
REPEAT;
D_Zeiger := FILEPOS (Mess_Daten); { Elementnummer ermitteln }
DEC (D_Zeiger, 1); { eine Elementnummer zurück }
SEEK (Mess_Daten, D_Zeiger); { neues Element suchen }
{$I-}
READ (Mess_Daten, Messwert); { Messwerte einlesen }
{$I+}
OK := IORESULT=0;
IF (NOT OK) OR (EOF (Mess_Daten)) THEN GOTO PLOT_ENDE;
FOR Z := 1 TO 4 DO
BEGIN
IF Messwert [Z] >= 777 THEN Ze [Z] := FALSE;
END;
FOR Z := 1 TO 4 DO { Ursprung der Linie berechnen }
BEGIN
IF (Messwert [Z] < 0) THEN Messwert [Z] := 0;
Y1 [Z] := TRUNC ((1.2 - Messwert [Z]) * 400 + 240);
IF Y1 [Z] > 400 THEN Y1 [Z] := 398;
IF Y1 [Z] < 60 THEN Y1 [Z] := 60;
END;
{$I-}
READ (Mess_Daten, Messwert); { neue Messwerte lesen }
{$I+}
OK := IORESULT=0;
IF (NOT OK) OR (EOF (Mess_Daten)) THEN GOTO PLOT_ENDE;
FOR Z := 1 TO 4 DO { Prüfen ob Linie sichtbar sein soll }
BEGIN
IF Messwert [Z] >= 777 THEN Ze [Z] := FALSE;
END;
FOR Z := 1 TO 4 DO { Ziel der Linie berechnen }
BEGIN
IF Z = 1 THEN SETCOLOR (10); { 1. Durchlauf in hellgrün }
IF Z = 2 THEN SETCOLOR (13); { 2. Durcklauf in magenta }
IF Z = 3 THEN SETCOLOR (7); { 3. Durchlauf in grau }
IF Z = 4 THEN SETCOLOR (1); { 4. Durchlauf in blau }
IF Clr = TRUE THEN SETCOLOR (0); { Löschmodus in schwarz }
IF (Messwert [Z] < 0) THEN Messwert [Z] := 0; { Zielpunkt berechnen }
Y2 [Z] := TRUNC ((1.2 - Messwert [Z]) * 400 + 240);
IF Y2 [Z] > 400 THEN Y2 [Z] := 398;
IF Y2 [Z] < 60 THEN Y2 [Z] := 60;
IF Ze [Z] = TRUE THEN LINE (X1, Y1 [Z], X2, Y2 [Z]); { Linie ziehen }
END;
INC (X1 , 3 - Zoom); { nächste Schreibposition }
INC (X2 , 3 - Zoom);
UNTIL (EOF (Mess_Daten)) OR (X1 > 590);
PLOT_ENDE:
OK := TRUE;
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ GRAPHISCHE AUSWERTUNG DES LADEVORGANGES │
│ EINGABEN : LADEPLATZ-NUMMER │
│ AUSGABE : LADEKURVE IN EIN KOORDINATENSYSTEM SCHREIBEN │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE Auswertung;
LABEL ENDE;
VAR
Puffer : STRING; { Zeichenpuffer }
jahrstr : STRING [4];
GraphDriver : INTEGER; { Grafik-Treiber }
GraphMode : INTEGER; { Grafik-Modus }
Err : INTEGER; { Grafik-Fehlerspeicher }
X1, Y1 : WORD; { Zeichenkoordinaten }
W : REAL; { REAL-Messwert }
Zeiger : LONGINT; { Dateizeiger }
Offs : LONGINT; { Dateizeiger Offset }
Antw : CHAR; { Tastaturabfrage }
OK : BOOLEAN; { IO-Result Variable }
Clr : BOOLEAN; { Löschmodus }
Anf_std : WORD; { Zeitbeschriftung der X-Achse, Stunden }
Anf_min : WORD; { Minuten }
X_POS : WORD; { Mauscursorposition X-Achse }
Spng : REAL; { Spannung am Punkt des Mauscursors }
Spng_Str : STRING [8]; { Spannung Ausgabestring }
Y_POS : WORD; { Mauscursorposition Y-Achse }
Y_POS_Real : REAL; { Position Y als Real-Typ }
Zeit : WORD; { Zeit in Min. am Pukt des Mausc. }
Zeit_Str : STRING [9]; { Zeit Ausgabestring }
BEGIN
Mausein (0);
GraphDriver := DETECT; { Grafiktreiber suchen }
INITGRAPH (GraphDriver, GraphMode, Grfk_Pfad); { Treiber initialisieren }
Err := GRAPHRESULT; { Status holen }
IF Err <> 0 THEN { Wenn initialisierung fehlerhaft }
BEGIN { dann Fehlermeldung }
Fehler_fenster;
GOTOXY (3, 3);
WRITE ('SYSTEMFEHLER:');
GOTOXY (3, 4);
WRITE (GraphErrorMsg (Err));
GOTOXY (3, 6);
WRITE ('Zurück zum Hauptmenü mit Tastendruck. >');
REPEAT UNTIL KEYPRESSED;
Antw := READKEY;
Antw := ' ';
EXIT;
END;
SETACTIVEPAGE (0); { aktive Schreibseite }
SETVISUALPAGE (0); { aktive Leseseite }
SETBKCOLOR (0); { Hintergrundfarbe }
CLEARVIEWPORT; { Bildschirm löschen }
SETCOLOR (14); { Schreibfarbe gelb }
SETLINESTYLE (SOLIDLN, 0, 4); { Rahmen }
SETCOLOR (15);
LINE (1, 1, 636, 1);
LINE (636, 1, 636, 455);
LINE (636, 455, 1, 455);
LINE (1, 455, 1, 1);
Zeiger := 0; { Dateizeiger }
REPEAT
SEEK (Mess_Daten, Zeiger); { Dateizeiger an den Anfang }
IF EOF (Mess_Daten) THEN { wenn Dateiende dann }
BEGIN { ist Datei leer }
CLOSEGRAPH;
Fehler_Fenster;
GOTOXY (3, 3);
WRITE ('GRAPHIKAUSWERTUNG:');
GOTOXY (3, 4);
WRITE ('Datei ist leer !');
GOTOXY (3, 6);
WRITE ('Zurück zum Hauptmenü mit Tastendruck. >');
REPEAT UNTIL KEYPRESSED;
Antw := READKEY;
Antw := ' ';
EXIT;
END;
READ (Mess_Daten, Messwert); { Dateinende suchen }
INC (Zeiger, 1); { Zeiger zeigt auf letzten Eintrag }
UNTIL EOF (Mess_Daten);
RESET (Mess_Daten); { Datum des Ladevorganges }
READ (Mess_Daten, Messwert);
wtag := TRUNC (Messwert [1]);
tag := TRUNC (Messwert [2]);
mon := TRUNC (Messwert [3]);
jahr := TRUNC (Messwert [4]);
STR (jahr, jahrstr);
READ (Mess_Daten, Messwert); { Beginn der Ladung um: }
std := TRUNC (Messwert [1]);
Anf_std := std;
min := TRUNC (Messwert [2]);
Anf_min := min;
sek := TRUNC (Messwert [3]);
s100 := TRUNC (Messwert [4]);
Puffer := ' Datum ' + TFormat (tag) + '.' + TFormat (mon) + '.' + jahrstr + ', Start: '+
TFormat (std) + ':' + TFormat (min) + ':' + TFormat (sek) + ' Uhr.';
SETCOLOR (12);
OUTTEXTXY (1, 10, ' Graphische Auswertung des Ladevorganges von:');
SETCOLOR (7);
OUTTEXTXY (1, 25, Puffer);
SETLINESTYLE (SOLIDLN, 0, 4); { Textausgaben }
SETCOLOR (10);
LINE (380, 14, 390, 14);
Puffer := 'Kanal 1';
OUTTEXTXY (395, 10, Puffer);
SETCOLOR (13);
LINE (380, 24, 390, 24);
Puffer := 'Kanal 2';
OUTTEXTXY (395, 20, Puffer);
SETCOLOR (7);
LINE (500, 14, 510, 14);
Puffer := 'Kanal 3';
OUTTEXTXY (515, 10, Puffer);
SETCOLOR (1);
LINE (500, 24, 510, 24);
Puffer := 'Kanal 4';
OUTTEXTXY (515, 20, Puffer);
Puffer := '';
SEEK (Mess_Daten, Zeiger - 1); { Ende der Ladezeit ermitteln }
READ (Mess_Daten, Messwert);
std := TRUNC (Messwert [1]);
min := TRUNC (Messwert [2]);
sek := TRUNC (Messwert [3]);
s100 := TRUNC (Messwert [4]);
Puffer := ' Ende : '+ TFormat (std) + ':' + TFormat (min) + ':' + TFormat (sek) + ' Uhr.';
SETCOLOR (7);
OUTTEXTXY (1, 35, Puffer);
Puffer := ' MESSWERTDATEI: '+ Mess_Datei;
OUTTEXTXY (1,430, Puffer);
SETCOLOR (15);
SETLINESTYLE (SOLIDLN, 0, 2); { Koordinatensystem zeichnen }
LINE (50, 60, 50, 400);
LINE (50, 400, 600, 400);
LINE (50, 60, 48, 68);
LINE (50, 60, 52, 68);
LINE (600, 400, 592, 398);
LINE (600, 400, 592, 402);
Y1 := 380; { Skalierung Y-Achse }
REPEAT
LINE (45, Y1, 50, Y1);
DEC (Y1, 20);
UNTIL Y1 < 80;
X1 := 50; { Skalierung X-Achse }
REPEAT
LINE (X1, 400, X1, 405);
INC (X1, 20);
UNTIL X1 > 580;
OUTTEXTXY (8, 45, 'Volt/Zelle'); { Beschriftungen }
OUTTEXTXY (8, 55, 'U (V)');
OUTTEXTXY (610, 408, 't');
OUTTEXTXY (500, 50, '+/- SCHIEBEN');
SETCOLOR (10);
OUTTEXTXY (1, 440, ' NI-CD-Akkulader V 2.0 (c) Carsten Stelling 1994');
SETCOLOR (15);
IF Zoom = 1 THEN OUTTEXTXY (500, 430, '1TE = 10min.');
IF Zoom = 2 THEN OUTTEXTXY (500, 430, '1TE = 20min.');
OUTTEXTXY (10, 75, '1,60'); { Beschriftung Y-Achse }
OUTTEXTXY (10, 95, '1,55');
OUTTEXTXY (10, 115, '1,50');
OUTTEXTXY (10, 135, '1,45');
OUTTEXTXY (10, 155, '1,40');
OUTTEXTXY (10, 175, '1,35');
OUTTEXTXY (10, 195, '1,30');
OUTTEXTXY (10, 215, '1,25');
OUTTEXTXY (10, 235, '1,20');
OUTTEXTXY (10, 255, '1,15');
OUTTEXTXY (10, 275, '1,10');
OUTTEXTXY (10, 295, '1,05');
OUTTEXTXY (10, 315, '1.00');
OUTTEXTXY (10, 335, '0,95');
OUTTEXTXY (10, 355, '0,90');
OUTTEXTXY (10, 375, '0,85');
OUTTEXTXY (10, 395, '0,80');
SETCOLOR (4);
OUTTEXTXY (600, 236, '1,2V');
Offs := 0; { Initialisierung }
Clr := FALSE;
Mausbereich (50, 55, 590, 400); { Mausbewegungsbereich im Grafikmodus }
REPEAT; { Schleife }
Gitternetz; { Gitternetz zeichnen }
Plotten (Offs, Clr, Anf_std, Anf_min); { Lade-/Entladekurven plotten }
Mausein (1); { Grafik-Mauscursor einschalten }
REPEAT;
Mausstatus; { Mausstatus holen }
IF Maust = 2 THEN GOTO ENDE; { linke Maustaste = Ende }
IF Mausx <> X_POS THEN { Wurde X-Pos. seit letztem Aufruf verändert? }
BEGIN { wenn ja, dann aktualisieren. }
SETCOLOR (0); { Farbe schwarz auf schwarz }
OUTTEXTXY (200, 60, '███████████'); { alten Wert löschen }
X_POS := Mausx; { X-Pos. aktualisieren }
IF Zoom = 1 THEN Zeit := TRUNC ((X_POS - 42) / 2 + Offs - 4);
IF Zoom = 2 THEN Zeit := TRUNC (((X_POS - 46) * Zoom) / 2 + Offs - 4) ; { Zeit in min. berechnen }
STR (Zeit, Zeit_Str); { Umwandeln in Stringformat }
Zeit_Str := Zeit_Str + ' min.'; { String erweitern }
SETCOLOR (9); { Farbe hellblau }
OUTTEXTXY (200, 60, Zeit_Str); { Textausgabe }
END;
IF Mausy <> Y_POS THEN { Wurde Y-Pos. seit letztem Aufruf verändert? }
BEGIN { wenn ja, dann aktualisieren. }
SETCOLOR (0); { Farbe schwarz auf schwarz }
OUTTEXTXY (320, 60, '███████████'); { alten Wert löschen }
Y_POS := Mausy; { Y-Pos. aktualisieren }
Y_POS_Real := Mausy; { Word-Typ in Real-Typ wandeln }
Spng := 1.2 - ((Y_POS_Real - 240) / 400); { Spannungswert berechnen }
STR (Spng:6:3, Spng_Str); { Umwandeln in Stringformat }
Spng_Str := Spng_Str + ' V.'; { String erweitern }
SETCOLOR (15); { Farbe weiß }
OUTTEXTXY (320, 60, Spng_Str); { Textausgabe }
END;
UNTIL KEYPRESSED; { Ende wenn Taste gedrückt }
Antw := READKEY; { Tastaturabfrage }
INC (X_POS, 1); { bewirkt Aktualisierung der Zeit nach Tastendruck }
INC (Y_POS, 1); { bewirkt Aktualisierung der Spannung }
CASE Antw OF { Fallunterscheidung }
'+' : BEGIN { X-Achse nach links schieben }
Clr := TRUE; { Löschmodus aktiv }
Mausein (0); { Maus aus }
Plotten (Offs, Clr, Anf_std, Anf_min);{ Löschen }
Clr := FALSE; { Löschmodus inaktiv }
INC (Offs, 60 * (Zoom)); { Offset erhöhen = 1 Std.}
END;
'-' : BEGIN { X-Achse nach rechts schieben }
Clr := TRUE;
Mausein (0);
Plotten (Offs, Clr, Anf_std, Anf_min);
Clr := FALSE;
DEC (Offs, 60 * (Zoom));
END;
END;
IF Offs < 0 THEN Offs := 0;
UNTIL Antw = #27; { Wenn ESC gedrückt }
ENDE:
CLOSE (Mess_Daten); { Messdaten-Datei schließen }
CLOSEGRAPH; { Grafiktreiber deaktivieren }
{ Textmodus wiederherstellen }
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ MESSDATEN-DATEINAMEN EINGEBEN │
│ EINGABEN : VOLLSTÄNDIGER DATEINAME │
│ AUSGABE : GEÖFFNETE DATEI │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE Messdaten_Dateiname;
VAR OK : BOOLEAN;
Antw : CHAR;
Alt : STRING [30]; { Alter Dateiname }
BEGIN
Alt := Mess_Datei; { Dateiname sichern }
WINDOW (10, 10, 58, 16); { neues Fenster öffnen }
TEXTBACKGROUND (3);
TEXTCOLOR (15);
CLRSCR;
WRITELN ('╔═ Neuer Dateiname ════════════════════════════╗');
WRITELN ('║ > ║');
WRITELN ('║ ║');
WRITELN ('║ ║');
WRITELN ('║ ║');
WRITELN ('║ ║');
WRITE ('╚══════════════════════════════════════════════╝');
GOTOXY (5,2);
READLN (Mess_Datei); { neuen Dateinamen lesen }
IF Mess_Datei = '' THEN { bei Leereingabe wird alter }
BEGIN { Dateiname wiederhergestellt und }
Mess_Datei := Alt; { Eingaberoutine beendet. }
EXIT;
END;
ASSIGN (Mess_Daten, Mess_Datei); { Datei mit neuem Namen definieren }
{$I-}
RESET (Mess_Daten); { Datei versuchen zu öffnen }
{$I+}
OK := IORESULT=0; { IO-Result auswerten }
IF NOT OK THEN
BEGIN { Öffnen war Fehlerhaft }
GOTOXY (5, 4);
WRITE ('DATEINAME NICHT GEFUNDEN.');
GOTOXY (5, 5);
WRITE ('SOLL DATEI NEU ERSTELLT WERDEN ? (J/N) >');
REPEAT
Antw := READKEY;
UNTIL (UPCASE(Antw) = 'J') OR (UPCASE(Antw) = 'N');
IF UPCASE(Antw) = 'J' THEN { Datei neu generieren }
BEGIN
{$I-}
REWRITE (Mess_Daten);
{$I+}
OK := IORESULT=0; { IO-Result auswerten }
IF NOT OK THEN
BEGIN { Schreibversuch mislang }
GOTOXY (5, 4);
WRITE (' ');
GOTOXY (5, 5);
TEXTBACKGROUND (12);
TEXTCOLOR (15);
WRITE (' DATEI KANN NICHT BESCHRIEBEN WERDEN! ');
Mess_Datei := Alt;
DELAY (2000);
END;
END;
IF UPCASE(Antw) = 'N' THEN Mess_Datei := Alt;
END;
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ VOREINSTELLUNGEN │
│ EINGABEN : PORTS, KAPAZITÄT, NENNSPANNUNG │
│ AUSGABE : ANLEGEN EINER DATENDATEI │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE Einstellungen;
LABEL START; { Sprungmarke }
VAR Nr : BYTE; { Variablendeklaration }
Err : INTEGER; { Fehlerspeicher }
Groesse : LONGINT; { Groesse der Messwertdatei }
Antw : CHAR; { Antwort von Tastatur }
Aktion : CHAR; { Menüauswahl }
OK : BOOLEAN; { Ergebnis der Dateioperationen }
OKmess : BOOLEAN; { Messdatei IORESULT }
Eingabe : Akku_str; { Eingabestring }
Zeitstr : STRING [5]; { Zoom-Anzeige }
Drckstr : STRING [4]; { Protokoll-Anzeige }
BEGIN START:
Par := ''; { Initialisierung }
Ser := '';
OK := FALSE;
OKmess := FALSE;
Mausbereich (1, 1, (80-1) * 8, (25-1) * 8); { Maus-Bewegungsbereich im Textmodus }
ASSIGN (Akku_Port, Akku_Pdatei); { Datei Akku_Port öffnen }
ASSIGN (Akku_Dat, Akku_Datei); { Datei Akku_Dat öffnen }
IF Zoom = 2 THEN Zeitstr := 'fein';
IF Zoom = 1 THEN Zeitstr := 'grob';
IF Drucken = TRUE THEN Drckstr := 'ein';
IF Drucken = FALSE THEN Drckstr := 'aus';
WINDOW (1, 1, 80, 25); { Fenster max. Größe }
Mausein (0);
TEXTBACKGROUND (0); { Hintergrundf. }
CLRSCR; { Bildschirm löschen }
TEXTBACKGROUND (7);
TEXTCOLOR (4);
WRITELN (' NI-CD-LADESTEUERUNG - VERSION 2.0 (c) Carsten Stelling 1994 ');
TEXTBACKGROUND (1);
TEXTCOLOR (15);
WRITELN;
WRITELN;
WRITELN ('╔═ Auswahl ═════════════════════════════╗');
WRITELN ('║ 1 = Lade-/Entladekurven betrachten ║');
WRITELN ('║ 2 = Zeitraster ', Zeitstr,' ║');
WRITELN ('║ 3 = Parametrierung (Datei erstellen) ║');
WRITELN ('║ 4 = Ladevorgang starten ║');
WRITELN ('║ 5 = Messdaten Dateiname ändern ║');
WRITELN ('║ 6 = A/D-WANDLER Testprogramm ║');
WRITELN ('║ 7 = Protokoll ', Drckstr, ' ║');
WRITELN ('║ 8 = Informationen ║');
WRITELN ('║ 9 = Programm ENDE ║');
WRITELN ('╚═══════════════════════════════════════╝');
TEXTBACKGROUND (0);
TEXTCOLOR (12);
WRITELN;
WRITELN ('Wählen Sie eine Aktion indem Sie die entsprechende Ziffer betätigen');
WRITELN ('oder die entsprechende Zeile mit dem Mauscursor ansteuern und die');
WRITELN ('linke Maustaste drücken.');
TEXTCOLOR (15);
GOTOXY (1, 22);
WRITE ('PROTOKOLL: ');
IF Drucken = TRUE THEN WRITE ('Druck an LPT1')
ELSE WRITE ('nicht drucken');
ASSIGN (Mess_Daten, Mess_Datei);
{$I-}
RESET (Mess_Daten);
{$I+}
OKmess := IORESULT=0;
IF NOT OKmess THEN
BEGIN
Fehler_Fenster;
GOTOXY (4, 3);
WRITELN ('Standard-Messwertdatei nicht vorhanden!');
GOTOXY (4, 4);
WRITELN ('Erzeuge leere Datei: MESS_1.NCL');
REWRITE (Mess_Daten);
DELAY (1500);
GOTOXY (4, 6);
WRITELN ('NEUSTART...');
DELAY (1500);
GOTO START;
END;
Groesse := FILESIZE (Mess_Daten);
CLOSE (Mess_Daten);
GOTOXY (1, 24);
WRITE ('MESSWERTDATEI: ',Mess_Datei,' (',Groesse,' Datensätze)');
Mausein (1);
Mausein (1);
REPEAT;
Aktion := '0';
IF KEYPRESSED THEN Aktion := READKEY;
Mausstatus;
Mausx := (Mausx + 8) DIV 8;
Mausy := (Mausy + 8) DIV 8;
IF (Mausx > 1) AND (Mausx < 41) AND (Maust = 1) THEN Aktion := CHR (44 + Mausy);
UNTIL (ORD (Aktion) > 48) AND (ORD (Aktion) < 58);
CASE Aktion OF
'7': BEGIN
Drucken := NOT Drucken;
IF (Drucken = TRUE) AND (AdrLPT = AdrLPT1) THEN
BEGIN
Fehler_Fenster;
GOTOXY (3, 2);
WRITE ('Drucken an LPT1 und Steuerung der');
GOTOXY (3, 3);
WRITE ('Zusatzplatine an LPT 1 ist nicht möglich.');
GOTOXY (3, 4);
WRITE ('Protokollierung wird ausgeschaltet.');
GOTOXY (3, 6);
WRITE ('Zurück zum Hauptmenü mit Tastendruck. >');
REPEAT UNTIL KEYPRESSED;
Antw := READKEY;
Antw := ' ';
Drucken := NOT Drucken;
END;
DELAY (500);
GOTO START;
END;
'5': BEGIN
Mausein (0);
Messdaten_Dateiname;
Mausein (1);
GOTO START;
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ A/D-WANDLER TESTPROGRAMM │
│ EINGABEN : COM-PORT DES WANDLERS │
│ AUSGABE : SPANNUNG DER 8 MESSKANÄLE │
└────────────────────────────────────────────────────────────────────────┘ }
'6': BEGIN
Mausein (0);
WINDOW (15, 8, 47, 19);
TEXTBACKGROUND (2);
TEXTCOLOR (15);
CLRSCR;
WRITELN ('╔═ A/D-Test ═══════════════════╗');
WRITELN ('║ ║');
WRITELN ('║ A/D-Wandler an Port ? ║');
WRITELN ('║ > ║');
WRITELN ('║ ║');
WRITELN ('║ ║');
WRITELN ('║ ║');
WRITELN ('║ ║');
WRITELN ('║ ║');
WRITELN ('║ ║');
WRITELN ('║ ║');
WRITE ('╚══════════════════════════════╝');
REPEAT;
GOTOXY (5, 4);
WRITELN (' ');
GOTOXY (5, 4);
READLN (Eingabe);
UNTIL (Eingabe = 'COM1') OR (Eingabe = 'com1') AND (AdrCOM1 <> 0)
OR (Eingabe = 'COM2') OR (Eingabe = 'com2') AND (AdrCOM2 <> 0)
OR (Eingabe = 'COM3') OR (Eingabe = 'com3') AND (AdrCOM3 <> 0)
OR (Eingabe = 'COM4') OR (Eingabe = 'com4') AND (AdrCOM4 <> 0);
IF (Eingabe = 'COM1') OR (Eingabe = 'com1') THEN Portadr := AdrCOM1;
IF (Eingabe = 'COM2') OR (Eingabe = 'com2') THEN Portadr := AdrCOM2;
IF (Eingabe = 'COM3') OR (Eingabe = 'com3') THEN Portadr := AdrCOM3;
IF (Eingabe = 'COM4') OR (Eingabe = 'com4') THEN Portadr := AdrCOM4;
Ser := Eingabe;
CLRSCR;
WRITELN ('╔═ A/D-Test ═══════════════════╗');
WRITELN ('║ KANAL SPANNUNG ║');
WRITELN ('║ 1: ║');
WRITELN ('║ 2: ║');
WRITELN ('║ 3: ║');
WRITELN ('║ 4: ║');
WRITELN ('║ 5: ║');
WRITELN ('║ 6: ║');
WRITELN ('║ 7: ║');
WRITELN ('║ 8: ║');
WRITELN ('║ ESC, RECHTE MAUSTASTE = ENDE ║');
WRITE ('╚══════════════════════════════╝');
Mausein (1);
CursorAus;
REPEAT;
FOR Z := 1 TO 8 DO
BEGIN
GOTOXY (14, Z + 2);
WRITE (AD_Messwert (Z):6:3, ' Volt');
DELAY (2);
END;
Mausstatus;
IF KEYPRESSED THEN Antw := READKEY;
UNTIL (Antw = CHR (27)) OR (Maust = 2);
Antw := '0';
CursorEin;
GOTO START;
END;
'8': BEGIN
WINDOW (1, 1, 80, 25); { Fenster max. Größe }
Mausein (0);
TEXTBACKGROUND (0); { Hintergrundf. }
CLRSCR; { Bildschirm löschen }
TEXTBACKGROUND (7);
TEXTCOLOR (4);
WRITELN (' NI-CD-LADESTEUERUNG - VERSION 2.0 (c) Carsten Stelling 1994 ',#10);
TEXTBACKGROUND (0);
TEXTCOLOR (3);
WRITELN ('PROGRAMM-INFORMATION:', #10);
TEXTCOLOR (7);
WRITELN ('Version 2.0');
WRITELN ('Letzte Änderung am 15.04.1994 15:37', #10);
WRITELN ('Unterstützte Schnittstellen:', #10);
WRITELN (' LPT1 : Zusatzplatine oder Protokoll-Drucker');
WRITELN (' LPT2 : Zusatzplatine');
WRITELN (' LPT3 : Zusatzplatine');
WRITELN ('COM1 - COM4 : A/D-WANDLER Fa. Conrad Best.Nr. 97 97 67', #10);
TEXTCOLOR (2);
WRITELN ('Es wird vorausgesetzt, daß nur 1.2 V-Zellen geladen werden.');
WRITELN ('Bei Verwendung von Akku-Packs sind die Spannungsteiler so');
WRITELN ('zu dimensionieren, daß die Eingangsspannung des A/D-Wandlers');
WRITELN ('bei Akku-Nennspannung 1.2V beträgt.', #10, #10, #10, #10);
TEXTCOLOR (14);
WRITE ('mehr Information...');
DELAY (500);
Warten;
WINDOW (1, 3, 80, 23);
Mausein (0);
CLRSCR;
TEXTCOLOR (7);
WRITELN ('BELEGUNG DES SERIELLEN ANSCHLUSSES (D-SUB 9/M):');
WRITELN ('┌─────┬────────────┬─────────────────────────────┐');
WRITELN ('│ PIN │ SIGNALNAME │ BENENNUNG / FUNKTION │');
WRITELN ('├─────┼────────────┼─────────────────────────────┤');
WRITELN ('│ 4 │ DTR │ Data Terminal Ready / SCLK │');
WRITELN ('│ 5 │ GND │ Ground / Bezugspotential │');
WRITELN ('│ 7 │ RTS │ Ready to Send / Daten Eing. │');
WRITELN ('│ 8 │ CTS │ Clear to Send / Daten Ausg. │');
WRITELN ('└─────┴────────────┴─────────────────────────────┘', #10);
WRITELN ('BELEGUNG DES SERIELLEN ANSCHLUSSES (D-SUB 25/M):');
WRITELN ('┌─────┬────────────┬─────────────────────────────┐');
WRITELN ('│ PIN │ SIGNALNAME │ BENENNUNG / FUNKTION │');
WRITELN ('├─────┼────────────┼─────────────────────────────┤');
WRITELN ('│ 20 │ DTR │ Data Terminal Ready / SCLK │');
WRITELN ('│ 7 │ GND │ Ground / Bezugspotential │');
WRITELN ('│ 4 │ RTS │ Ready to Send / Daten Eing. │');
WRITELN ('│ 5 │ CTS │ Clear to Send / Daten Ausg. │');
WRITELN ('└─────┴────────────┴─────────────────────────────┘');
DELAY (500);
Warten;
WINDOW (1, 3, 80, 23);
Mausein (0);
CLRSCR;
TEXTCOLOR (7);
WRITELN ('BELEGUNG DES PARALLELEN ANSCHLUSSES (D-SUB 25/F):');
WRITELN ('┌─────┬────────────┬─────────────────────────────┐');
WRITELN ('│ PIN │ SIGNALNAME │ BENENNUNG / FUNKTION │');
WRITELN ('├─────┼────────────┼─────────────────────────────┤');
WRITELN ('│ 2 │ DATA 0 │ Akku 1 - Ladetransistor │');
WRITELN ('│ 3 │ DATA 1 │ Akku 1 - Entlade-MOSFET │');
WRITELN ('│ 4 │ DATA 2 │ Akku 2 - Ladetransistor │');
WRITELN ('│ 5 │ DATA 3 │ Akku 2 - Entlade-MOSFET │');
WRITELN ('│ 6 │ DATA 4 │ Akku 3 - Ladetransistor │');
WRITELN ('│ 7 │ DATA 5 │ Akku 3 - Entlade-MOSFET │');
WRITELN ('│ 8 │ DATA 6 │ Akku 4 - Ladetransistor │');
WRITELN ('│ 9 │ DATA 7 │ Akku 4 - Entlade-MOSFET │');
WRITELN ('│ 18 │ GND │ Ground / Bezugspotential │');
WRITELN ('│ 25 │ GND │ Ground / Bezugspotential │');
WRITELN ('└─────┴────────────┴─────────────────────────────┘');
DELAY (500);
Warten;
WINDOW (1, 3, 80, 25);
Mausein (0);
CLRSCR;
TEXTCOLOR (7);
WRITELN ('BERECHNUNGSFORMELN FÜR SPANNUNGSTEILER:',#10);
WRITELN (' AKKU + ──────┬────────── ');
WRITELN (' │ │ │');
WRITELN (' ┌┴┐ │ │ R2 * Ua');
WRITELN (' R1 │ │ U1│ │ R1 = ───────── - R2');
WRITELN (' └┬┘ │ │ 1.2V');
WRITELN (' │ V │');
WRITELN (' ├────── │Ua');
WRITELN (' │ │ │');
WRITELN (' ┌┴┐ │ │ R1 * 1.2V');
WRITELN (' R2 │ │ U2│ │ R2 = ───────────');
WRITELN (' └┬┘ │ │ Ua - 1.2V');
WRITELN (' │ V V');
WRITELN (' AKKU - ──────┴──────────');
TEXTCOLOR (15);
WRITELN (' R2 sollte im Bereich von 1 kΩ');
WRITELN (' bis 10 kΩ gewählt werden.',#10);
WRITELN ('Beispiel: Ua = 4.8 V, R2 gewählt 1 kΩ, R1 berechnet 3 kΩ');
TEXTCOLOR (2);
WRITELN ('(niederohmige Spannungsteiler vermindern Störungen)', #10);
TEXTCOLOR (14);
WRITELN ('Info Ende.');
DELAY (500);
Warten;
GOTO START;
END;
'9': BEGIN
Mausein (0);
WINDOW (1, 1, 80, 25);
CLRSCR;
WRITELN;
TEXTCOLOR(7);
WRITELN ('NI-CD-Ladeprogramm beendet.');
HALT;
END;
'1': BEGIN
ASSIGN (Mess_Daten, Mess_Datei);
{$I-}
RESET (Mess_Daten);
{$I+}
OKmess := IORESULT=0;
IF NOT OKmess THEN
BEGIN
TEXTCOLOR (31);
GOTOXY (1, 24);
WRITE ('DATEI ',Mess_Datei,' NICHT VORHANDEN !');
DELAY (3000);
GOTO START;
END;
Auswertung; GOTO START; END;
'2' : BEGIN
IF Zoom = 1 THEN Zoom := 2 ELSE
IF Zoom = 2 THEN Zoom := 1;
DELAY (500);
GOTO START;
END;
'3' : BEGIN
REWRITE (Akku_Port);
REWRITE (Akku_Dat);
OK := FALSE;
END;
'4' : BEGIN
{$I-}
RESET (Akku_Port);
RESET (Akku_Dat);
{$I+}
OK := IORESULT=0;
IF NOT OK THEN
BEGIN
REWRITE (Akku_Port);
REWRITE (Akku_Dat);
END; { END von '3': BEGIN }
END; { END von IF }
END; { END von CASE }
REPEAT;
Mausein (0);
WINDOW (1, 1, 80, 25); { Eingabefenster }
TEXTBACKGROUND (0); { für Akkuparameter }
CLRSCR;
TEXTBACKGROUND (7);
TEXTCOLOR (4);
WRITELN (' NI-CD-LADESTEUERUNG - VERSION 2.0 (c) Carsten Stelling 1994 ');
TEXTBACKGROUND (0);
TEXTCOLOR (14);
WRITELN ('═════════════════════════════ GRUNDEINSTELLUNGEN ══════════════════════════════');
TEXTBACKGROUND (3);
TEXTCOLOR (15);
WRITELN ('╔═ I/O ═╤═ Adr.═╗');
IF AdrLPT1 <> 0 THEN WRITELN ('║ LPT1: │ ',HexZahl (AdrLPT1, 3),' ║');
IF AdrLPT2 <> 0 THEN WRITELN ('║ LPT2: │ ',HexZahl (AdrLPT2, 3),' ║');
IF AdrCOM1 <> 0 THEN WRITELN ('║ COM1: │ ',HexZahl (AdrCOM1, 3),' ║');
IF AdrCOM2 <> 0 THEN WRITELN ('║ COM2: │ ',HexZahl (AdrCOM2, 3),' ║');
IF AdrCOM3 <> 0 THEN WRITELN ('║ COM3: │ ',HexZahl (AdrCOM3, 3),' ║');
IF AdrCOM4 <> 0 THEN WRITELN ('║ COM4: │ ',HexZahl (AdrCOM4, 3),' ║');
WRITELN ('╚═══════╧═══════╝');
TEXTBACKGROUND (0);
REPEAT; { Welche Schnittstelle ? }
GOTOXY (1, 14);
WRITE ('Auswertung der A/D-Wandlersignale von Port: ');
CLREOL;
IF NOT OK THEN READLN (Eingabe) ELSE
BEGIN
READ (Akku_Port, Eingabe);
WRITE (Eingabe);
END;
UNTIL (Eingabe = 'COM1') OR (Eingabe = 'com1') AND (AdrCOM1 <> 0)
OR (Eingabe = 'COM2') OR (Eingabe = 'com2') AND (AdrCOM2 <> 0)
OR (Eingabe = 'COM3') OR (Eingabe = 'com3') AND (AdrCOM3 <> 0)
OR (Eingabe = 'COM4') OR (Eingabe = 'com4') AND (AdrCOM4 <> 0);
IF (Eingabe = 'COM1') OR (Eingabe = 'com1') THEN Portadr := AdrCOM1;
IF (Eingabe = 'COM2') OR (Eingabe = 'com2') THEN Portadr := AdrCOM2;
IF (Eingabe = 'COM3') OR (Eingabe = 'com3') THEN Portadr := AdrCOM3;
IF (Eingabe = 'COM4') OR (Eingabe = 'com4') THEN Portadr := AdrCOM4;
Ser := Eingabe;
TEXTCOLOR (7);
REPEAT; { Welche Schnittstelle ? }
GOTOXY (1, 15);
WRITE ('Ansteuerung der Zusatzplatine mit Port....: ');
CLREOL;
IF NOT OK THEN READLN (Eingabe) ELSE
BEGIN
READ (Akku_Port, Eingabe);
WRITE (Eingabe);
END;
UNTIL (Eingabe = 'LPT1') OR (Eingabe = 'lpt1')
OR (Eingabe = 'LPT2') OR (Eingabe = 'lpt2');
IF (Eingabe = 'LPT1') OR (Eingabe = 'lpt1') AND (AdrLPT1 <> 0) THEN AdrLPT := AdrLPT1;
IF (Eingabe = 'LPT2') OR (Eingabe = 'lpt2') AND (AdrLPT2 <> 0) THEN AdrLPT := AdrLPT2;
IF (Eingabe = 'LPT3') OR (Eingabe = 'lpt3') AND (AdrLPT3 <> 0) THEN AdrLPT := AdrLPT3;
Par := Eingabe;
IF NOT OK THEN
BEGIN
WRITE (Akku_Port, Ser); { Benutzte Schnittstellen speichern }
WRITE (Akku_Port, Par);
END;
TEXTBACKGROUND (1);
TEXTCOLOR (11);
GOTOXY (20, 5);
WRITE ('╔═ Akku ══╤═ Kapaz.══╤═ Spng.══╤═ Algorithmus ════════╗');
GOTOXY (20, 6);
WRITE ('║ AKKU 1: │ │ │ ║');
GOTOXY (20, 7);
WRITE ('║ AKKU 2: │ │ │ ║');
GOTOXY (20, 8);
WRITE ('║ AKKU 3: │ │ │ ║');
GOTOXY (20, 9);
WRITE ('║ AKKU 4: │ │ │ ║');
GOTOXY (20, 10);
WRITE ('╚═════════╧══════════╧═════════╧══════════════════════╝');
GOTOXY (20, 11);
TEXTBACKGROUND (0);
WRITE ('0 = nicht angeschlossen');
FOR Nr := 1 TO 4 DO
BEGIN
REPEAT;
GOTOXY (1, 16 + Nr);
CLREOL;
TEXTBACKGROUND (0);
WRITE ('KAPAZITÄT AKKU ',Nr,' (mAh) ?: ');
CLREOL;
IF NOT OK THEN
BEGIN
READLN (Eingabe);
WRITE (Akku_Dat, Eingabe);
END
ELSE BEGIN
READ (Akku_Dat, Eingabe);
WRITE (Eingabe);
END;
VAL (Eingabe, Akku [Nr].Kap, Err);
UNTIL (Err = 0) AND (Akku [Nr].Kap >=0) AND (Akku [Nr].Kap <=5000);
GOTOXY (31, Nr+5);
TEXTBACKGROUND (1);
WRITE (Akku [Nr].Kap :5:0,' mAh');
END;
FOR Nr := 1 TO 4 DO
BEGIN
IF Akku [Nr].Kap > 0 THEN
BEGIN
REPEAT;
GOTOXY (34, 16 + Nr);
CLREOL;
TEXTBACKGROUND (0);
WRITE ('NENNSPANNUNG (V) ?: ');
CLREOL;
IF NOT OK THEN
BEGIN
READLN (Eingabe);
WRITE (Akku_dat, Eingabe);
END
ELSE BEGIN
READ (Akku_Dat, Eingabe);
WRITE (Eingabe);
END;
VAL (Eingabe, Akku [Nr].Spg, Err);
UNTIL (Err = 0) AND (Akku [Nr].Spg >=0) AND (Akku [Nr].Spg <=20);
GOTOXY (43, Nr+5);
TEXTBACKGROUND (1);
WRITE (Akku [Nr].Spg :5:1,' V');
END
ELSE
BEGIN
Eingabe := '0';
VAL (Eingabe, Akku [Nr].Spg, Err);
WRITE (Akku_dat, Eingabe);
END;
END;
GOTOXY (1, 22);
WRITE (' ALGORITHMUS (1 = NUR LADEN, 2 = VORHER ENTLADEN, 3 = REGENERIEREN) ');
FOR Nr := 1 TO 4 DO
BEGIN
IF Akku [Nr].Kap > 0 THEN
BEGIN
REPEAT;
GOTOXY (63, 16 + Nr);
CLREOL;
TEXTBACKGROUND (0);
WRITE ('ALGORITHMUS ?: ');
CLREOL;
IF NOT OK THEN
BEGIN
READLN (Eingabe);
WRITE (Akku_dat, Eingabe);
END
ELSE BEGIN
READ (Akku_Dat, Eingabe);
WRITE (Eingabe);
END;
VAL (Eingabe, Akku [Nr].Algor, Err);
UNTIL (Err = 0) AND (Akku [Nr].Algor > 0) AND (Akku [Nr].Algor < 4);
GOTOXY (56, Nr+5);
TEXTBACKGROUND (1);
CASE Akku [Nr].Algor OF
1 : WRITE ('NUR LADEN');
2 : WRITE ('VORHER ENTLADEN');
3 : WRITE ('REGENERIEREN');
END;
END
ELSE
BEGIN
Eingabe := '0';
VAL (Eingabe, Akku [Nr].Algor, Err);
WRITE (Akku_dat, Eingabe);
END;
END;
TEXTBACKGROUND (4);
TEXTCOLOR (15);
GOTOXY (1 , 23);
WRITE (' SIND ALLE EINGABEN RICHTIG (J/N) ? ');
Antw := READKEY;
IF Antw = #27 THEN
BEGIN
Antw := ' ';
CLOSE (Akku_Port);
CLOSE (Akku_Dat);
GOTO START;
END;
IF UPCASE (Antw) <> 'J' THEN BEGIN
REWRITE (Akku_Dat);
REWRITE (Akku_Port);
OK := FALSE;
END;
UNTIL UPCASE (Antw) = 'J';
CLOSE (Akku_Port);
CLOSE (Akku_Dat);
IF Aktion = '3' THEN GOTO START;
IF (Drucken = TRUE) AND (AdrLPT = AdrLPT1) THEN
BEGIN
Fehler_Fenster;
GOTOXY (3, 2);
WRITE ('Drucken an LPT1 und Steuerung der');
GOTOXY (3, 3);
WRITE ('Zusatzplatine an LPT 1 ist nicht möglich.');
GOTOXY (3, 4);
WRITE ('Protokollierung wird ausgeschaltet.');
GOTOXY (3, 6);
WRITE ('Zurück zum Hauptmenü mit Tastendruck. >');
REPEAT UNTIL KEYPRESSED;
Antw := READKEY;
Antw := ' ';
Drucken := NOT Drucken;
GOTO START;
END;
FOR Nr := 1 TO 4 DO
BEGIN
WITH Akku [Nr] DO
BEGIN
Laden := FALSE;
Entladen := FALSE;
V_Summe := 0.0;
V_Mittel := 0.0;
V_Vorher := 0.0;
END;
END;
TEXTBACKGROUND (0); { Messdaten-Fenster }
TEXTCOLOR (7);
WINDOW (1, 2, 80, 25);
CLRSCR;
GOTOXY (1, 3);
WRITELN ('╔═ Akku ═╤═ CH 0 ════════╤═ φ U ════════════╤═ Status ══╤═ Kap.══════════╗');
WRITELN ('║ Nr: 1 │ │ │ │ ║');
WRITELN ('║ ├─ CH 1 ────────┼─ I max ──────────┼─ Zeit ────┼─ Alg.──────────╢');
WRITELN ('║ │ │ │ │ ║');
WRITELN ('╠═ Akku ═╪═ CH 2 ════════╪═ φ U ════════════╪═ Status ══╪═ Kap.══════════╣');
WRITELN ('║ Nr: 2 │ │ │ │ ║');
WRITELN ('║ ├─ CH 3─────────┼─ I max ──────────┼─ Zeit ────┼─ Alg.──────────╢');
WRITELN ('║ │ │ │ │ ║');
WRITELN ('╠═ Akku ═╪═ CH 4 ════════╪═ φ U ════════════╪═ Status ══╪═ Kap.══════════╣');
WRITELN ('║ Nr: 3 │ │ │ │ ║');
WRITELN ('║ ├─ CH 5 ────────┼─ I max ──────────┼─ Zeit ────┼─ Alg.──────────╢');
WRITELN ('║ │ │ │ │ ║');
WRITELN ('╠═ Akku ═╪═ CH 6 ════════╪═ φ U ════════════╪═ Status ══╪═ Kap.══════════╣');
WRITELN ('║ Nr: 4 │ │ │ │ ║');
WRITELN ('║ ├─ CH 7 ────────┼─ I max ──────────┼─ Zeit ────┼─ Alg.──────────╢');
WRITELN ('║ │ │ │ │ ║');
WRITELN ('╚════════╧═══════════════╧══════════════════╧═══════════╧════════════════╝');
WRITELN ('MESSWERTDATEI : ', Mess_Datei);
TEXTCOLOR (13);
WRITE ('SCHNITTSTELLEN: ',Ser, ' / ', Par);
TEXTBACKGROUND (1);
TEXTCOLOR (14);
GOTOXY (57, 21);
WRITE (' ESC = Abbrechen ');
TEXTBACKGROUND (0);
FOR Nr := 1 TO 4 DO
BEGIN
TEXTCOLOR (3);
GOTOXY (3, (Nr - 1) * 4 + 5);
IF Akku [Nr].Spg > 0 THEN WRITE (Akku [Nr].Spg :0:1,' V');
GOTOXY (60, (Nr - 1) * 4 + 4);
IF Akku [Nr].Kap > 0 THEN WRITE (Akku [Nr].Kap :0:0,' mAh');
TEXTCOLOR (14);
GOTOXY (60, (Nr - 1) * 4 + 6);
CASE Akku [Nr].Algor OF
1 : WRITE ('NUR LADEN');
2 : WRITE ('VORHER ENTLAD.');
3 : WRITE ('REGENERIEREN');
END;
END;
TEXTCOLOR (10);
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ TABELLENEINTRAG │
│ EINGABEN : LADEPLATZ-NUMMER │
│ AUSGABE : WERTE IN DIE TABELLE SCHREIBEN │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE TabEintrag (Platz : BYTE);
VAR ZE, CO : BYTE;
BEGIN
CASE Platz OF
1: BEGIN
ZE := 4;
CO := 10;
END;
2: BEGIN
ZE := 8;
CO := 13;
END;
3: BEGIN
ZE := 12;
CO := 7;
END;
4: BEGIN
ZE := 16;
CO := 1;
END;
END; { END von CASE }
GOTOXY (12, ZE);
TEXTCOLOR (CO);
WRITE (Mess1[Platz]:6:3,' VOLT');
GOTOXY (28, ZE);
WRITE (Akku [Platz].V_Mittel :7:4,' VOLT');
GOTOXY (12, ZE+2);
WRITE (Mess2[Platz]:6:3,' VOLT');
GOTOXY (28, ZE+2);
WRITE ((Mess1[Platz] - Mess2[Platz]) / R[Platz] : 6:3,' AMPERE');
GOTOXY (47, ZE);
IF Akku [Platz].Laden = TRUE THEN WRITE ('LADEN ', Akku [Platz].Zyklus, ' ') ELSE
IF Akku [Platz].Entladen = TRUE THEN WRITE ('ENTLADEN') ELSE
IF Akku [Platz].Defekt = TRUE THEN
BEGIN
TEXTCOLOR (28);
WRITE ('DEFEKT !');
TEXTCOLOR (CO);
END ELSE
BEGIN TEXTCOLOR (31);
WRITE ('VOLL ');
TEXTCOLOR (CO);
END;
GOTOXY (47, ZE+2);
GETTIME (std,min,sek,s100);
WRITE (TFormat (std),':',TFormat (min),':',TFormat (sek));
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ STARTPROTOKOLL AUF DRUCKER AUSGEBEN │
│ EINGABEN : KEINE │
│ AUSGABE : PROTOKOLL AN STANDARDDRUCKER LPT1 │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE Startprotokoll;
VAR Z : BYTE;
BEGIN;
{$I-}
WRITELN (LST,' ╔════════════════════════════════════════════════╗');
WRITELN (LST,' ║ NI-CD-AKKULADER Version 2.0 ║');
WRITELN (LST,' ║ (c) Carsten Stelling ║');
WRITELN (LST,' ║ Alleestraße 10 ║');
WRITELN (LST,' ║ 56566 Neuwied ║');
WRITELN (LST,' ║ Tel: 02622 / 4062 ║');
WRITELN (LST,' ╚════════════════════════════════════════════════╝',#10);
WRITE (LST,' PROTOKOLL DES LADEVORGANGES VOM: ');
WRITELN (LST, tag,'.',mon,'.',jahr,' - ',TFormat (Std),':',TFormat (min),':',TFormat (sek),' Uhr');
WRITELN (LST,' Messdatenerfassung in Datei: ',Mess_Datei);
WRITELN (LST,' Steuern mit Schnittstelle : ',Par);
WRITELN (LST,' ADU an ser. Schnittstelle : ',Ser, #10);
FOR Z := 1 TO 4 DO
BEGIN
WRITELN (LST,' AKKU ',Z,': Nennspannung : ',Akku [Z].Spg:4:1,' Volt');
WRITELN (LST,' Nennkapazität: ',Akku [Z].Kap:5:0,' mAh');
WRITE (LST,' Algorithmus..: ');
CASE Akku [Z].Algor OF
0: WRITELN (LST,'---');
1: WRITELN (LST,'nur laden');
2: WRITELN (LST,'vorher entladen');
3: WRITELN (LST,'regenerieren in 3 Zyklen');
END;
WRITE (LST,' Status.......: ');
IF Akku [Z].Online = TRUE THEN WRITELN (LST, 'ONLINE') ELSE
IF Akku [Z].Online = FALSE THEN WRITELN (LST, 'OFFLINE');
IF Akku [Z].Defekt = TRUE THEN WRITELN (LST,' *** AKKU DEFEKT ***');
WRITELN (LST,' ────────────────────────────────────────────────────────────────────');
END;
{$I+}
Dr_OK := IORESULT=0;
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ ENDPROTOKOLL AUF DRUCKER AUSGEBEN │
│ EINGABEN : KEINE │
│ AUSGABE : PROTOKOLL AN STANDARDDRUCKER LPT1 │
└────────────────────────────────────────────────────────────────────────┘ }
PROCEDURE Endprotokoll;
VAR Z : BYTE;
BEGIN
{$I-}
WRITE (LST,' ENDE DES LADEVORGANGES AM: ');
WRITE (LST, tag,'.',mon,'.',jahr,' - ',TFormat (Std),':',TFormat (min),':',TFormat (sek),' Uhr',#10,#10,#13);
FOR Z := 1 TO 4 DO
BEGIN
WRITELN (LST,' AKKU ',Z,': Istspannung..: ',Akku [Z].V_Mittel:6:3,' Volt');
WRITE (LST,' Status.......: ');
IF Akku [Z].Online = TRUE THEN WRITELN (LST, 'ONLINE') ELSE
IF Akku [Z].Online = FALSE THEN WRITELN (LST, 'OFFLINE');
IF Akku [Z].Defekt = TRUE THEN WRITELN (LST,' *** AKKU DEFEKT ***');
WRITELN (LST,' ────────────────────────────────────────────────────────────────────');
END;
IF Bed_Abr = TRUE THEN WRITELN (LST, #10,' LADEVORGANG WURDE VORZEITIG ABGEBROCHEN !!');
WRITELN (LST, #12);
{$I+}
Dr_OK := IORESULT=0;
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ PROGRAMM-ENDE │
│ EINGABEN : KEINE │
│ AUSGABE : RÜCKKEHR ZUR DOS- ODER PASCAL UMGEBUNG │
└────────────────────────────────────────────────────────────────────────┘ }
{$F+}
PROCEDURE Programm_Ende;
{$F-}
VAR Nr : BYTE;
OK : BOOLEAN;
Antw : CHAR;
BEGIN
EXITPROC := Exit_Adr;
FOR Nr := 1 TO 4 DO
BEGIN
Laden_aus (Nr);
Entladen_aus (Nr);
END;
FOR Nr := 1 TO 4 DO
BEGIN
IF Akku [Nr].Defekt = TRUE THEN Messwert [Nr] := 999
ELSE
IF (Akku [Nr].Defekt = FALSE) AND (Akku [Nr].Laden = FALSE) AND
(Akku [Nr].Entladen = FALSE) THEN Messwert [Nr] := 888
ELSE
IF ((Akku [Nr].Laden = TRUE) OR (Akku [Nr].Entladen = TRUE)) AND
(Bed_Abr = TRUE) THEN Messwert [Nr] := 777
ELSE
Messwert [Nr] := 999;
END;
WRITE (Mess_Daten, Messwert);
GETTIME (std,min,sek,s100);
Messwert [1] := std;
Messwert [2] := min;
Messwert [3] := sek;
Messwert [4] := s100;
WRITE (Mess_Daten, Messwert);
IF Dr_OK = FALSE THEN
BEGIN
GOTOXY (1, 23);
TEXTBACKGROUND (12);
TEXTCOLOR (15);
WRITE (' ALARM: DRUCKER NICHT BETRIEBSBEREIT AN LPT1 ');
END;
GOTOXY (1, 24);
TEXTBACKGROUND (0);
TEXTCOLOR (31);
WRITE (' LADEVORGANG ABGESCHLOSSEN. - BITTE EINE BELIEBIGE TASTE DRÜCKEN.');
IF Drucken = TRUE THEN Endprotokoll;
CLOSE (Mess_Daten);
Mausein (1);
CursorEin;
DELAY (1000);
REPEAT
Mausstatus;
UNTIL (KEYPRESSED) OR (Maust = 1);
IF KEYPRESSED THEN
BEGIN
Antw := READKEY;
Antw := ' ';
END;
Mausein (0);
END;
{ ┌────────────────────────────────────────────────────────────────────────┐
│ H A U P T P R O G R A M M │
│ EINGABEN : KEINE │
│ AUSGABE : STEUERUNG DER AKKU LADE- UND ENTLADEZYKLEN │
└────────────────────────────────────────────────────────────────────────┘ }
BEGIN
IF AdrLPT1 <> 0 THEN PORT [AdrLPT1] := 0; { LPT-Ports initialisieren }
IF AdrLPT2 <> 0 THEN PORT [AdrLPT2] := 0;
IF AdrLPT3 <> 0 THEN PORT [AdrLPT3] := 0;
CursorErmitteln; { Cursorpos. und Erscheinungsbild ermitteln }
CursorEin; { Cursor darstellen }
Wid_Werte; { Widerstandswerte aus SETUP holen }
Drucken := FALSE; { Voreinstellung: kein Protokoll }
Zoom := 2; { Voreinstellung feines Zeitraster }
Mausinit; { Maustreiber initialisieren }
Mausein (1); { Mauscursor einschalten }
START:
Dr_OK := TRUE; { Druck OK }
Bed_Abr := FALSE; { kein Bedienerabbruch }
AD_Init_Err := FALSE; { kein Init-Fehler }
PORT [AdrLPT] := 0; { aktuellen Port initialisieren }
Einstellungen; { Parametrierung }
AD_Wandler_init; { A/D-Wandler initialisieren und feststellen }
{ ob dieser überhaupt vorhanden ist. }
IF AD_Init_Err = TRUE THEN GOTO START; { Neustart bei Initialisierungsfehler }
Exit_Adr := EXITPROC; { Zeiger der System-Rücksprungadresse sichern }
EXITPROC := @Programm_Ende; { Zeiger auf Adresse der eigenen Prozedur einstellen }
ASSIGN (Mess_Daten, Mess_Datei); { Messwert-Datei öffnen }
REWRITE (Mess_Daten); { Messwert-Datei überschreiben }
GETTIME (std, min, sek, s100); { akt. Datum und Uhrzeit }
GETDATE (jahr, mon, tag, wtag);
Messwert [1] := wtag;
Messwert [2] := tag;
Messwert [3] := mon;
Messwert [4] := jahr;
WRITE (Mess_Daten, Messwert); { Datum in Rec. 1 speichern }
Messwert [1] := std;
Messwert [2] := min;
Messwert [3] := sek;
Messwert [4] := s100;
WRITE (Mess_Daten, Messwert); { Zeit in Rec. 2 speichern }
{ *** Akkus testen *** }
FOR Zaehler := 1 TO 4 DO
BEGIN
IF Akku [Zaehler].Kap = 0 THEN Akku [Zaehler].Online := FALSE ELSE
Akku [Zaehler].Online := TRUE;
IF (Akku [Zaehler].Kap > 0) AND ((AD_Messwert (Zaehler*2-1) < 0.4) OR (AD_Messwert (Zaehler * 2 - 1) > 1.7)) THEN
Akku [Zaehler].Defekt := TRUE ELSE
BEGIN
Akku [Zaehler].Defekt := FALSE;
Akku [Zaehler].Proben := 0;
Akku [Zaehler].V_Mittel := 0;
Akku [Zaehler].V_Summe := 0;
Akku [Zaehler].Zyklus := 1;
END;
IF (Akku [Zaehler].Online = TRUE) AND (Akku [Zaehler].Algor = 1) THEN
Akku [Zaehler].Laden := TRUE;
IF (Akku [Zaehler].Online = TRUE) AND ((Akku [Zaehler].Algor = 2) OR
(Akku [Zaehler].Algor = 3)) THEN
BEGIN
Akku [Zaehler].Entladen := TRUE;
END;
END;
IF Drucken = TRUE THEN Startprotokoll;
IF Dr_OK = FALSE THEN
BEGIN
Programm_Ende;
GOTO START;
END;
FOR Zaehler := 1 TO 4 DO
BEGIN
Messwert [Zaehler] := Akku [Zaehler].Kap;
END;
WRITE (Mess_Daten, Messwert);
FOR Zaehler := 1 TO 4 DO
BEGIN
Messwert [Zaehler] := Akku [Zaehler].Spg;
END;
WRITE (Mess_Daten, Messwert);
FOR Zaehler := 1 TO 4 DO
BEGIN
Messwert [Zaehler] := Akku [Zaehler].Algor;
END;
WRITE (Mess_Daten, Messwert);
GETTIME (std, min, sek, s100);
minalt := min;
Mausein (1);
CursorAus;
REPEAT; { Wiederholen bis alle A. offline }
FOR Zaehler := 1 TO 5 DO { Umlaufender Zähler }
BEGIN
CASE Zaehler OF
5 : BEGIN { 5. Schritt }
GETTIME (std,min,sek,s100); { Uhrzeit }
IF min <> minalt THEN { eine Minute ist um dann }
BEGIN { Testen ob Steigung der Ladekurve negativ }
minalt := min;
FOR Z := 1 TO 4 DO
BEGIN
IF Akku [Z].Online = TRUE THEN
BEGIN
IF Akku [Z].Proben = 0 THEN Akku [Z].Proben := 1;
Akku [Z].V_Mittel := Akku [Z].V_Summe / Akku [Z].Proben;
Akku [Z].Proben := 0;
Akku [Z].V_Summe := 0;
IF (Akku [Z].V_Mittel + 0.0001 < Akku [Z].V_Vorher) AND (Akku [Z].Entladen = FALSE) THEN
BEGIN
IF (Akku [Z].Algor = 3) AND (Akku [Z].Zyklus < 2) THEN
BEGIN
Akku [Z].Laden := FALSE;
Akku [Z].Entladen := TRUE;
INC (Akku [Z].Zyklus, 1);
Tabeintrag (Z);
END ELSE BEGIN
WITH Akku [Z] DO
BEGIN
Laden := FALSE;
Entladen := FALSE;
Online := FALSE;
Tabeintrag (Z);
END; { END von WITH }
END; { END von IF }
END; {END von IF }
Akku [Z].V_Vorher := Akku [Z].V_Mittel;
Messwert [Z] := Akku [Z].V_Mittel;
Tabeintrag (Z);
END; { END von IF }
END; { END von FOR DO }
WRITE (Mess_Daten, Messwert);
END; { END von IF }
END; { END von BEGIN }
1,2,3,4 : BEGIN
IF Akku [Zaehler].Online = TRUE THEN
BEGIN
IF (Akku [Zaehler].Algor = 1) AND (Akku [Zaehler].Laden = TRUE) AND
(Akku [Zaehler].Online = TRUE) THEN GOTO LADEN;
IF ((Akku [Zaehler].Algor = 2) OR (Akku [Zaehler].Algor = 3)) AND
(Akku [Zaehler].Entladen = TRUE) AND (Akku [Zaehler].Online = TRUE)
THEN GOTO ENTLADEN;
LADEN:
Laden_ein (Zaehler);
DELAY (200);
Laden_aus (Zaehler);
Pruef := AD_Messwert (Zaehler);
Mess1 [Zaehler] := AD_Messwert (Zaehler * 2 - 1);
Mess2 [Zaehler] := AD_Messwert (Zaehler * 2);
Tabeintrag (Zaehler);
Entladen_ein (Zaehler);
DELAY (1);
Entladen_aus (Zaehler);
GOTO EINTRAG;
ENTLADEN:
Laden_aus (Zaehler); { zur Sicherheit }
Entladen_ein (Zaehler);
Microdelay (TRUNC(Akku [Zaehler].Kap * 50));
Pruef := AD_Messwert (Zaehler);
Mess1 [Zaehler] := AD_Messwert (Zaehler * 2 - 1);
Mess2 [Zaehler] := AD_Messwert (Zaehler * 2);
Tabeintrag (Zaehler);
Entladen_aus (Zaehler);
Microdelay (TRUNC(Akku [Zaehler].Kap * 50));
EINTRAG:
Akku [Zaehler].V_summe := Akku [Zaehler].V_Summe + Mess1 [Zaehler];
Akku [Zaehler].Proben := Akku [Zaehler].Proben + 1;
END; { END von IF }
END; { END von BEGIN CASE }
END; { END von CASE OF }
{ *** SICHERHEITSTESTS *** }
IF Akku [Zaehler].Online = TRUE THEN
BEGIN
IF (Mess1 [Zaehler] < 0.4) OR (Mess1 [Zaehler] > 1.8) THEN
BEGIN
WITH Akku[Zaehler] DO
BEGIN
Online := FALSE;
Defekt := TRUE;
Laden := FALSE;
Entladen := FALSE;
Tabeintrag (Zaehler);
END;
END;
END;
IF (Akku [Zaehler].Online = TRUE) AND (Akku [Zaehler].Entladen = TRUE) AND
(Mess1 [Zaehler] < 0.8) THEN
BEGIN
Akku [Zaehler].Entladen := FALSE;
Akku [Zaehler].Laden := TRUE;
Akku [Zaehler].V_Mittel := Akku [Zaehler].V_Summe / Akku [Zaehler].Proben;
Akku [Zaehler].V_Vorher := Akku [Zaehler].V_Mittel;
Tabeintrag (Zaehler);
END;
END; { END von FOR }
{ *** Tastatur bedienen *** }
IF KEYPRESSED THEN
BEGIN
Taste := READKEY;
IF Taste = CHR (27) THEN
BEGIN
Bed_Abr := TRUE;
Programm_Ende;
GOTO START;
END;
END;
Mausstatus;
Mausx := (Mausx + 8) DIV 8;
Mausy := (Mausy + 8) DIV 8;
IF (Maust = 1) AND (Mausx > 56) AND (Mausx < 74) AND (Mausy = 22) THEN
BEGIN
Bed_Abr := TRUE;
Programm_Ende;
GOTO START;
END;
{ *** Schleife wiederholen bis kein Akku mehr Online *** }
UNTIL (Akku [1].Online = FALSE) AND (Akku [2].Online = FALSE) AND
(Akku [3].Online = FALSE) AND (Akku [4].Online = FALSE);
Programm_Ende;
GOTO START;
END.