From 7f5c144e5b6123cc03046b4e842268fc960d11df Mon Sep 17 00:00:00 2001 From: mbirth Date: Wed, 8 Dec 2004 08:45:38 +0000 Subject: [PATCH] Initial Revision --- CM2010.dfm | 717 ++++++++++++++++++++++++++++++++++++++++++++ CM2010.pas | 739 ++++++++++++++++++++++++++++++++++++++++++++++ CM2010Project.cfg | 39 +++ CM2010Project.dof | 142 +++++++++ CM2010Project.dpr | 14 + CM2010Project.ini | 63 ++++ MyCM2010_de.txt | 204 +++++++++++++ MyCM2010_en.txt | 204 +++++++++++++ 8 files changed, 2122 insertions(+) create mode 100644 CM2010.dfm create mode 100644 CM2010.pas create mode 100644 CM2010Project.cfg create mode 100644 CM2010Project.dof create mode 100644 CM2010Project.dpr create mode 100644 CM2010Project.ini create mode 100644 MyCM2010_de.txt create mode 100644 MyCM2010_en.txt diff --git a/CM2010.dfm b/CM2010.dfm new file mode 100644 index 0000000..e62276d --- /dev/null +++ b/CM2010.dfm @@ -0,0 +1,717 @@ +object Form1: TForm1 + Left = 195 + Top = 109 + Width = 716 + Height = 477 + Caption = + 'Charge Manager 2010 --- (c)2003 by Markus Birth ' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + OnClose = FormClose + OnCreate = FormCreate + PixelsPerInch = 96 + TextHeight = 13 + object Label2: TLabel + Left = 128 + Top = 0 + Width = 12 + Height = 13 + Caption = '05' + end + object Label3: TLabel + Left = 201 + Top = 1 + Width = 12 + Height = 13 + Caption = '10' + end + object Label4: TLabel + Left = 275 + Top = 0 + Width = 12 + Height = 13 + Caption = '15' + end + object Label5: TLabel + Left = 351 + Top = 0 + Width = 12 + Height = 13 + Caption = '20' + end + object Label6: TLabel + Left = 427 + Top = 0 + Width = 12 + Height = 13 + Caption = '25' + end + object Label7: TLabel + Left = 501 + Top = 1 + Width = 12 + Height = 13 + Caption = '30' + end + object Image1: TImage + Left = 8 + Top = 264 + Width = 602 + Height = 162 + end + object C1: TImage + Left = 344 + Top = 128 + Width = 17 + Height = 17 + OnClick = C1Click + end + object C2: TImage + Left = 344 + Top = 200 + Width = 17 + Height = 17 + OnClick = C2Click + end + object C3: TImage + Left = 544 + Top = 128 + Width = 17 + Height = 17 + OnClick = C3Click + end + object C4: TImage + Left = 544 + Top = 200 + Width = 17 + Height = 17 + OnClick = C4Click + end + object Label9: TLabel + Left = 8 + Top = 0 + Width = 48 + Height = 13 + Caption = 'Raw Data' + end + object Label10: TLabel + Left = 672 + Top = 259 + Width = 22 + Height = 13 + Caption = '5min' + end + object Label11: TLabel + Left = 673 + Top = 408 + Width = 23 + Height = 13 + Caption = '1sec' + end + object Label12: TLabel + Left = 671 + Top = 379 + Width = 22 + Height = 13 + Caption = '1min' + end + object Label8: TLabel + Left = 612 + Top = 259 + Width = 34 + Height = 13 + Caption = '- 1,60V' + end + object Label13: TLabel + Left = 616 + Top = 388 + Width = 22 + Height = 13 + Caption = 'secs' + end + object T_1: TLabel + Left = 344 + Top = 166 + Width = 49 + Height = 10 + Alignment = taCenter + AutoSize = False + Caption = '---------' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -8 + Font.Name = 'Small Fonts' + Font.Style = [] + ParentFont = False + end + object T_2: TLabel + Left = 344 + Top = 238 + Width = 49 + Height = 10 + Alignment = taCenter + AutoSize = False + Caption = '---------' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -8 + Font.Name = 'Small Fonts' + Font.Style = [] + ParentFont = False + end + object T_3: TLabel + Left = 544 + Top = 166 + Width = 49 + Height = 10 + Alignment = taCenter + AutoSize = False + Caption = '---------' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -8 + Font.Name = 'Small Fonts' + Font.Style = [] + ParentFont = False + end + object T_4: TLabel + Left = 544 + Top = 238 + Width = 49 + Height = 10 + Alignment = taCenter + AutoSize = False + Caption = '---------' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -8 + Font.Name = 'Small Fonts' + Font.Style = [] + ParentFont = False + end + object GraphDelayBar: TTrackBar + Left = 648 + Top = 256 + Width = 25 + Height = 169 + Ctl3D = True + Max = 299 + Orientation = trVertical + ParentCtl3D = False + PageSize = 10 + Frequency = 30 + Position = 240 + TabOrder = 22 + ThumbLength = 15 + OnChange = GraphDelayBarChange + end + object L1: TCheckBox + Left = 344 + Top = 112 + Width = 41 + Height = 17 + Caption = 'Log' + TabOrder = 17 + OnClick = L1Click + end + object COMSettings: TButton + Left = 592 + Top = 16 + Width = 113 + Height = 25 + Caption = 'COM Port Settings...' + TabOrder = 0 + OnClick = COMSettingsClick + end + object MultiButt: TButton + Left = 592 + Top = 48 + Width = 113 + Height = 25 + Caption = 'Start capturing' + TabOrder = 1 + OnClick = MultiButtClick + end + object GroupBox1: TGroupBox + Left = 8 + Top = 184 + Width = 185 + Height = 73 + Caption = 'COM Status' + TabOrder = 2 + object Label1: TLabel + Left = 30 + Top = 16 + Width = 71 + Height = 13 + Caption = 'Last character:' + end + object L_Time: TLabel + Left = 110 + Top = 16 + Width = 73 + Height = 13 + AutoSize = False + Caption = 'hh:mm:ss' + end + object ComLed1: TComLed + Left = 0 + Top = 32 + Width = 25 + Height = 25 + ComPort = ComPort + LedSignal = lsConn + Kind = lkYellowLight + end + object ComLed2: TComLed + Left = 24 + Top = 32 + Width = 25 + Height = 25 + ComPort = ComPort + LedSignal = lsCTS + Kind = lkBlueLight + end + object ComLed3: TComLed + Left = 48 + Top = 32 + Width = 25 + Height = 25 + ComPort = ComPort + LedSignal = lsDSR + Kind = lkRedLight + end + object ComLed4: TComLed + Left = 88 + Top = 32 + Width = 25 + Height = 25 + ComPort = ComPort + LedSignal = lsRing + Kind = lkPurpleLight + end + object ComLed5: TComLed + Left = 112 + Top = 32 + Width = 25 + Height = 25 + ComPort = ComPort + LedSignal = lsRLSD + Kind = lkRedLight + end + object ComLed6: TComLed + Left = 144 + Top = 32 + Width = 25 + Height = 25 + ComPort = ComPort + LedSignal = lsRx + Kind = lkGreenLight + end + object ComLed7: TComLed + Left = 160 + Top = 32 + Width = 25 + Height = 25 + ComPort = ComPort + LedSignal = lsTx + Kind = lkRedLight + end + object Label14: TLabel + Left = 150 + Top = 54 + Width = 13 + Height = 13 + Caption = 'Rx' + end + object Label15: TLabel + Left = 167 + Top = 54 + Width = 12 + Height = 13 + Caption = 'Tx' + end + object Label16: TLabel + Left = 114 + Top = 56 + Width = 21 + Height = 10 + Caption = 'RLSD' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -8 + Font.Name = 'Small Fonts' + Font.Style = [] + ParentFont = False + end + object Label17: TLabel + Left = 92 + Top = 56 + Width = 17 + Height = 10 + Caption = 'Ring' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -8 + Font.Name = 'Small Fonts' + Font.Style = [] + ParentFont = False + end + object Label18: TLabel + Left = 52 + Top = 56 + Width = 17 + Height = 10 + Caption = 'DSR' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -8 + Font.Name = 'Small Fonts' + Font.Style = [] + ParentFont = False + end + object Label19: TLabel + Left = 28 + Top = 56 + Width = 16 + Height = 10 + Caption = 'CTS' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -8 + Font.Name = 'Small Fonts' + Font.Style = [] + ParentFont = False + end + object Label20: TLabel + Left = 3 + Top = 56 + Width = 19 + Height = 10 + Caption = 'Conn' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -8 + Font.Name = 'Small Fonts' + Font.Style = [] + ParentFont = False + end + end + object Edit1: TEdit + Left = 64 + Top = 16 + Width = 521 + Height = 20 + Enabled = False + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -9 + Font.Name = 'Courier New' + Font.Style = [] + ParentFont = False + TabOrder = 3 + Text = + '01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 2' + + '2 23 24 25 26 27 28 29 30 31 32 33 34' + end + object Edit2: TEdit + Left = 64 + Top = 40 + Width = 521 + Height = 20 + Enabled = False + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -9 + Font.Name = 'Courier New' + Font.Style = [] + ParentFont = False + TabOrder = 4 + Text = + '01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 2' + + '2 23 24 25 26 27 28 29 30 31 32 33 34' + end + object Edit3: TEdit + Left = 64 + Top = 64 + Width = 521 + Height = 20 + Enabled = False + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -9 + Font.Name = 'Courier New' + Font.Style = [] + ParentFont = False + TabOrder = 5 + Text = + '01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 2' + + '2 23 24 25 26 27 28 29 30 31 32 33 34' + end + object Edit4: TEdit + Left = 64 + Top = 88 + Width = 521 + Height = 20 + Enabled = False + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -9 + Font.Name = 'Courier New' + Font.Style = [] + ParentFont = False + TabOrder = 6 + Text = + '01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 2' + + '2 23 24 25 26 27 28 29 30 31 32 33 34' + end + object R_1: TRadioButton + Left = 8 + Top = 16 + Width = 49 + Height = 17 + Caption = 'Slot 1' + Enabled = False + TabOrder = 7 + end + object R_2: TRadioButton + Left = 8 + Top = 40 + Width = 49 + Height = 17 + Caption = 'Slot 2' + Enabled = False + TabOrder = 8 + end + object R_3: TRadioButton + Left = 8 + Top = 64 + Width = 49 + Height = 17 + Caption = 'Slot 3' + Enabled = False + TabOrder = 9 + end + object R_4: TRadioButton + Left = 8 + Top = 88 + Width = 49 + Height = 17 + Caption = 'Slot 4' + Enabled = False + TabOrder = 10 + end + object StatusBar: TStatusBar + Left = 0 + Top = 431 + Width = 708 + Height = 19 + Panels = <> + SimplePanel = True + end + object D_1: TMemo + Left = 200 + Top = 112 + Width = 137 + Height = 71 + Enabled = False + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -13 + Font.Name = 'Courier New' + Font.Style = [] + Lines.Strings = ( + '1:') + ParentFont = False + ReadOnly = True + TabOrder = 11 + end + object D_2: TMemo + Left = 200 + Top = 184 + Width = 137 + Height = 71 + Enabled = False + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -13 + Font.Name = 'Courier New' + Font.Style = [] + Lines.Strings = ( + '2:') + ParentFont = False + ReadOnly = True + TabOrder = 12 + end + object D_3: TMemo + Left = 400 + Top = 112 + Width = 137 + Height = 71 + Enabled = False + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -13 + Font.Name = 'Courier New' + Font.Style = [] + Lines.Strings = ( + '3:') + ParentFont = False + ReadOnly = True + TabOrder = 13 + end + object D_4: TMemo + Left = 400 + Top = 184 + Width = 137 + Height = 71 + Enabled = False + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -13 + Font.Name = 'Courier New' + Font.Style = [] + Lines.Strings = ( + '4:') + ParentFont = False + ReadOnly = True + TabOrder = 14 + end + object D_Stat: TMemo + Left = 8 + Top = 112 + Width = 137 + Height = 71 + Color = clLime + Ctl3D = True + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -13 + Font.Name = 'Courier New' + Font.Style = [] + Lines.Strings = ( + ' CHARGE MANAGER' + '================' + '1:--- 3:---' + '2:--- 4:---') + ParentCtl3D = False + ParentFont = False + ReadOnly = True + TabOrder = 15 + end + object LogButton: TButton + Left = 592 + Top = 80 + Width = 113 + Height = 25 + Caption = 'Start logging' + TabOrder = 16 + OnClick = LogButtonClick + end + object L2: TCheckBox + Left = 344 + Top = 184 + Width = 41 + Height = 17 + Caption = 'Log' + TabOrder = 18 + OnClick = L2Click + end + object L3: TCheckBox + Left = 544 + Top = 112 + Width = 41 + Height = 17 + Caption = 'Log' + TabOrder = 19 + OnClick = L3Click + end + object L4: TCheckBox + Left = 544 + Top = 184 + Width = 41 + Height = 17 + Caption = 'Log' + TabOrder = 20 + OnClick = L4Click + end + object GraphDelayCtrl: TEdit + Left = 616 + Top = 400 + Width = 25 + Height = 21 + TabOrder = 23 + Text = '60' + OnChange = GraphDelayCtrlChange + OnKeyDown = GraphDelayCtrlKeyDown + end + object PB_1: TProgressBar + Left = 344 + Top = 176 + Width = 49 + Height = 8 + Smooth = True + TabOrder = 24 + end + object PB_2: TProgressBar + Left = 344 + Top = 248 + Width = 49 + Height = 8 + Smooth = True + TabOrder = 25 + end + object PB_3: TProgressBar + Left = 544 + Top = 176 + Width = 49 + Height = 8 + Smooth = True + TabOrder = 26 + end + object PB_4: TProgressBar + Left = 544 + Top = 248 + Width = 49 + Height = 8 + Smooth = True + TabOrder = 27 + end + object ColorDialog: TColorDialog + Left = 664 + Top = 112 + end + object DelayTimer: TTimer + Enabled = False + Interval = 5000 + OnTimer = DelayTimerTimer + Left = 664 + Top = 160 + end + object ComPort: TComPort + BaudRate = br9600 + Port = 'COM1' + Parity.Bits = prNone + StopBits = sbOneStopBit + DataBits = dbEight + Events = [evRxChar, evTxEmpty, evRxFlag, evRing, evBreak, evCTS, evDSR, evError, evRLSD, evRx80Full] + FlowControl.OutCTSFlow = False + FlowControl.OutDSRFlow = False + FlowControl.ControlDTR = dtrDisable + FlowControl.ControlRTS = rtsDisable + FlowControl.XonXoffOut = False + FlowControl.XonXoffIn = False + OnAfterOpen = ComPortAfterOpen + OnAfterClose = ComPortAfterClose + OnRxChar = ComPortRxChar + OnRxFlag = ComPortRxFlag + Left = 160 + Top = 120 + end +end diff --git a/CM2010.pas b/CM2010.pas new file mode 100644 index 0000000..e1d4d60 --- /dev/null +++ b/CM2010.pas @@ -0,0 +1,739 @@ +unit CM2010; + +interface + +uses + Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, + Dialogs, ExtCtrls, StdCtrls, CPort, ComCtrls, IniFiles; + +type + TForm1 = class(TForm) + ComPort: TComPort; + COMSettings: TButton; + MultiButt: TButton; + GroupBox1: TGroupBox; + L_CTS: TLabel; + L_DSR: TLabel; + L_RLSD: TLabel; + Label1: TLabel; + L_Time: TLabel; + Edit1: TEdit; + Edit2: TEdit; + Edit3: TEdit; + Edit4: TEdit; + R_1: TRadioButton; + R_2: TRadioButton; + R_3: TRadioButton; + R_4: TRadioButton; + StatusBar: TStatusBar; + D_1: TMemo; + D_2: TMemo; + D_3: TMemo; + D_4: TMemo; + Label2: TLabel; + Label3: TLabel; + Label4: TLabel; + Label5: TLabel; + Label6: TLabel; + Label7: TLabel; + D_Stat: TMemo; + LogButton: TButton; + Image1: TImage; + Label8: TLabel; + L1: TCheckBox; + L2: TCheckBox; + L3: TCheckBox; + L4: TCheckBox; + ColorDialog: TColorDialog; + C1: TImage; + C2: TImage; + C3: TImage; + C4: TImage; + Label9: TLabel; + GraphDelayBar: TTrackBar; + Label10: TLabel; + Label11: TLabel; + Label12: TLabel; + GraphDelayCtrl: TEdit; + Label13: TLabel; + DelayTimer: TTimer; + procedure COMSettingsClick(Sender: TObject); + procedure MultiButtClick(Sender: TObject); + procedure ComPortOpen(Sender: TObject); + procedure ComPortClose(Sender: TObject); + procedure ComPortRxChar(Sender: TObject; Count: Integer); + procedure ComPortCTSChange(Sender: TObject; OnOff: Boolean); + procedure ComPortDSRChange(Sender: TObject; OnOff: Boolean); + procedure ComPortRLSDChange(Sender: TObject; OnOff: Boolean); + procedure ComPortRxFlag(Sender: TObject); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure FormCreate(Sender: TObject); + procedure LogButtonClick(Sender: TObject); + procedure C1Click(Sender: TObject); + procedure C2Click(Sender: TObject); + procedure C3Click(Sender: TObject); + procedure C4Click(Sender: TObject); + procedure L1Click(Sender: TObject); + procedure L2Click(Sender: TObject); + procedure L3Click(Sender: TObject); + procedure L4Click(Sender: TObject); + procedure GraphDelayBarChange(Sender: TObject); + procedure DelayTimerTimer(Sender: TObject); + procedure GraphDelayCtrlChange(Sender: TObject); + procedure GraphDelayCtrlKeyDown(Sender: TObject; var Key: Word; + Shift: TShiftState); + private + { Private declarations } + public + { Public declarations } + end; + +var + Form1: TForm1; + +implementation + +{$R *.dfm} + +const + CRLF: string = Chr(13) + Chr(10); + +var + Slot: array[1..4] of String[34]; + GraphPos: array[1..4,1..2] of byte; + GraphCol: array[1..4] of TColor; + GraphDelay: integer = 60; + GraphTime: integer; + Sync: String[136] = ''; + InSync: boolean = true; + LSlot: byte = 1; + Logging: boolean = false; + LastEvent: TDateTime = 0; + +procedure TForm1.COMSettingsClick(Sender: TObject); +begin + ComPort.ShowSetupDialog; +end; + +procedure TForm1.MultiButtClick(Sender: TObject); +begin + if ComPort.Connected then + ComPort.Close + else + ComPort.Open; +end; + +procedure TForm1.ComPortOpen(Sender: TObject); +begin + MultiButt.Caption := 'Stop capturing'; +end; + +procedure TForm1.ComPortClose(Sender: TObject); +var i: integer; +begin + InSync := true; + Sync := ''; + LSlot := 1; + for i:=1 to 4 do Slot[i] := ''; + MultiButt.Caption := 'Start capturing'; +end; + +function ShowHex(x: byte): string; +const hset: string = '0123456789abcdef'; +begin + ShowHex := hset[(x DIV 16)+1]+hset[(x MOD 16)+1]; +end; + +function BuildHex(x: string): string; +var i: integer; + t: string; +begin + t := ''; + for i:=1 to Length(x) do t := t + ShowHex(Ord(x[i])) + ' '; + BuildHex := t; +end; + +function GetVolts(s: byte): word; +begin + GetVolts := Ord(Slot[s][16])*256+Ord(Slot[s][17]); +end; + +function GetAmps(s: byte): word; +begin + GetAmps := Ord(Slot[s][14])*256+Ord(Slot[s][15]); +end; + +function GetCCap(s: byte): dword; +begin + GetCCap := Ord(Slot[s][18])*65536+Ord(Slot[s][19])*256+Ord(Slot[s][20]); +end; + +function GetDCap(s: byte): dword; +begin + GetDCap := Ord(Slot[s][21])*65536+Ord(Slot[s][22])*256+Ord(Slot[s][23]); +end; + +function GetHours(s: byte): byte; +begin + GetHours := Ord(Slot[s][6]); +end; + +function GetMinutes(s: byte): byte; +begin + GetMinutes := Ord(Slot[s][7]); +end; + +function FormatCaps(c: dword): string; +var t: string; +begin + t := IntToStr(c); + if (c<=100000) then t := Copy(t,1,Length(t)-2) + '.' + Copy(t,Length(t)-1,1) else t := Copy(t,1,Length(t)-2); + if t[1]='.' then t := '0' + t; + while Length(t)<5 do t := ' '+t; + FormatCaps := t; +end; + +function FormatTime(s: byte): string; +var t: string; +begin + if (ShowHex(Ord(Slot[s][2]))[2]<>'0') then begin + if GetHours(s)<10 then t := '0' + IntToStr(GetHours(s)) + ':' else t := IntToStr(GetHours(s)) + ':'; + if GetMinutes(s)<10 then t := t + '0' + IntToStr(GetMinutes(s)) else t := t + IntToStr(GetMinutes(s)); + end else t := '--:--'; + FormatTime := t; +end; + +function FormatUI(v: dword): string; +var t: string; +begin + if v>0 then begin + t := IntToStr(v); + while Length(t)<4 do t := '0' + t; + t := Copy(t,1,Length(t)-3) + '.' + Copy(t,Length(t)-2,2); + if t[1]='.' then t := '0' + t; + end else t := '----'; + while Length(t)<7 do t := ' '+t; + FormatUI := t; +end; + +function GetAutoMan(s: byte): string; +begin + if ShowHex(Ord(Slot[s][2]))[2]<>'0' then begin + if ShowHex(Ord(Slot[s][3]))[1]='0' then GetAutoMan := 'AUTO' else GetAutoMan := 'MAN '; + end else GetAutoMan := '----'; +end; + +function GetTriAction(s: byte): string; +begin + case ShowHex(Ord(Slot[s][2]))[2] of + '0': GetTriAction := '---'; + '8': GetTriAction := 'CHA'; + '9': GetTriAction := 'DIS'; + 'a': GetTriAction := 'CHK'; + 'b': GetTriAction := 'CYC'; + 'c': GetTriAction := 'ALV'; + 'd': GetTriAction := 'RDY'; + 'e': GetTriAction := 'ERR'; + 'f': GetTriAction := 'TRI'; + else + GetTriAction := '???'; + end; +end; + +procedure LoadSettings; +var cf: TIniFile; +begin + try + cf := TIniFile.Create(ChangeFileExt(Application.ExeName,'.ini')); + Form1.AlphaBlendValue := cf.ReadInteger('Window','AlphaValue',255); + Form1.AlphaBlend := cf.ReadBool('Window','AlphaBlend',false); + + Form1.ComPort.Port := TPortType(cf.ReadInteger('Communication','Port',0)-1); + Form1.ComPort.BaudRate := TBaudRate(cf.ReadInteger('Communication','BaudRate',6)); + Form1.ComPort.DataBits := TDataBits(cf.ReadInteger('Communication','DataBits',3)); + Form1.ComPort.StopBits := TStopBits(cf.ReadInteger('Communication','StopBits',0)); + Form1.ComPort.Parity.Bits := TParityBits(cf.ReadInteger('Communication','Parity.Bits',0)); + Form1.ComPort.Parity.Check := cf.ReadBool('Communication','Parity.Check',false); + Form1.ComPort.Parity.Replace := cf.ReadBool('Communication','Parity.Replace',false); + Form1.ComPort.Parity.ReplaceChar := cf.ReadInteger('Communication','Parity.ReplaceChar',0); + Form1.ComPort.FlowControl.ControlDTR := TDTRFlowControl(cf.ReadInteger('Communication','FlowControl.DTR',1)); + Form1.ComPort.FlowControl.ControlRTS := TRTSFlowControl(cf.ReadInteger('Communication','FlowControl.RTS',0)); + Form1.ComPort.FlowControl.DSRSensitivity := cf.ReadBool('Communication','FlowControl.DSRSensitivity',false); + Form1.ComPort.FlowControl.OutCTSFlow := cf.ReadBool('Communication','FlowControl.OutCTSFlow',false); + Form1.ComPort.FlowControl.OutDSRFlow := cf.ReadBool('Communication','FlowControl.OutDSRFlow',false); + Form1.ComPort.FlowControl.TxContinueOnXoff := cf.ReadBool('Communication','FlowControl.TxContinueOnXoff',false); + Form1.ComPort.FlowControl.XoffChar := cf.ReadInteger('Communication','FlowControl.XoffChar',19); + Form1.ComPort.FlowControl.XonChar := cf.ReadInteger('Communication','FlowControl.XonChar',17); + Form1.ComPort.FlowControl.XonXoffIn := cf.ReadBool('Communication','FlowControl.XonXoffIn',false); + Form1.ComPort.FlowControl.XonXoffOut := cf.ReadBool('Communication','FlowControl.XonXoffOut',false); + + GraphDelay := cf.ReadInteger('Slots','GraphDelay',60); + Form1.GraphDelayBar.Position := 300-GraphDelay; + Form1.GraphDelayCtrl.Text := IntToStr(GraphDelay); + GraphCol[1] := TColor(cf.ReadInteger('Slots','1.Color',16711680)); + GraphCol[2] := TColor(cf.ReadInteger('Slots','2.Color',255)); + GraphCol[3] := TColor(cf.ReadInteger('Slots','3.Color',32768)); + GraphCol[4] := TColor(cf.ReadInteger('Slots','4.Color',16711935)); + + { TODO : Load settings on startup from INI-file } + cf.Free; + except + on E: Exception do ShowMessage('ERROR: Could not read settings from ini-file!'+CRLF+'('+E.Message+')'); + end; +end; + +procedure SaveSettings; +var cf: TIniFile; +begin + try + cf := TIniFile.Create(ChangeFileExt(Application.ExeName,'.ini')); + cf.WriteInteger('Communication','Port',Ord(Form1.ComPort.Port)+1); + cf.WriteInteger('Communication','BaudRate',Ord(Form1.ComPort.BaudRate)); + cf.WriteInteger('Communication','DataBits',Ord(Form1.ComPort.DataBits)); + cf.WriteInteger('Communication','StopBits',Ord(Form1.ComPort.StopBits)); + cf.WriteInteger('Communication','Parity.Bits',Ord(Form1.ComPort.Parity.Bits)); + cf.WriteBool('Communication','Parity.Check',Form1.ComPort.Parity.Check); + cf.WriteBool('Communication','Parity.Replace',Form1.ComPort.Parity.Replace); + cf.WriteInteger('Communication','Parity.ReplaceChar',Form1.ComPort.Parity.ReplaceChar); + cf.WriteInteger('Communication','FlowControl.DTR',Ord(Form1.ComPort.FlowControl.ControlDTR)); + cf.WriteInteger('Communication','FlowControl.RTS',Ord(Form1.ComPort.FlowControl.ControlRTS)); + cf.WriteBool('Communication','FlowControl.DSRSensitivity',Form1.ComPort.FlowControl.DSRSensitivity); + cf.WriteBool('Communication','FlowControl.OutCTSFlow',Form1.ComPort.FlowControl.OutCTSFlow); + cf.WriteBool('Communication','FlowControl.OutDSRFlow',Form1.ComPort.FlowControl.OutDSRFlow); + cf.WriteBool('Communication','FlowControl.TxContinueOnXoff',Form1.ComPort.FlowControl.TxContinueOnXoff); + cf.WriteInteger('Communication','FlowControl.XoffChar',Form1.ComPort.FlowControl.XoffChar); + cf.WriteInteger('Communication','FlowControl.XonChar',Form1.ComPort.FlowControl.XonChar); + cf.WriteBool('Communication','FlowControl.XonXoffIn',Form1.ComPort.FlowControl.XonXoffIn); + cf.WriteBool('Communication','FlowControl.XonXoffOut',Form1.ComPort.FlowControl.XonXoffOut); + + cf.WriteInteger('Slots','GraphDelay',GraphDelay); + cf.WriteInteger('Slots','1.Color',Ord(GraphCol[1])); + cf.WriteInteger('Slots','2.Color',Ord(GraphCol[2])); + cf.WriteInteger('Slots','3.Color',Ord(GraphCol[3])); + cf.WriteInteger('Slots','4.Color',Ord(GraphCol[4])); + + { TODO : Save settings to INI-file } + cf.Free; + except + on E: Exception do ShowMessage('ERROR: Could not write settings to ini-file!'+CRLF+'('+E.Message+')'); + end; +end; + +procedure DoStatDisp(m: TMemo); +var t: string; +begin + t := ' CHARGE MANAGER ' + CRLF; + t := t + '================' + CRLF; + t := t + '1:' + GetTriAction(1) + ' 3:' + GetTriAction(3) + CRLF; + t := t + '2:' + GetTriAction(2) + ' 4:' + GetTriAction(4); + if (t<>m.Text) then m.Text := t; +end; + +procedure DoValDisp(s: byte; m: TMemo); +var b3,c,d: char; +var t: string; +begin + b3 := ShowHex(Ord(Slot[s][3]))[2]; + c := ' '; + d := ' '; + case b3 of + '1','3','5','7': c := '»'; + '2','4','6': d := '»'; + end; + t := IntToStr(s) + ':' + GetTriAction(s) + c + 'C=' + FormatCaps(GetCCap(s)) + 'mAh' + CRLF; + t := t + GetAutoMan(s) + ' ' + d + 'D=' + FormatCaps(GetDCap(s)) + 'mAh' + CRLF; + t := t + ' U=' + FormatUI(GetVolts(s)) + 'V' + CRLF; + t := t + FormatTime(s) + ' I=' + FormatUI(GetAmps(s)) + 'A'; + if (t<>m.Text) then m.Text := t; +end; + +procedure DoEmptyDisp(s: byte; m: TMemo); +var t: string; +begin + t := IntToStr(s) + ':'; + if (m.Text<>t) then m.Text := t; +end; + +procedure DoAccuSettings(s: byte; m: TMemo; w1, w2: string); +var t: string; +begin + t := ' ACCU- SETTINGS ' + CRLF; + t := t + '================' + CRLF; + t := t + IntToStr(s) + ': ' + w1 + CRLF; + t := t + w2; + if (m.Text<>t) then m.Text := t; +end; + +procedure DoDisplay(s: byte; m: TMemo); +var b2,b3,b4: string[2]; +begin + b2 := ShowHex(Ord(Slot[s][2])); + b3 := ShowHex(Ord(Slot[s][3])); + b4 := ShowHex(Ord(Slot[s][4])); + if (b2+b3='0000') then begin + DoEmptyDisp(s, m); + m.Enabled := false; + end else if (b2+b3='0100') then begin + DoAccuSettings(s, m, 'SET AUTO/MAN', ' » AUTOMATIC'); + m.Enabled := true; + end else if (b2+b3='0200') then begin + DoAccuSettings(s, m, 'SET AUTO/MAN', ' » MANUAL'); + m.Enabled := true; + end else if (b2+b3='0210') then begin + DoAccuSettings(s, m, 'SET CAPACITY','» 100- 200 mAh'); + m.Enabled := true; + end else if (b2+b3='0220') then begin + DoAccuSettings(s, m, 'SET CAPACITY','» 200- 350 mAh'); + m.Enabled := true; + end else if (b2+b3='0230') then begin + DoAccuSettings(s, m, 'SET CAPACITY','» 350- 600 mAh'); + m.Enabled := true; + end else if (b2+b3='0240') then begin + DoAccuSettings(s, m, 'SET CAPACITY','» 600- 900 mAh'); + m.Enabled := true; + end else if (b2+b3='0250') then begin + DoAccuSettings(s, m, 'SET CAPACITY','» 900- 1200 mAh'); + m.Enabled := true; + end else if (b2+b3='0260') then begin + DoAccuSettings(s, m, 'SET CAPACITY','» 1200- 1500 mAh'); + m.Enabled := true; + end else if (b2+b3='0270') then begin + DoAccuSettings(s, m, 'SET CAPACITY','» 1500- 2200 mAh'); + m.Enabled := true; + end else if (b2+b3='0280') then begin + DoAccuSettings(s, m, 'SET CAPACITY','» 2200- ... mAh'); + m.Enabled := true; + end else if (b2='03') then begin + DoAccuSettings(s, m, 'SET PROGRAM', ' » CHARGE'); + m.Enabled := true + end else if (b2='04') then begin + DoAccuSettings(s, m, 'SET PROGRAM', ' » DISCHARGE'); + m.Enabled := true + end else if (b2='05') then begin + DoAccuSettings(s, m, 'SET PROGRAM', ' » CHECK'); + m.Enabled := true + end else if (b2='06') then begin + DoAccuSettings(s, m, 'SET PROGRAM', ' » CYCLE'); + m.Enabled := true + end else if (b2='07') then begin + DoAccuSettings(s, m, 'SET PROGRAM', ' » ALIVE'); + m.Enabled := true + end else begin + DoValDisp(s, m); + m.Enabled := true; + end; +end; + +procedure GraphClear(Image: TImage); +const linespace: integer = 50; // horizontal helping lines (50 = 0,5V) + minspace: integer = 30; // vertical helping lines (30 = 30min) +var GH, GW, i: integer; +begin + GH := Image.Height - 2; + GW := Image.Width - 2; + Image.Canvas.Brush.Color := clWindow; + Image.Canvas.Brush.Style := bsSolid; + Image.Canvas.Pen.Color := clBlack; + Image.Canvas.FillRect(Rect(0,0,Image.Width,Image.Height)); + Image.Canvas.Rectangle(0,0,Image.Width,Image.Height); + Image.Canvas.Pen.Color := clSilver; + for i:=1 to (GH DIV linespace) do begin + Image.Canvas.MoveTo(1,1+GH-linespace*i); + Image.Canvas.LineTo(GW+1,1+GH-linespace*i); + end; + for i:=1 to (GW DIV minspace) do begin + Image.Canvas.MoveTo(minspace*i,1); + Image.Canvas.LineTo(minspace*i,GH+1); + end; +end; + +procedure PaintGraph(Image: TImage; Slot: integer); +var t: string; + y: integer; + GW, GH: integer; +begin + GW := Image.Width - 2; + GH := Image.Height - 2; + if Slot=1 then begin + Image.Canvas.CopyRect(Rect(1,1,GW,GH+1),Image.Canvas,Rect(2,1,GW+1,GH+1)); + Image.Canvas.Pen.Color := clWindow; + Image.Canvas.Brush.Color := clWindow; + Image.Canvas.Brush.Style := bsSolid; + Image.Canvas.FillRect(Rect(GW,1,GW+1,GH+1)); + Image.Canvas.Pixels[GW,GH+1-50] := clSilver; // 0,5V-Mark + Image.Canvas.Pixels[GW,GH+1-100] := clSilver; // 1,0V-Mark + Image.Canvas.Pixels[GW,GH+1-150] := clSilver; // 1,5V-Mark + end; + Image.Canvas.Pen.Color := GraphCol[Slot]; + if Abs(GraphPos[Slot,1]-GraphPos[Slot,2])>=50 then begin + Image.Canvas.Font.Name := 'Small Fonts'; + Image.Canvas.Font.Size := 7; + Image.Canvas.Font.Color := GraphCol[Slot]; + t := TimeToStr(time); + y := GraphPos[Slot,2]-Image.Canvas.TextHeight(t) DIV 2; + if y>Image.Height-Image.Canvas.TextHeight(t)-1 then y := Image.Height-Image.Canvas.TextHeight(t)-1; + Image.Canvas.TextOut(GW-2-Image.Canvas.TextWidth(t),y,t); + end; + if (GraphPos[Slot,1]t1 then r := t2-t1 else r := t1-t2; + result := Trunc(r * 86400000); +end; + +procedure TForm1.ComPortRxChar(Sender: TObject; Count: Integer); +var str: string; + i: integer; +begin + if MSBetween(now, LastEvent)>400 then begin + StatusBar.SimpleText := 'Signal timed out. Resynching'; + LastEvent := now; + InSync := true; + end; + ComPort.ReadStr(str, Count); + for i:=1 to Count do begin + if InSync then begin + if Length(Sync)=0 then StatusBar.SimpleText := 'Waiting for SyncBuffer to fill'; + if Length(Sync)<136 then begin + Sync := Sync + str[i]; + StatusBar.SimpleText := StatusBar.SimpleText + '.'; + end else begin + if StatusBar.SimpleText[1]<>'S' then StatusBar.SimpleText := 'Synchronizing'; + Sync := Copy(Sync,2,Length(Sync)) + Str[i]; + StatusBar.SimpleText := StatusBar.SimpleText + '.'; + if (Ord(Sync[1])=1) AND (Ord(Sync[35])=2) AND (Ord(Sync[69])=3) AND (Ord(Sync[103])=4) then begin + StatusBar.SimpleText := StatusBar.SimpleText + 'done.'; + InSync := false; + LSlot := 1; + R_1.Checked := true; + end; + end; + end else begin + if Length(Slot[LSlot])>=34 then Slot[LSlot] := ''; + Slot[LSlot] := Slot[LSlot] + Str[i]; + if Length(Slot[LSlot])>=34 then begin + case LSlot of + 1: R_1.Checked := false; + 2: R_2.Checked := false; + 3: R_3.Checked := false; + 4: R_4.Checked := false; + end; + if (Ord(Slot[LSlot][1])<>LSlot) then begin + StatusBar.SimpleText := 'Synchronization lost. Resynching'; + InSync := true; + LastEvent := now; +// Sync := ''; + end; + Inc(LSlot); + if LSlot>4 then LSlot := 1; + case LSlot of + 1: R_1.Checked := true; + 2: R_2.Checked := true; + 3: R_3.Checked := true; + 4: R_4.Checked := true; + end; + if (LSlot=1) AND (GraphTime>=GraphDelay) then begin + DoGraphDisp(Image1, 1); + DoGraphDisp(Image1, 2); + DoGraphDisp(Image1, 3); + DoGraphDisp(Image1, 4); + GraphTime := 0; + end; + if (LSlot=1) then Inc(GraphTime); + end; + end; + Edit1.Text := BuildHex(Slot[1]); + DoDisplay(1, D_1); + Edit2.Text := BuildHex(Slot[2]); + DoDisplay(2, D_2); + Edit3.Text := BuildHex(Slot[3]); + DoDisplay(3, D_3); + Edit4.Text := BuildHex(Slot[4]); + DoDisplay(4, D_4); + DoStatDisp(D_Stat); + end; +end; + +procedure TForm1.ComPortCTSChange(Sender: TObject; OnOff: Boolean); +begin + L_CTS.Enabled := OnOff; +end; + +procedure TForm1.ComPortDSRChange(Sender: TObject; OnOff: Boolean); +begin + L_DSR.Enabled := OnOff; +end; + +procedure TForm1.ComPortRLSDChange(Sender: TObject; OnOff: Boolean); +begin + L_RLSD.Enabled := OnOff; +end; + +procedure TForm1.ComPortRxFlag(Sender: TObject); +begin + L_Time.Caption := TimeToStr(time); + LastEvent := now; +end; + +procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); +begin + SaveSettings; +end; + +procedure UpdateColors; +begin + Form1.C1.Canvas.Brush.Color := GraphCol[1]; + Form1.C1.Canvas.Brush.Style := bsSolid; + Form1.C1.Canvas.FillRect(Rect(0,0,100,100)); + + Form1.C2.Canvas.Brush.Color := GraphCol[2]; + Form1.C2.Canvas.Brush.Style := bsSolid; + Form1.C2.Canvas.FillRect(Rect(0,0,100,100)); + + Form1.C3.Canvas.Brush.Color := GraphCol[3]; + Form1.C3.Canvas.Brush.Style := bsSolid; + Form1.C3.Canvas.FillRect(Rect(0,0,100,100)); + + Form1.C4.Canvas.Brush.Color := GraphCol[4]; + Form1.C4.Canvas.Brush.Style := bsSolid; + Form1.C4.Canvas.FillRect(Rect(0,0,100,100)); +end; + +procedure TForm1.FormCreate(Sender: TObject); +var i: integer; +begin + LoadSettings; + UpdateColors; + GraphClear(Image1); + GraphTime := GraphDelay; + for i:=1 to 4 do begin + GraphPos[i,1] := Image1.Height - 2; + GraphPos[i,2] := Image1.Height - 2; + end; +end; + +procedure TForm1.LogButtonClick(Sender: TObject); +begin + if (NOT L1.Checked) AND (NOT L2.Checked) AND (NOT L3.Checked) AND (NOT L4.Checked) then begin + L1.Checked := true; + L2.Checked := true; + L3.Checked := true; + L4.Checked := true; + LogButton.Caption := 'Stop logging'; + end else begin + L1.Checked := false; + L2.Checked := false; + L3.Checked := false; + L4.Checked := false; + LogButton.Caption := 'Start logging'; + end; +end; + +procedure TForm1.C1Click(Sender: TObject); +begin + ColorDialog.Color := GraphCol[1]; + ColorDialog.Execute; + GraphCol[1] := ColorDialog.Color; + UpdateColors; +end; + +procedure TForm1.C2Click(Sender: TObject); +begin + ColorDialog.Color := GraphCol[2]; + ColorDialog.Execute; + GraphCol[2] := ColorDialog.Color; + UpdateColors; +end; + +procedure TForm1.C3Click(Sender: TObject); +begin + ColorDialog.Color := GraphCol[3]; + ColorDialog.Execute; + GraphCol[3] := ColorDialog.Color; + UpdateColors; +end; + +procedure TForm1.C4Click(Sender: TObject); +begin + ColorDialog.Color := GraphCol[4]; + ColorDialog.Execute; + GraphCol[4] := ColorDialog.Color; + UpdateColors; +end; + +procedure StartStopCheck; +begin + if (Form1.L1.Checked) OR (Form1.L2.Checked) OR (Form1.L3.Checked) OR (Form1.L4.Checked) then + Form1.LogButton.Caption := 'Stop logging' + else + Form1.LogButton.Caption := 'Start logging'; +end; + +procedure TForm1.L1Click(Sender: TObject); +begin + StartStopCheck; +end; + +procedure TForm1.L2Click(Sender: TObject); +begin + StartStopCheck; +end; + +procedure TForm1.L3Click(Sender: TObject); +begin + StartStopCheck; +end; + +procedure TForm1.L4Click(Sender: TObject); +begin + StartStopCheck; +end; + +procedure TForm1.GraphDelayBarChange(Sender: TObject); +begin + GraphDelay := 300-GraphDelayBar.Position; + GraphDelayCtrl.Text := IntToStr(GraphDelay); +end; + +procedure TForm1.DelayTimerTimer(Sender: TObject); +begin + GraphDelayCtrl.Text := IntToStr(300-GraphDelayBar.Position); +end; + +procedure TForm1.GraphDelayCtrlChange(Sender: TObject); +begin + DelayTimer.Enabled := false; + DelayTimer.Enabled := true; +end; + +procedure TForm1.GraphDelayCtrlKeyDown(Sender: TObject; var Key: Word; + Shift: TShiftState); +var x: integer; +begin + if (Key=VK_RETURN) then begin + try + x := StrToInt(GraphDelayCtrl.Text); + except + GraphDelayCtrl.Text := '##'; + x := 300-GraphDelayBar.Position; + end; + if (x>0) then GraphDelayBar.Position := 300-x else GraphDelayCtrl.Text := '##'; + end; +end; + +end. + diff --git a/CM2010Project.cfg b/CM2010Project.cfg new file mode 100644 index 0000000..33a8769 --- /dev/null +++ b/CM2010Project.cfg @@ -0,0 +1,39 @@ +-$A8 +-$B- +-$C+ +-$D+ +-$E- +-$F- +-$G+ +-$H+ +-$I+ +-$J- +-$K- +-$L+ +-$M- +-$N+ +-$O+ +-$P+ +-$Q- +-$R- +-$S- +-$T- +-$U- +-$V+ +-$W- +-$X+ +-$YD +-$Z1 +-cg +-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +-H+ +-W+ +-M +-$M16384,1048576 +-K$00400000 +-LE"c:\program files\borland\delphi7\Projects\Bpl" +-LN"c:\program files\borland\delphi7\Projects\Bpl" +-LUdesignide;vcl;rtl;vclx;vclactnband +-w-UNSAFE_TYPE +-w-UNSAFE_CODE +-w-UNSAFE_CAST diff --git a/CM2010Project.dof b/CM2010Project.dof new file mode 100644 index 0000000..d82ea1f --- /dev/null +++ b/CM2010Project.dof @@ -0,0 +1,142 @@ +[FileVersion] +Version=7.0 +[Compiler] +A=8 +B=0 +C=1 +D=1 +E=0 +F=0 +G=1 +H=1 +I=1 +J=0 +K=0 +L=1 +M=0 +N=1 +O=1 +P=1 +Q=0 +R=0 +S=0 +T=0 +U=0 +V=1 +W=0 +X=1 +Y=1 +Z=1 +ShowHints=1 +ShowWarnings=1 +UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +NamespacePrefix= +SymbolDeprecated=1 +SymbolLibrary=1 +SymbolPlatform=1 +UnitLibrary=1 +UnitPlatform=1 +UnitDeprecated=1 +HResultCompat=1 +HidingMember=1 +HiddenVirtual=1 +Garbage=1 +BoundsError=1 +ZeroNilCompat=1 +StringConstTruncated=1 +ForLoopVarVarPar=1 +TypedConstVarPar=1 +AsgToTypedConst=1 +CaseLabelRange=1 +ForVariable=1 +ConstructingAbstract=1 +ComparisonFalse=1 +ComparisonTrue=1 +ComparingSignedUnsigned=1 +CombiningSignedUnsigned=1 +UnsupportedConstruct=1 +FileOpen=1 +FileOpenUnitSrc=1 +BadGlobalSymbol=1 +DuplicateConstructorDestructor=1 +InvalidDirective=1 +PackageNoLink=1 +PackageThreadVar=1 +ImplicitImport=1 +HPPEMITIgnored=1 +NoRetVal=1 +UseBeforeDef=1 +ForLoopVarUndef=1 +UnitNameMismatch=1 +NoCFGFileFound=1 +MessageDirective=1 +ImplicitVariants=1 +UnicodeToLocale=1 +LocaleToUnicode=1 +ImagebaseMultiple=1 +SuspiciousTypecast=1 +PrivatePropAccessor=1 +UnsafeType=0 +UnsafeCode=0 +UnsafeCast=0 +[Linker] +MapFile=0 +OutputObjs=0 +ConsoleApp=1 +DebugInfo=0 +RemoteSymbols=0 +MinStackSize=16384 +MaxStackSize=1048576 +ImageBase=4194304 +ExeDescription=CM2010 Project +[Directories] +OutputDir= +UnitOutputDir= +PackageDLLOutputDir= +PackageDCPOutputDir= +SearchPath= +Packages=designide;vcl;rtl;vclx;vclactnband +Conditionals= +DebugSourceDirs= +UsePackages=1 +[Parameters] +RunParams= +HostApplication= +Launcher= +UseLauncher=0 +DebugCWD= +[Language] +ActiveLang= +ProjectLang= +RootDir= +[Version Info] +IncludeVerInfo=1 +AutoIncBuild=1 +MajorVer=1 +MinorVer=0 +Release=0 +Build=4 +Debug=0 +PreRelease=1 +Special=0 +Private=0 +DLL=0 +Locale=1033 +CodePage=1252 +[Version Info Keys] +CompanyName=Markus Birth +FileDescription= +FileVersion=1.0.0.4 +InternalName=CM2010 +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= +[Excluded Packages] +c:\program files\borland\delphi7\Bin\dclsmpedit70.bpl=Borland Editor Script Enhancements +c:\program files\borland\delphi7\Bin\dclemacsedit70.bpl=Borland Editor Emacs Enhancements +[HistoryLists\hlUnitAliases] +Count=1 +Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; diff --git a/CM2010Project.dpr b/CM2010Project.dpr new file mode 100644 index 0000000..76c6f04 --- /dev/null +++ b/CM2010Project.dpr @@ -0,0 +1,14 @@ +program CM2010Project; + +uses + Forms, + CM2010 in 'CM2010.pas' {Form1}; + +{$R *.res} + +begin + Application.Initialize; + Application.Title := 'Charge Manager 2010 --- (c)2003 by Markus Birth'; + Application.CreateForm(TForm1, Form1); + Application.Run; +end. diff --git a/CM2010Project.ini b/CM2010Project.ini new file mode 100644 index 0000000..bd2b902 --- /dev/null +++ b/CM2010Project.ini @@ -0,0 +1,63 @@ +[Window] +AlphaBlend=1 +AlphaValue=222 + +[Communication] +Port=COM1 +BaudRate=9600 +DataBits=8 +StopBits=1 +Parity=None +Parity.Check=0 +Parity.Replace=0 +Parity.ReplaceChar=0 +FlowControl=None +FlowControl.DTR=1 +FlowControl.RTS=0 +FlowControl.DSRSensitivity=0 +FlowControl.OutCTSFlow=0 +FlowControl.OutDSRFlow=0 +FlowControl.TxContinueOnXoff=0 +FlowControl.XoffChar=19 +FlowControl.XonChar=17 +FlowControl.XonXoffIn=0 +FlowControl.XonXoffOut=0 + +[Slots] +1.Color=16711680 +2.Color=255 +3.Color=32768 +4.Color=16711935 +GraphDelay=75 + +;BELOW HERE IS FOR FUTURE ONLY + +[Models] +cm2010="Charge Manager 2010" +cm2020="Charge Manager 2020" + +[Model.cm2010] +Slots=4 +RecordLength=34 +Byte.SlotNo=1 +Byte.Disp=2L +Byte.BattType=3H +Byte.Progress=3L +Byte.Counter=5 +Byte.Hours=6 +Byte.Minutes=7 +Byte.Current=14-15 +Byte.Voltage=16-17 +Byte.CCap=18-20 +Byte.DCap=21-23 +Byte.Resi=33-34 + +[Model.cm2020] +Slots=10 +RecordLength=22 +Byte.SlotNo=1 +Byte.Disp=4L +Byte.Progress=5L +Byte.CCap=6-8 +Byte.DCap=9-11 +Byte. diff --git a/MyCM2010_de.txt b/MyCM2010_de.txt new file mode 100644 index 0000000..6d9feff --- /dev/null +++ b/MyCM2010_de.txt @@ -0,0 +1,204 @@ +Conrad Charge Manager 2010 + +Protokollübersicht + + +Übertragungsrate: 9600 baud, 8 Datenbits, keine Parität, 1 Stopbit +Verbindung via Nullmodemkabel. + +Der CM gibt kontinuierlich Daten über den Zustand der einzelnen Schächte aus. Der Abstand zwischen den Informationen über ein und denselben Schacht beträgt 1 Sekunde. + +Kommandos können scheinbar keine gesendet werden, da laut Schaltplan von www.conrad.de (512265-in-01-de-charge_manager_2010_schnittstellenb.pdf) die Ladeelektronik des Geräts keinen Eingang hat. + +Sämtliche Informationen zu einem Schacht werden in 34 Bytes gesendet. Es gibt somit 4 Pakete à 34 Bytes. + +Alle Werte sind in Big-Endian (Big-End-First; 65536 = 01 00 00; 256 = 01 00) + + +Bytes Bedeutung +----- ---------------------- +01 Ladeschacht (1-4) + +02 ??? Programm; Lo: Displayanzeige (Details: siehe unten) +03 Hi: Manuell gewählte Kapazität; Lo: Momentane Stelle im Programm (Details: siehe unten) + +04 ??? + +05 Interner Zähler/Timer, zählt nach Einlegen des Akkus die 3 Sekunden, die man Zeit hat, etwas einzugeben, rückwärts, ansonsten zählt es von 60d rückwarts und bei 00 erfolgt Umsprung auf nächste Minute +06 Stunden +07 Minuten + +08 ??? + +09-10 Spannung (U) - nur beim Aufladen, sonst 00 00. Evtl. max. Spannung für Delta-U-Abschaltung. + +11 ??? (evtl. ungefährer Füllstand des Akkus?) +12 ??? +13 ??? + +14-15 Stromstärke (I) +16-17 Spannung (U) +18-20 Geladene Kapazität (CCap) +21-23 Entladene Kapazität (DCap) + +24 0Bh, falls nicht geladen wird, sonst was anderes + +25-26 Vor-vor-vor-letzte Spannung +27-28 Vor-vor-letzte Spannung +29-30 Vor-letzte Spannung +31-32 Letzte Spannung +33-34 Widerstand im Schacht (5MOhm = 01 F4; kein Akku: FF FF) + + +Bytes 02 und 03: + +02 03 04 +-- -- -- +00 00 00 Kein Programm, Schacht leer + +01 00 00 Wahl: Auto/Man: Auto +02 00 00 Wahl: Auto/Man: Manuell +(Zähler in Byte 5 zählt von 03 bis 00 und schaltet dann auf die nächste Auswahl) + +02 10 00 Wahl: Man: 100-200 +02 20 00 Wahl: Man: 200-350 +02 30 00 Wahl: Man: 350-600 +02 40 00 Wahl: Man: 600-900 +02 50 00 Wahl: Man: 900-1200 +02 60 00 Wahl: Man: 1200-1500 +02 70 00 Wahl: Man: 1500-2200 +02 80 00 Wahl: Man: 2200-... +(Zähler in Byte 5 zählt von 03 bis 00 und schaltet dann auf die nächste Auswahl/startet Programm) + +03 xx 00 Wahl: Auto: CHARGE +04 xx 00 Wahl: Auto: DISCHARGE +05 xx 00 Wahl: Auto: CHECK +06 xx 00 Wahl: Auto: CYCLE +07 xx 00 Wahl: Auto: ALIVE +(xx - 00:Auto, 10-80:Man) +(Zähler in Byte 5 zählt von 03 bis 00 und startet dann das Programm) + +08 05 01 Auto: CHA (Lädt) + +09 06 00 Auto: DIS (Entlädt) +09 26 08 Man: 200-350: DIS (Entlädt) + +0a 04 01 Auto: CHK (Entlädt) +0a 24 08 Man: 200-350: CHK (Entlädt) + +0b 03 01 Auto: CYC (Lädt) +0b 04 01 Auto: CYC (Entlädt) +0b 05 04 Auto: CYC (Lädt nach Entladen) + +0c 01 01 Auto: ALV (Lädt) +0c 02 01 Auto: ALV (Entlädt) +0c 02 03 Auto: ALV (Entlädt immer noch) +0c 02 04 Auto: ALV (Entlädt immer immer noch) +0c 02 08 Auto: ALV (Entlädt nach Laden) +0c 03 01 Auto: ALV (Lädt nach Entladen) +0c 03 02 Auto: ALV (Lädt nach Entladen immer immer noch) +0c 03 03 Auto: ALV (Lädt nach Entladen immer noch) +0c 04 01 Auto: ALV (Entlädt nach Laden) +0c 04 03 Auto: ALV (Entlädt nach Laden nach Entladen) +0c 04 08 Auto: ALV (Entlädt nach Laden nach Entladen) +0c 05 01 Auto: ALV (Lädt nach Entladen nach Laden nach Entladen) +0c 05 02 Auto: ALV (Lädt nach Entladen nach Laden nach Entladen) +0c 05 04 Auto: ALV (Lädt nach Entladen) +0c 42 06 Man: 600-900: ALV (Entlädt nach Laden) +0c 44 06 Man: 600-900: ALV (Entlädt nach Laden nach Entladen nach Laden) + +0d 08 01 Auto: CYC (RDY/Fertig) +0d 08 02 Auto: CHA (RDY/Fertig) +0d 08 03 Auto: ALV (RDY/Fertig) +0d 08 04 Auto: ALV (RDY/Fertig) +0d 48 04 Man: 600-900: ALV (RDY/Fertig) + +0e 0c xx ERR + +1b 03 01 Auto: CYC (Lädt immer noch) + +4c 03 03 Auto: ALV (Lädt immer immer noch) +4c 05 04 Auto: ALV (Lädt nach Entladen nach Laden nach Entladen nach Laden) + +58 25 02 Man: 200-350: CHA (Lädt) + +5b 23 02 Man: 200-350: CYC (Lädt) + +5c 21 02 Man: 200-350: ALV (Lädt) +5c 41 04 Man: 600-900: ALV (Lädt) +5c 43 04 Man: 600-900: ALV (Lädt nach Entladen) +5c 45 04 Man: 600-900: ALV (Lädt (letzte Phase)) + +6b 03 03 Auto: CYC (Lädt immer immer immer immer noch) + +6c 03 03 Auto: ALV (Lädt nach Entladen) +6c 05 04 Auto: ALV (Lädt nach Entladen nach Laden nach Entladen nach Laden) + +cb 03 04 Auto: CYC (Lädt immer noch) + +db 03 03 Auto: CYC (Lädt ... noch) +db 03 04 Auto: CYC (Lädt immer immer immer noch) + +dc 03 02 Auto: ALV (Lädt nach Entladen) +dc 05 03 Auto: ALV (Lädt ... noch) + +fb 03 03 Auto: CYC (Lädt immer immer noch) + + + +Der Lo-Part von Byte 2 gibt Auskunft über die aktuelle Display-Anzeige: +H bbbb Beschreibung +- ---- ------------ +0 0000 --- +1 0001 Wahl: Auto/Man: Auto +2 0010 Wahl: Auto/Man: Manuell +3 0011 Wahl: Auto: CHARGE +4 0100 Wahl: Auto: DISCHARGE +5 0101 Wahl: Auto: CHECK +6 0110 Wahl: Auto: CYCLE +7 0111 Wahl: Auto: ALIVE +8 1000 CHA +9 1001 DIS +a 1010 CHK +b 1011 CYC +c 1100 ALV +d 1101 RDY +e 1110 ERR +f 1111 TRI + + + +Der Lo-Part von Byte 3 gibt Auskunft über den Ablauf des Programms: +H bbbb Beschreibung +- ---- ------------ +0 0000 Kein Programm aktiv +1 0001 Laden <--- ALV startet hier +2 0010 Entladen +3 0011 Laden <--- CYC startet hier +4 0100 Entladen <--- CHK startet hier +5 0101 Laden <--- CHA startet hier +6 0110 Entladen (wird übersprungen, nur bei DIS startet das Programm hier) +7 0111 Erhaltungsladung (Trickle) +8 1000 RDY/Fertig + + + +Der Hi-Part von Byte 3 gibt Auskunft über die gewählte Akku-Kapazität: +H bbbb Beschreibung +- ---- ------------- +0 0000 Automatik +1 0001 100- 200 mAh +2 0010 200- 350 mAh +3 0011 350- 600 mAh +4 0100 600- 900 mAh +5 0101 900-1200 mAh +6 0110 1200-1500 mAh +7 0111 1500-2200 mAh +8 1000 2200-... mAh + + +Byte 4 scheint anzuzeigen, ob gerade die Kapazität gemessen wird, oder nicht: 01 oder 02 = Messen, bei 00 aktualisiert er das Symbol, 03/04 kommt während CYC vor. + + + +Weitere Aufschlüsselungen oder Korrekturen bitte per Mail an Markus Birth . diff --git a/MyCM2010_en.txt b/MyCM2010_en.txt new file mode 100644 index 0000000..bdb6684 --- /dev/null +++ b/MyCM2010_en.txt @@ -0,0 +1,204 @@ +Conrad Charge Manager 2010 + +Protocol overview + + +Transfer settings: 9600 baud, 8 Data bits, no parity, 1 Stopbit +Connection via Null modem cable. + +The CM2010 always sends info about the condition of each slot. The delay between 2 infos about the same slot is 1 second. + +It seems you can't send commands to the CM2010 because the circuit plan from www.conrad.de (512265-in-01-de-charge_manager_2010_schnittstellenb.pdf) shows no input for the charging controller. + +All values about a slot are sent in 34 Bytes. There are 4 Packets of 34 Bytes each. + +All values are in Big-Endian (Big-End-First; 65536 = 01 00 00; 256 = 01 00) + + +Bytes Meaning +----- ---------------------- +01 Slot (1-4) + +02 ??? Chosen Program; Lo: Display state (Details: see below) +03 Hi: manually chosen capacity; Lo: current step in program (Details: see below) + +04 ??? + +05 Internal counter/timer, counts back the 3 seconds after insertion of battery, where you have time to change settings. Otherwise it counts back from 60d and increases minute when 00. +06 Hours +07 Minutes + +08 ??? + +09-10 Voltage (U) - only when charging, otherwise 00 00. Perhaps max. current for Delta-U-shut-off. + +11 ??? (perhaps approx. charge of battery?) +12 ??? +13 ??? + +14-15 Current (I) +16-17 Voltage (U) +18-20 Charged capacity (CCap) +21-23 Discharged capacity (DCap) + +24 0Bh, if not charging, otherwise something else + +25-26 Fourth last voltage +27-28 Third last voltage +29-30 Second last voltage +31-32 Last voltage +33-34 Resistance in slot (5MOhm = 01 F4; no battery: FF FF) + + +Bytes 02 and 03: + +02 03 04 +-- -- -- +00 00 00 No program, Slot empty + +01 00 00 Choice: Auto/Man: Auto +02 00 00 Choice: Auto/Man: Manual +(Counter in Byte 5 counts from 03 to 00 and then switches to next choice) + +02 10 00 Choice: Man: 100-200 +02 20 00 Choice: Man: 200-350 +02 30 00 Choice: Man: 350-600 +02 40 00 Choice: Man: 600-900 +02 50 00 Choice: Man: 900-1200 +02 60 00 Choice: Man: 1200-1500 +02 70 00 Choice: Man: 1500-2200 +02 80 00 Choice: Man: 2200-... +(Counter in Byte 5 counts from 03 to 00 and then switches to next choice/runs program) + +03 xx 00 Choice: Auto: CHARGE +04 xx 00 Choice: Auto: DISCHARGE +05 xx 00 Choice: Auto: CHECK +06 xx 00 Choice: Auto: CYCLE +07 xx 00 Choice: Auto: ALIVE +(xx - 00:Auto, 10-80:Man) +(Counter in Byte 5 counts from 03 to 00 and then runs the program) + +08 05 01 Auto: CHA (Charges) + +09 06 00 Auto: DIS (Discharges) +09 26 08 Man: 200-350: DIS (Discharges) + +0a 04 01 Auto: CHK (Discharges) +0a 24 08 Man: 200-350: CHK (Discharges) + +0b 03 01 Auto: CYC (Charges) +0b 04 01 Auto: CYC (Discharges) +0b 05 04 Auto: CYC (Charges after Discharging) + +0c 01 01 Auto: ALV (Charges) +0c 02 01 Auto: ALV (Discharges) +0c 02 03 Auto: ALV (still Discharges) +0c 02 04 Auto: ALV (still still Discharges) +0c 02 08 Auto: ALV (Discharges after Charging) +0c 03 01 Auto: ALV (Charges after Discharging) +0c 03 02 Auto: ALV (Charges after Discharging immer immer noch) +0c 03 03 Auto: ALV (Charges after Discharging immer noch) +0c 04 01 Auto: ALV (Discharges after Charging) +0c 04 03 Auto: ALV (Discharges after Charging after Discharging) +0c 04 08 Auto: ALV (Discharges after Charging after Discharging) +0c 05 01 Auto: ALV (Charges after Discharging after Charging after Discharging) +0c 05 02 Auto: ALV (Charges after Discharging after Charging after Discharging) +0c 05 04 Auto: ALV (Charges after Discharging) +0c 42 06 Man: 600-900: ALV (Discharges after Charging) +0c 44 06 Man: 600-900: ALV (Discharges after Charging after Discharging after Charging) + +0d 08 01 Auto: CYC (RDY/Fertig) +0d 08 02 Auto: CHA (RDY/Fertig) +0d 08 03 Auto: ALV (RDY/Fertig) +0d 08 04 Auto: ALV (RDY/Fertig) +0d 48 04 Man: 600-900: ALV (RDY/Fertig) + +0e 0c xx ERR + +1b 03 01 Auto: CYC (Charges immer noch) + +4c 03 03 Auto: ALV (Charges immer immer noch) +4c 05 04 Auto: ALV (Charges after Discharging after Charging after Discharging after Charging) + +58 25 02 Man: 200-350: CHA (Charges) + +5b 23 02 Man: 200-350: CYC (Charges) + +5c 21 02 Man: 200-350: ALV (Charges) +5c 41 04 Man: 600-900: ALV (Charges) +5c 43 04 Man: 600-900: ALV (Charges after Discharging) +5c 45 04 Man: 600-900: ALV (Charges (last phase)) + +6b 03 03 Auto: CYC (still still still still Charges) + +6c 03 03 Auto: ALV (Charges after Discharging) +6c 05 04 Auto: ALV (Charges after Discharging after Charging after Discharging after Charging) + +cb 03 04 Auto: CYC (still Charges) + +db 03 03 Auto: CYC (Charges ... for now) +db 03 04 Auto: CYC (still still still Charges) + +dc 03 02 Auto: ALV (Charges after Discharging) +dc 05 03 Auto: ALV (Charges ... for now) + +fb 03 03 Auto: CYC (still still Charges) + + + +The Lo-Part of Byte 2 reflects the current display: +H bbbb Description +- ---- ----------- +0 0000 --- +1 0001 Choice: Auto/Man: Auto +2 0010 Choice: Auto/Man: Manuell +3 0011 Choice: Auto: CHARGE +4 0100 Choice: Auto: DISCHARGE +5 0101 Choice: Auto: CHECK +6 0110 Choice: Auto: CYCLE +7 0111 Choice: Auto: ALIVE +8 1000 CHA +9 1001 DIS +a 1010 CHK +b 1011 CYC +c 1100 ALV +d 1101 RDY +e 1110 ERR +f 1111 TRI + + + +The Lo-Part of Byte 3 reflects the program flow: +H bbbb Description +- ---- ----------- +0 0000 No program active +1 0001 Charging <--- ALV starts here +2 0010 Discharging +3 0011 Charging <--- CYC starts here +4 0100 Discharging <--- CHK starts here +5 0101 Charging <--- CHA starts here +6 0110 Discharging (is being skipped, only when DIS, the program starts here) +7 0111 Trickle charge +8 1000 RDY/Ready + + + +The Hi-Part of Byte 3 reflects the chosen battery capacity: +H bbbb Description +- ---- ----------- +0 0000 Automatic +1 0001 100- 200 mAh +2 0010 200- 350 mAh +3 0011 350- 600 mAh +4 0100 600- 900 mAh +5 0101 900-1200 mAh +6 0110 1200-1500 mAh +7 0111 1500-2200 mAh +8 1000 2200-... mAh + + +Byte 4 seems to reflect, if the capacity is being measured or not: 01 or 02 = Measuring, if 00, updating the battery symbol, 03/04 occurs during CYC. + + + +More informations of corrections via eMail to Markus Birth .