1
0
mirror of https://github.com/mbirth/cm2010.git synced 2024-12-24 03:14:07 +00:00
This commit is contained in:
Markus Birth 2012-10-22 23:47:46 +02:00
commit 692b18d1fd
8 changed files with 2284 additions and 0 deletions

717
CM2010.dfm Normal file
View File

@ -0,0 +1,717 @@
object Form1: TForm1
Left = 195
Top = 109
Width = 716
Height = 477
Caption =
'Charge Manager 2010 --- (c)2003 by Markus Birth <mbirth@webwrite' +
'rs.de>'
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

901
CM2010.pas Normal file
View File

@ -0,0 +1,901 @@
unit CM2010;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, CPort, ComCtrls, IniFiles, CPortCtl, DateUtils;
type
TForm1 = class(TForm)
COMSettings: TButton;
MultiButt: TButton;
GroupBox1: TGroupBox;
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;
ComPort: TComPort;
PB_1: TProgressBar;
PB_2: TProgressBar;
PB_3: TProgressBar;
PB_4: TProgressBar;
ComLed1: TComLed;
ComLed2: TComLed;
ComLed3: TComLed;
ComLed4: TComLed;
ComLed5: TComLed;
ComLed6: TComLed;
ComLed7: TComLed;
Label14: TLabel;
Label15: TLabel;
Label16: TLabel;
Label17: TLabel;
Label18: TLabel;
Label19: TLabel;
Label20: TLabel;
T_1: TLabel;
T_2: TLabel;
T_3: TLabel;
T_4: TLabel;
procedure COMSettingsClick(Sender: TObject);
procedure MultiButtClick(Sender: TObject);
procedure ComPortAfterOpen(Sender: TObject);
procedure ComPortAfterClose(Sender: TObject);
procedure ComPortRxChar(Sender: TObject; Count: Integer);
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}
type
TRecords = array[1..4]of String[34];
TBuf = array[0..33] of char;
const
CRLF: string = Chr(13) + Chr(10);
var
Slot: TRecords;
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;
f1,f2,f3,f4: file of byte;
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.ComPortAfterOpen(Sender: TObject);
begin
MultiButt.Caption := 'Stop capturing';
end;
procedure TForm1.ComPortAfterClose(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 GetProgress(s: byte): byte;
begin
Result := 0;
if (ShowHex(Ord(Slot[s][3]))[2]<>'0') then begin
case ShowHex(Ord(Slot[s][2]))[2] of
'8': case ShowHex(Ord(Slot[s][3]))[2] of
'5': Result := 50;
'7','8': Result := 100;
end;
'9': case ShowHex(Ord(Slot[s][3]))[2] of
'6': Result := 50;
'7','8': Result := 100;
end;
'a': case ShowHex(Ord(Slot[s][3]))[2] of
'4': Result := 33;
'5': Result := 66;
'7','8': Result := 100;
end;
'b': case ShowHex(Ord(Slot[s][3]))[2] of
'3': Result := 25;
'4': Result := 50;
'5': Result := 75;
'7','8': Result := 100;
end;
'c': case ShowHex(Ord(Slot[s][3]))[2] of
'1': Result := 16;
'2': Result := 33;
'3': Result := 50;
'4': Result := 66;
'5': Result := 83;
'7','8': Result := 100;
end;
'd','e','f': Result := 100;
end;
end else Result := 0;
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);
with Form1 do begin
ComPort.Port := cf.ReadString('Communication','Port','COM1');
ComPort.BaudRate := StrToBaudRate(cf.ReadString('Communication','BaudRate','9600'));
ComPort.DataBits := StrToDataBits(cf.ReadString('Communication','DataBits','8'));
ComPort.StopBits := StrToStopBits(cf.ReadString('Communication','StopBits','1'));
ComPort.Parity.Bits := StrToParity(cf.ReadString('Communication','Parity','None'));
ComPort.Parity.Check := cf.ReadBool('Communication','Parity.Check',false);
ComPort.Parity.Replace := cf.ReadBool('Communication','Parity.Replace',false);
ComPort.Parity.ReplaceChar := Chr(cf.ReadInteger('Communication','Parity.ReplaceChar',0));
ComPort.FlowControl.FlowControl := StrToFlowControl(cf.ReadString('Communication','FlowControl','Custom'));
ComPort.FlowControl.ControlDTR := TDTRFlowControl(cf.ReadInteger('Communication','FlowControl.DTR',1));
ComPort.FlowControl.ControlRTS := TRTSFlowControl(cf.ReadInteger('Communication','FlowControl.RTS',0));
ComPort.FlowControl.DSRSensitivity := cf.ReadBool('Communication','FlowControl.DSRSensitivity',false);
ComPort.FlowControl.OutCTSFlow := cf.ReadBool('Communication','FlowControl.OutCTSFlow',false);
ComPort.FlowControl.OutDSRFlow := cf.ReadBool('Communication','FlowControl.OutDSRFlow',false);
ComPort.FlowControl.TxContinueOnXoff := cf.ReadBool('Communication','FlowControl.TxContinueOnXoff',false);
ComPort.FlowControl.XoffChar := Chr(cf.ReadInteger('Communication','FlowControl.XoffChar',19));
ComPort.FlowControl.XonChar := Chr(cf.ReadInteger('Communication','FlowControl.XonChar',17));
ComPort.FlowControl.XonXoffIn := cf.ReadBool('Communication','FlowControl.XonXoffIn',false);
ComPort.FlowControl.XonXoffOut := cf.ReadBool('Communication','FlowControl.XonXoffOut',false);
end;
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));
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'));
with Form1 do begin
cf.WriteString('Communication', 'Port', ComPort.Port);
cf.WriteString('Communication', 'BaudRate', BaudRateToStr(ComPort.BaudRate));
cf.WriteString('Communication', 'DataBits', DataBitsToStr(ComPort.DataBits));
cf.WriteString('Communication', 'StopBits', StopBitsToStr(ComPort.StopBits));
cf.WriteString('Communication', 'Parity', ParityToStr(ComPort.Parity.Bits));
cf.WriteBool('Communication', 'Parity.Check', ComPort.Parity.Check);
cf.WriteBool('Communication', 'Parity.Replace', ComPort.Parity.Replace);
cf.WriteInteger('Communication', 'Parity.ReplaceChar', Ord(ComPort.Parity.ReplaceChar));
cf.WriteString('Communication', 'FlowControl', FlowControlToStr(ComPort.FlowControl.FlowControl));
cf.WriteInteger('Communication', 'FlowControl.DTR', Ord(ComPort.FlowControl.ControlDTR));
cf.WriteInteger('Communication', 'FlowControl.RTS', Ord(ComPort.FlowControl.ControlRTS));
cf.WriteBool('Communication', 'FlowControl.DSRSensitivity', ComPort.FlowControl.DSRSensitivity);
cf.WriteBool('Communication', 'FlowControl.OutCTSFlow', ComPort.FlowControl.OutCTSFlow);
cf.WriteBool('Communication', 'FlowControl.OutDSRFlow', ComPort.FlowControl.OutDSRFlow);
cf.WriteBool('Communication', 'FlowControl.TxContinueOnXoff', ComPort.FlowControl.TxContinueOnXoff);
cf.WriteInteger('Communication' ,'FlowControl.XoffChar', Ord(ComPort.FlowControl.XoffChar));
cf.WriteInteger('Communication', 'FlowControl.XonChar', Ord(ComPort.FlowControl.XonChar));
cf.WriteBool('Communication', 'FlowControl.XonXoffIn', ComPort.FlowControl.XonXoffIn);
cf.WriteBool('Communication', 'FlowControl.XonXoffOut', ComPort.FlowControl.XonXoffOut);
end;
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]));
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: string[2];
begin
b2 := ShowHex(Ord(Slot[s][2]));
b3 := ShowHex(Ord(Slot[s][3]));
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;
function GetManType(s: byte): String;
begin
case Ord(Slot[s][3]) AND $F0 of
$00: Result := 'Automatic';
$10: Result := '100-200';
$20: Result := '200-350';
$30: Result := '350-600';
$40: Result := '600-900';
$50: Result := '900-1200';
$60: Result := '1200-1500';
$70: Result := '1500-2200';
$80: Result := '2200-....';
else
Result := '?????????';
end;
end;
function MakeBuf(s: integer): TBuf;
var i: integer;
begin
for i:=1 to 34 do Result[i-1] := Slot[s][i];
end;
procedure DoLog(s: byte);
var Buf: TBuf;
begin
with Form1 do begin
case s of
1: if L1.Checked then begin
Buf := MakeBuf(1);
BlockWrite(f1,Buf,34);
end;
2: if L2.Checked then begin
Buf := MakeBuf(2);
BlockWrite(f2,Buf,34);
end;
3: if L3.Checked then begin
Buf := MakeBuf(3);
BlockWrite(f3,Buf,34);
end;
4: if L4.Checked then begin
Buf := MakeBuf(4);
BlockWrite(f4,Buf,34);
end;
end;
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]<GH) then Image.Canvas.MoveTo(GW-1,GraphPos[Slot,1]) else Image.Canvas.MoveTo(GW,GraphPos[Slot,2]);
if (GraphPos[Slot,2]<GH) then begin
Image.Canvas.LineTo(GW,GraphPos[Slot,2]);
Image.Canvas.Pixels[GW,GraphPos[Slot,2]] := GraphCol[Slot];
end;
end;
procedure DoGraphDisp(Image: TImage; Slot: integer);
begin
GraphPos[Slot,1] := GraphPos[Slot,2];
GraphPos[Slot,2] := Image.Height-2-GetVolts(Slot) DIV 10;
PaintGraph(Image, Slot);
end;
function MSBetween(t1, t2: TDateTime): integer;
var r: double;
begin
if t2>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;
case LSlot of
1: begin
Edit1.Text := BuildHex(Slot[1]);
DoDisplay(1, D_1);
T_1.Caption := GetManType(1);
PB_1.Position := GetProgress(1);
DoLog(1);
end;
2: begin
Edit2.Text := BuildHex(Slot[2]);
DoDisplay(2, D_2);
T_2.Caption := GetManType(2);
PB_2.Position := GetProgress(2);
DoLog(2);
end;
3: begin
Edit3.Text := BuildHex(Slot[3]);
DoDisplay(3, D_3);
T_3.Caption := GetManType(3);
PB_3.Position := GetProgress(3);
DoLog(3);
end;
4: begin
Edit4.Text := BuildHex(Slot[4]);
DoDisplay(4, D_4);
T_4.Caption := GetManType(4);
PB_4.Position := GetProgress(4);
DoLog(4);
end;
end;
Inc(LSlot);
if LSlot>4 then LSlot := 1;
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 begin
Inc(GraphTime);
DoStatDisp(D_Stat);
end;
case LSlot of
1: R_1.Checked := true;
2: R_2.Checked := true;
3: R_3.Checked := true;
4: R_4.Checked := true;
end;
end;
end;
end;
end;
procedure TForm1.ComPortRxFlag(Sender: TObject);
begin
L_Time.Caption := TimeToStr(time);
LastEvent := now;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if ComPort.Connected then ComPort.Close;
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;
function GetDateTimeString(): string;
var y,m,d,h,i,s,ms: word;
begin
DecodeDateTime(now,y,m,d,h,i,s,ms);
Result := '';
Result := Result + IntToStr(y);
if (m<10) then Result := Result + '0';
Result := Result + IntToStr(m);
if (d<10) then Result := Result + '0';
Result := Result + IntToStr(d);
if (h<10) then Result := Result + '0';
Result := Result + IntToStr(h);
if (i<10) then Result := Result + '0';
Result := Result + IntToStr(i);
if (s<10) then Result := Result + '0';
Result := Result + IntToStr(s);
end;
procedure TForm1.L1Click(Sender: TObject);
begin
StartStopCheck;
if (L1.Checked) then begin
AssignFile(f1,'Slot01_'+GetDateTimeString()+'.log');
Rewrite(f1);
end else begin
CloseFile(f1);
end;
end;
procedure TForm1.L2Click(Sender: TObject);
begin
StartStopCheck;
if (L2.Checked) then begin
AssignFile(f2,'Slot02_'+GetDateTimeString()+'.log');
Rewrite(f2);
end else begin
CloseFile(f2);
end;
end;
procedure TForm1.L3Click(Sender: TObject);
begin
StartStopCheck;
if (L3.Checked) then begin
AssignFile(f3,'Slot03_'+GetDateTimeString()+'.log');
Rewrite(f3);
end else begin
CloseFile(f3);
end;
end;
procedure TForm1.L4Click(Sender: TObject);
begin
StartStopCheck;
if (L4.Checked) then begin
AssignFile(f4,'Slot04_'+GetDateTimeString()+'.log');
Rewrite(f4);
end else begin
CloseFile(f4);
end;
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.

39
CM2010Project.cfg Normal file
View File

@ -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

142
CM2010Project.dof Normal file
View File

@ -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=5
Debug=0
PreRelease=1
Special=0
Private=0
DLL=0
Locale=1033
CodePage=1252
[Version Info Keys]
CompanyName=Markus Birth <mbirth@webwriters.de>
FileDescription=
FileVersion=1.0.0.5
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;

14
CM2010Project.dpr Normal file
View File

@ -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.

63
CM2010Project.ini Normal file
View File

@ -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.

204
MyCM2010_de.txt Normal file
View File

@ -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 <mbirth@webwriters.de>.

204
MyCM2010_en.txt Normal file
View File

@ -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 <mbirth@webwriters.de>.