多串口监控问题 ( 积分: 200 )

  • 主题发起人 主题发起人 shtxxf
  • 开始时间 开始时间
S

shtxxf

Unregistered / Unconfirmed
GUEST, unregistred user!
正在做考勤打卡系统。有十五个打卡通道,每个通道对应一个串口!使用SPCOMM控件。第十六串口作为报警通讯端口!要使用多线程吗?如果要请各位多多帮忙。分不够再加。
 
正在做考勤打卡系统。有十五个打卡通道,每个通道对应一个串口!使用SPCOMM控件。第十六串口作为报警通讯端口!要使用多线程吗?如果要请各位多多帮忙。分不够再加。
 
我这里用两个串口控制下位机工作,一个采集数据,一个控制,不知道和你那种情况是否一样?
 
你是用多线程做的吗?两个和多个还不一样。可以帮忙提供源码吗?
 
恩。。。我不是用多线程做的,我也在调试呢
你要不试试这样,添加comm1到comm15,给每个comm的commport属性改为相应的pnCOM1到pnCOM15,然后用comm1.outputbyte,comm15.outputbyte这样用,你试试吧,我也在调呢!
如果用多线程应该也也可以,你想使用comm中的什么方法呢?
 
我担心下班打卡的人多,4000人啊。不用线程会出问题啊。有经验的帮帮忙啊。分不够再加。。。。
 
可以一个线程监控一个串口来采集数据,这就体现了多线程的优点了
 
TO dawnsong
被动接收数据------解析数据------发送异常(保存日志)-----到抄收数据时间(自动抄收数据)----恢复监控状态。
这是流程!线程如何做?可以给个DEMO吗?
 
可以一个线程监控一个串口,创建一个数据存储队列,可能同一时刻有好几个人刷卡,但他们的刷卡次序精确点讲,肯定有先后;
 
被动接收数据
---------------
可以用同步查询方式,做到线程里这个简单,对每一个串口开一个监听线程,
不断的用ClearCommError查询得到当前收到的数据字节数量,达到一定值后,保存到另外一个缓冲区内,这个缓冲区需要临界保护。

解析等就依赖于这个受保护的缓冲区,这个缓冲区问题说起来简单,做起来可并不那么容易,Demo我现在倒是没有,呵呵,只能在这里白活几句:)
 
你是在设计硬件还是软件呀
我所知的考勤用485通信的话,只要一台电脑就可以了。
由这台电脑发指令给考勤机,考勤机收到特定指令后就广播数据包,
你接受这个包就可以了。
 
一台电脑啊!同时监控15个串口。发现其中之一有异常就要报警同时将信息保存到数据库。各位大虾帮忙啊。。。。呜呜
 
TO dawnsong
是不是可以做个DEMO啊?分不够另开贴给。。。。。
 
我是这样想的啊,一个spcom控件监控一个COM口,怎么样呢
其他的应该好处理啊
有点笨,呵呵
学习
 
to znj_326
“其他的应该好处理啊”
请帮忙来个DEMO,要流程正确哦。。。
放了几天了,哎!
欺负我朝中无人啊。。。。
 
SPComm本来就是多线程的,
好啊,给多少分啊
 
考勤作实时通信没有必要吧,这样稳定性会很差的.
太容易丢失数据了,现在市面上的考勤钟都有存储空间的.
只要在存满之前采集下来就行了.

当然很多考勤钟也支持实时通信的,只要有人刷卡它就向网络发数据包
你在COM或其它端口接受它就可以了.

还是不明白你到底在干些什么
 
现实是这样做的!
请你们提供方法。
要求达到的功能:
1、监控(1-15);
2、报警(16)/存数据库日志表;
3、定时抄收数据。
那位大虾能提供好的方法,另给100分!
 
一个简简单单的多线程监控,仅仅建立串口监听,并判断入口缓冲区数据是否大于256,是则读串口数据到本线程的缓冲区内,算是个简单的Demo(利用的是WinApi来打开串口,采用的是同步监听的方式)
---------------------------------------------------------------------------
unit uMain;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
lboxThreads: TListBox;
btnStartTheThread: TButton;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btnStartTheThreadClick(Sender: TObject);
private
{ Private declarations }

public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses uComThread;

{$R *.dfm}
var
threads:array[0..15] of TComThread;

procedure TForm1.btnStartTheThreadClick(Sender: TObject);
var
strComX:string;
begin
strComX :=Format('Com%d',[lboxThreads.ItemIndex+1]);
if not Assigned(threads[lboxThreads.ItemIndex]) then
begin
threads[lboxThreads.ItemIndex] :=TComThread.Create(strComX);
end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
i:Integer;
begin
for i:=0 to lboxThreads.Count-1 do
begin
if Assigned(threads[lboxThreads.ItemIndex]) then
begin
threads[lboxThreads.ItemIndex].Destroy;
threads[lboxThreads.ItemIndex] :=nil;
end;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
i:Integer;
begin
for i:=0 to lboxThreads.Count-1 do
threads[lboxThreads.ItemIndex] :=nil;
end;

end.
---------------------------------------------------------------------------
unit uComThread;

interface

uses
Classes,Windows, SysUtils;

type
TComThread = class(TThread)
private
{ Private declarations }
FComX :THandle;
FStrComX:string;
cache :array[0..255] of Byte;
protected
procedure Execute; override;
public
constructor Create(const AStrComX:string);overload;
destructor Destroy;override;
end;

implementation

{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,

Synchronize(UpdateCaption);

and UpdateCaption could look like,

procedure TComThread.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }

{ TComThread }
constructor TComThread.Create(const AStrComX:string);
begin
FStrComX :=AStrComX;
FComX :=CreateFile(PChar(FStrComX),
GENERIC_READ or GENERIC_WRITE,
0, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if FComX=INVALID_HANDLE_VALUE then
raise Exception.Create('Can not open '+FStrComX);
if not SetupComm(FComX, 4096, 4096) then //建立读写缓冲区
begin
CloseHandle(FComX);
raise Exception.Create('Can not SetupComm!');
end;
//清空读写缓冲区
PurgeComm(FComX, PURGE_TXABORT or PURGE_RXABORT or
PURGE_TXCLEAR or PURGE_RXCLEAR);

inherited Create(false);
end;
destructor TComThread.Destroy;
begin
CloseHandle(FComX);
end;
procedure TComThread.Execute;
var
error:DWORD;
theComStat:COMSTAT;
begin
{ Place thread code here }
while not Terminated do
begin
ClearCommError(FComX,error,@theComStat);
if theComStat.cbInQue>=256 then
ReadFile(FComX,cache,256,error,nil);
end;
end;

end.

---------------------------------------------------------------------------
object Form1: TForm1
Left = 0
Top = 0
Width = 532
Height = 254
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnClose = FormClose
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object lboxThreads: TListBox
Left = 0
Top = 0
Width = 73
Height = 220
Align = alLeft
ItemHeight = 13
Items.Strings = (
'Thread-1'
'Thread-2'
'Thread-3'
'Thread-4'
'Thread-5'
'Thread-6'
'Thread-7'
'Thread-8'
'Thread-9'
'Thread-10'
'Thread-11'
'Thread-12'
'Thread-13'
'Thread-14'
'Thread-15'
'Thread-16')
TabOrder = 0
end
object btnStartTheThread: TButton
Left = 80
Top = 8
Width = 105
Height = 25
Caption = 'btnStartTheThread'
TabOrder = 1
OnClick = btnStartTheThreadClick
end
end

---------------------------------------------------------------------------
 
快下班了,明天要安装软件!各位大虾有经验的帮忙指点一下!!!!
还有140分,全给你。
 
后退
顶部