本示例使用设备:485通讯液显带键盘RFID打菲计件读卡器工位机串口可二次开发编程-淘宝网 (taobao.com)
javascript
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Web Serial Api串口读卡器485工控机示例 </title>
<script>
window.onload = function() {
document.getElementById('butt_openserial').hidden=true;
document.getElementById('butt_closeserial').hidden=true;
}
if ('serial' in navigator){
}else{
alert('您的浏览器不支持 Web Serial API,暂无法使用以下功能!');
}
navigator.serial.onconnect =function event(){
console.log("Serial port connected: ", event.target);
}
navigator.serial.ondisconnect =function event(){
console.log("Serial port disconnected: ", event.target);
}
var port = null;
var reader = null;
var reading = false;
const getdata=new Uint8Array(1000); //接收串口返回的数据
var DataPoint=0; //接收数据指针
var SendCode=0; //已发送的指令代码
var connecting = false; //正在通讯
var time1;
var datetimestr=""
var weekday=0 ;
setInterval(showTime, 1000);
function isUIntNum(val) {
var testval = /^\d+$/; // 非负整数
return (testval.test(val));
}
function isHex(val) {
var testval = /^(\d|[A-F]|[a-f])+$/; // 十六进制数判断
return (testval.test(val));
}
function showTime() {
const now = new Date();
const hours = now.getHours().toString().padStart(2, '0');
const minutes = now.getMinutes().toString().padStart(2, '0');
const seconds = now.getSeconds().toString().padStart(2, '0');
const timeString = `${hours}:${minutes}:${seconds}`;
const day = now.getDate().toString().padStart(2, '0');
const month = (now.getMonth() + 1).toString().padStart(2, '0');
const year = now.getFullYear();
const dateString = `${year}-${month}-${day}`;
weekday=now.getDay();
datetimestr=dateString+" "+ timeString+" "+weekday.toString();
document.getElementById('label_datetime').innerText =datetimestr;
}
async function SelectSerial(){
try{
port =await navigator.serial.requestPort(); // 弹出系统串口列表对话框,选择一个串口进行连接
ports =await navigator.serial.getPorts(); // 获取已连接的授权过的设备列表
document.getElementById('butt_openserial').hidden=false;
}
catch (e)
{
console.log(e);
}
}
function updateInputData(data) {
let array = new Uint8Array(data); // event.data.buffer就是接收到的inputreport包数据了
let hexstr = "";
for (const data of array) {
hexstr += (Array(2).join(0) + data.toString(16).toUpperCase()).slice(-2) + " "; // 将字节数据转换成(XX )形式字符串
getdata[DataPoint]=data;
DataPoint=DataPoint+1;
}
ReceiveData.value += hexstr;
var label_disp = document.getElementById('label_disp');
if(SendCode==1 && DataPoint>4 ){
ConnectOver();
if(getdata[4]==getdata[2] ^ getdata[3]){
deviceno.value=(getdata[2]+getdata[3]*256).toString();
label_disp.innerText = "读取机号成功!";
}
}else if(SendCode==2 && DataPoint>=2 && getdata[0]==0x69 && getdata[1]==0xf0){
label_disp.innerText = "设置新机号成功!";
deviceno.value=newdeviceno.value;
ConnectOver();
}else if(SendCode==3 && DataPoint>0){
label_disp.innerText = "发卡器已响声!";
ConnectOver();
}else if(SendCode==4){
if(getdata[0]==0){
ConnectOver();
label_disp.innerText = "未寻到卡!";
}else if(getdata[0]==0x69 && DataPoint>7){
ConnectOver();
var dispinfo="";
if(getdata[1]==0xd2 && getdata[2]^getdata[3]^getdata[4]^getdata[5]^getdata[6]==getdata[7]){
cardnohex="";
for(i=2;i<7;i++){cardnohex=cardnohex+(Array(2).join(0) + getdata[i].toString(16).toUpperCase()).slice(-2);}
HLCode=cardnohex.substring(2,4)+cardnohex.substring(4,6)+cardnohex.substring(6,8)+cardnohex.substring(8,10);
card8h10dz=parseInt("0x"+HLCode).toString().padStart(10, '0');
cardwg26z=parseInt("0x"+cardnohex.substring(4,6)).toString().padStart(3, '0')+parseInt("0x"+cardnohex.substring(6,10)).toString().padStart(5, '0');
cardwg34z=parseInt("0x"+cardnohex.substring(2,6)).toString().padStart(5, '0')+parseInt("0x"+cardnohex.substring(6,10)).toString().padStart(5, '0');
dispinfo=dispinfo+"读取16进制卡号:"+cardnohex+",转8H10D码:"+card8h10dz+",转WG34码:"+cardwg34z+",转WG26码:"+cardwg26z;
}else{
dispinfo=dispinfo+"卡号异或和校验错误,未能读取到正确的卡号!";
}
label_disp.innerText =dispinfo;
}
}else if(SendCode==5 ){
if(getdata[0]==0x00 ){
ConnectOver();
label_disp.innerText = "没有按键!";
}else if(getdata[0]==0x69 && getdata[DataPoint-1]==0x0d){
keystr="";
for(i=2;i<DataPoint;i++){keystr=keystr+String.fromCharCode(getdata[i]);}
label_disp.innerText = "读取键值:"+keystr;
ConnectOver();
}
}else if(SendCode==6 ){
if(getdata[0]==0x00 ){
label_disp.innerText = "没有刷卡按键!";
ConnectOver();
}else if(getdata[0]==0x69 && getdata[1]==0x69 && getdata[DataPoint-1]==getdata[DataPoint-2]^getdata[DataPoint-3]){
if(getdata[2]==0x01 && getdata[3]^getdata[4]^getdata[5]^getdata[6]^getdata[7]==getdata[8]){ //只有刷卡数据
cardnohex="";
for(i=3;i<8;i++){cardnohex=cardnohex+(Array(2).join(0) + getdata[i].toString(16).toUpperCase()).slice(-2);}
HLCode=cardnohex.substring(2,4)+cardnohex.substring(4,6)+cardnohex.substring(6,8)+cardnohex.substring(8,10);
card8h10dz=parseInt("0x"+HLCode).toString().padStart(10, '0');
cardwg26z=parseInt("0x"+cardnohex.substring(4,6)).toString().padStart(3, '0')+parseInt("0x"+cardnohex.substring(6,10)).toString().padStart(5, '0');
cardwg34z=parseInt("0x"+cardnohex.substring(2,6)).toString().padStart(5, '0')+parseInt("0x"+cardnohex.substring(6,10)).toString().padStart(5, '0');
label_disp.innerText="读取16进制卡号:"+cardnohex+",转8H10D码:"+card8h10dz+",转WG34码:"+cardwg34z+",转WG26码:"+cardwg26z;
ConnectOver();
}else if(getdata[2]==0x02 && getdata[DataPoint-4]==0x0d){ //只有按键数据
keystr="";
for(i=4;i<DataPoint-4;i++){keystr=keystr+String.fromCharCode(getdata[i]);}
label_disp.innerText = "读取键值:"+keystr;
ConnectOver();
}else if(getdata[2]==0x03 && getdata[DataPoint-4]==0x0d){ //卡号+按键值
cardnohex="";
for(i=3;i<8;i++){cardnohex=cardnohex+(Array(2).join(0) + getdata[i].toString(16).toUpperCase()).slice(-2);}
HLCode=cardnohex.substring(2,4)+cardnohex.substring(4,6)+cardnohex.substring(6,8)+cardnohex.substring(8,10);
card8h10dz=parseInt("0x"+HLCode).toString().padStart(10, '0');
cardwg26z=parseInt("0x"+cardnohex.substring(4,6)).toString().padStart(3, '0')+parseInt("0x"+cardnohex.substring(6,10)).toString().padStart(5, '0');
keystr="";
for(i=10;i<DataPoint-4;i++){keystr=keystr+String.fromCharCode(getdata[i]);}
label_disp.innerText="读取16进制卡号:"+cardnohex+",转8H10D码:"+card8h10dz+",转WG26码:"+cardwg26z+",按键值:"+keystr;
ConnectOver();
}
}
}else if(SendCode==8 && DataPoint>=2 && getdata[0]==0x69 && getdata[1]==0x0f){
label_disp.innerText = "设置新管理密码成功!";
ConnectOver();
}else if(SendCode==11 && DataPoint>=2){
label_disp.innerText = "读取设备状态成功!";
ConnectOver();
}
}
async function listenReceived(){
if (reading){
console.log("On reading.");
return;
}
reading=true;
while (port.readable && reading) {
reader = port.readable.getReader();
try {
while (true) {
const { value, done } = await reader.read();
if (done) {
// |reader| has been canceled.
break;
}
// 需要特别注意的是:实际使用中即使对端是按一个个包发送的串口数据,接收时收到的也可能是分多段收到的
updateInputData(value);
}
} catch (e) {
alert(e);
} finally {
reader.releaseLock();
}
}
await port.close(); // 关闭串口
port = null;
alert("串口已关闭!");
var label_disp = document.getElementById('label_disp');
label_disp.innerText = "请先选择并打开与读卡器相连的串口!";
}
async function OpenSerial(){
if (port==null){
alert('请先选择要操作的串口号!');
return;
}else{
document.getElementById('butt_closeserial').hidden=false;
var baudSelected = parseInt(document.getElementById("select_btn").value);
await port.open({
baudRate: baudSelected,
});
listenReceived();
alert('串口打开成功!');
var label_disp = document.getElementById('label_disp');
label_disp.innerText = "串口已打开,可向串口发送指令!";
}
}
async function CloseSerial(){
if ((port == null) || (!port.writable)) {
alert("请选择并打开与发卡器相连的串口!");
return;
}
if (reading) {
reading = false;
reader?.cancel();
}
document.getElementById('butt_openserial').hidden=true;
document.getElementById('butt_closeserial').hidden=true;
}
function ListSendData(senddata,datalen){ //显示串口发送的数据
var sendhex="";
for(i=0;i<datalen;i++){
sendhex=sendhex+senddata[i].toString(16).padStart(2, '0').toUpperCase()+" ";
}
SendData.value=sendhex;
ReceiveData.value="";
var label_disp = document.getElementById('label_disp');
label_disp.innerText = "指令已发送...";
}
function ConnTimeout(){ //通讯超时处理
if(connecting){
ConnectOver()
var label_disp = document.getElementById('label_disp');
label_disp.innerText = "通讯超时!";
}
}
function ConnectOver(){ //通讯已完成
clearInterval(time1);
connecting=false;
SendCode=0;
DataPoint=0;
}
async function getdevicenumber(){
if ((port == null) || (!port.writable)) {
alert("请选择并打开与发卡器相连的串口!");
return;
}
var beepdelay=parseInt(document.getElementById("beepdelay").value);
const outputData = new Uint8Array(5);
outputData[0]=0xaa;
outputData[1]=0xaa;
outputData[2]=0x00;
outputData[3]=0x00;
outputData[4]=0xa5;
ListSendData(outputData,5);
SendCode=1;
DataPoint=0;
const writer = port.writable.getWriter();
await writer.write(outputData); // 发送数据
writer.releaseLock();
time1 = setInterval("ConnTimeout()", 100); //开启100毫秒的通讯超时
connecting=true;
}
async function editdevicenumber(){
if ((port == null) || (!port.writable)) {
alert("请选择并打开与发卡器相连的串口!");
return;
}
var olddevicenum=parseInt(document.getElementById("deviceno").value);
var newdevicenum=parseInt(document.getElementById("newdeviceno").value);
const outputData = new Uint8Array(10);
outputData[0]=0xaa;
outputData[1]=0xaa;
outputData[2]=olddevicenum % 256;
outputData[3]=olddevicenum / 256;
outputData[4]=0xf0;
outputData[5]=newdevicenum % 256;
outputData[6]=newdevicenum / 256;
outputData[7]=outputData[5] ^ 0xff;
outputData[8]=outputData[6] ^ 0xff;
outputData[9]=0x00;
ListSendData(outputData,10);
SendCode=2;
DataPoint=0;
const writer = port.writable.getWriter();
await writer.write(outputData); // 发送数据
writer.releaseLock();
time1 = setInterval("ConnTimeout()",100); //开启100毫秒的通讯超时
connecting=true;
}
async function beep(){
if ((port == null) || (!port.writable)) {
alert("请选择并打开与发卡器相连的串口!");
return;
}
var devicenum=parseInt(document.getElementById("deviceno").value);
var beepdelay=parseInt(document.getElementById("beepdelay").value);
const outputData = new Uint8Array(8);
outputData[0]=0xaa;
outputData[1]=0xaa;
outputData[2]=devicenum % 256;
outputData[3]=devicenum / 256;
outputData[4]=0xc3;
outputData[5]=beepdelay / 256;
outputData[6]=beepdelay % 256;
outputData[7]=outputData[5] ^ outputData[6];
ListSendData(outputData,8);
SendCode=3;
DataPoint=0;
const writer = port.writable.getWriter();
await writer.write(outputData); // 发送数据
writer.releaseLock();
//time1 = setInterval("ConnTimeout()", 100); //开启100毫秒的通讯超时
//connecting=true;
}
async function Request(){
if ((port == null) || (!port.writable)) {
alert("请选择并打开与发卡器相连的串口!");
return;
}
var devicenum=parseInt(document.getElementById("deviceno").value);
const outputData = new Uint8Array(5);
outputData[0]=0xaa;
outputData[1]=0xaa;
outputData[2]=devicenum % 256;
outputData[3]=devicenum / 256;
outputData[4]=0xd2;
ListSendData(outputData,5);
SendCode=4;
DataPoint=0;
const writer = port.writable.getWriter();
await writer.write(outputData); // 发送数据
writer.releaseLock();
time1 = setInterval("ConnTimeout()", 100); //开启100毫秒的通讯超时
connecting=true;
}
async function ReadKey(){
if ((port == null) || (!port.writable)) {
alert("请选择并打开与发卡器相连的串口!");
return;
}
var devicenum=parseInt(document.getElementById("deviceno").value);
const outputData = new Uint8Array(5);
outputData[0]=0xaa;
outputData[1]=0xaa;
outputData[2]=devicenum % 256;
outputData[3]=devicenum / 256;
outputData[4]=0x87;
ListSendData(outputData,5);
SendCode=5;
DataPoint=0;
const writer = port.writable.getWriter();
await writer.write(outputData); // 发送数据
writer.releaseLock();
time1 = setInterval("ConnTimeout()", 100); //开启100毫秒的通讯超时
connecting=true;
}
async function ReadCardKey(){
if ((port == null) || (!port.writable)) {
alert("请选择并打开与发卡器相连的串口!");
return;
}
var devicenum=parseInt(document.getElementById("deviceno").value);
const outputData = new Uint8Array(5);
outputData[0]=0xaa;
outputData[1]=0xaa;
outputData[2]=devicenum % 256;
outputData[3]=devicenum / 256;
outputData[4]=0x69;
ListSendData(outputData,5);
SendCode=6;
DataPoint=0;
const writer = port.writable.getWriter();
await writer.write(outputData); // 发送数据
writer.releaseLock();
time1 = setInterval("ConnTimeout()", 100); //开启100毫秒的通讯超时
connecting=true;
}
async function DispBeep(){
if ((port == null) || (!port.writable)) {
alert("请选择并打开与发卡器相连的串口!");
return;
}
let devicenum=parseInt(document.getElementById("deviceno").value);
let dispstr=document.getElementById("text_dispstr").value+" "; //加入空格是为了能满屏显示
let beeplen=parseInt(document.getElementById("beeplen").value);
let stoplen=parseInt(document.getElementById("stoplen").value);
let beepcount=parseInt(document.getElementById("beepcount").value);
dispasc=GetChineseCode(dispstr);
var outputData = new Uint8Array(39);
outputData[0]=0xaa;
outputData[1]=0xaa;
outputData[2]=devicenum % 256;
outputData[3]=devicenum / 256;
outputData[4]=0x5a;
for(i=0;i<30;i++){
outputData[5+i]=parseInt(dispasc.substr(i*2,2),16);;
}
outputData[35]=beeplen / 20;
outputData[36]=stoplen / 20;
outputData[37]=beepcount;
let crc=0;
for(i=5;i<=37;i++){crc=crc ^ outputData[i];}
outputData[38]=crc;
ListSendData(outputData,39);
SendCode=7;
DataPoint=0;
const writer = port.writable.getWriter();
await writer.write(outputData); // 发送数据
writer.releaseLock();
}
async function editdevicepassword(){
if ((port == null) || (!port.writable)) {
alert("请选择并打开与发卡器相连的串口!");
return;
}
let devicenum=parseInt(document.getElementById("deviceno").value);
let newpassword=document.getElementById("newpassword").value;
if(newpassword.length!=6){
alert("读卡器管理密码必须是6位数字!请输入正确的管理密码。");
document.getElementById("newpassword").focus();
document.getElementById("newpassword").select();
return;
}
var outputData = new Uint8Array(9);
outputData[0]=0xaa;
outputData[1]=0xaa;
outputData[2]=devicenum % 256;
outputData[3]=devicenum / 256;
outputData[4]=0xf;
for(i=0;i<3;i++){
outputData[5+i]=parseInt(newpassword.substr(i*2,2),16);
}
outputData[8]=outputData[5]^outputData[6]^outputData[7];
ListSendData(outputData,9);
SendCode=8;
DataPoint=0;
const writer = port.writable.getWriter();
await writer.write(outputData); // 发送数据
writer.releaseLock();
time1 = setInterval("ConnTimeout()", 100); //开启100毫秒的通讯超时
connecting=true;
}
async function SwitchOn(){
if ((port == null) || (!port.writable)) {
alert("请选择并打开与发卡器相连的串口!");
return;
}
let devicenum=parseInt(document.getElementById("deviceno").value);
let switchdelay=parseInt(document.getElementById("switchdelay").value);
var outputData = new Uint8Array(9);
outputData[0]=0xaa;
outputData[1]=0xaa;
outputData[2]=devicenum % 256;
outputData[3]=devicenum / 256;
outputData[4]=0x1e;
outputData[5]=0xf1;
outputData[6]=switchdelay / 256;
outputData[7]=switchdelay % 256;
outputData[8]=outputData[5]^outputData[6]^outputData[7];
ListSendData(outputData,9);
SendCode=9;
DataPoint=0;
const writer = port.writable.getWriter();
await writer.write(outputData); // 发送数据
writer.releaseLock();
}
async function SwitchOff(){
if ((port == null) || (!port.writable)) {
alert("请选择并打开与发卡器相连的串口!");
return;
}
let devicenum=parseInt(document.getElementById("deviceno").value);
var outputData = new Uint8Array(9);
outputData[0]=0xaa;
outputData[1]=0xaa;
outputData[2]=devicenum % 256;
outputData[3]=devicenum / 256;
outputData[4]=0x1e;
outputData[5]=0xe1;
outputData[6]=0x00;
outputData[7]=0x00;
outputData[8]=outputData[5]^outputData[6]^outputData[7];
ListSendData(outputData,9);
SendCode=10;
DataPoint=0;
const writer = port.writable.getWriter();
await writer.write(outputData); // 发送数据
writer.releaseLock();
}
async function ReadStatus(){
if ((port == null) || (!port.writable)) {
alert("请选择并打开与发卡器相连的串口!");
return;
}
let devicenum=parseInt(document.getElementById("deviceno").value);
if(devicenum==0){
alert("请先输入要读取的机号!");
document.getElementById("deviceno").focus();
document.getElementById("deviceno").select();
return;
}
var outputData = new Uint8Array(5);
outputData[0]=0xaa;
outputData[1]=0xaa;
outputData[2]=devicenum % 256;
outputData[3]=devicenum / 256;
outputData[4]=0x2d;
ListSendData(outputData,5);
SendCode=11;
DataPoint=0;
const writer = port.writable.getWriter();
await writer.write(outputData); // 发送数据
writer.releaseLock();
time1 = setInterval("ConnTimeout()", 100); //开启100毫秒的通讯超时
connecting=true;
}
async function SetDevDateTime(){
if ((port == null) || (!port.writable)) {
alert("请选择并打开与发卡器相连的串口!");
return;
}
let devicenum=parseInt(document.getElementById("deviceno").value);
var outputData = new Uint8Array(13);
outputData[0]=0xaa;
outputData[1]=0xaa;
outputData[2]=devicenum % 256;
outputData[3]=devicenum / 256;
outputData[4]=0x4b;
outputData[5]=parseInt(datetimestr.substr(17,2),16);
outputData[6]=parseInt(datetimestr.substr(14,2),16);
outputData[7]=parseInt(datetimestr.substr(11,2),16);
outputData[8]=parseInt(datetimestr.substr(8,2),16);
outputData[9]=parseInt(datetimestr.substr(5,2),16);
outputData[10]=weekday;
outputData[11]=parseInt(datetimestr.substr(2,2),16);
let crc=0;
for(i=5;i<=11;i++){crc=crc ^ outputData[i];}
outputData[12]=crc;
ListSendData(outputData,13);
SendCode=12;
DataPoint=0;
const writer = port.writable.getWriter();
await writer.write(outputData); // 发送数据
writer.releaseLock();
}
</script>
<style>
th {
font-family:楷体;
background-color:#F6FAFF;
color:blue;
}
td {
font-family:楷体;
background-color:#F6FAFF;
}
</style>
</head>
<body>
<table width="950" height="423" align="center">
<tr>
<td width="120" height="50">
<input name="btnSelect" type="submit" id="btnSelect" style="width:100%" onclick="SelectSerial()" value="选择串口" />
</td>
<td width="800">波特率:<label for="select_btn"></label>
<select name="select_btn" id="select_btn">
<option>1200</option>
<option>4800</option>
<option>9600</option>
<option>14400</option>
<option selected="selected">19200</option>
<option>38400</option>
<option>43000</option>
<option>57600</option>
<option>115200</option>
<option>128000</option>
<option>230400</option>
<option>256000</option>
<option>460800</option>
<option>921600</option>
<option>1382400</option>
</select>
数据位:
<select name="select_btn2" id="select_data">
<option>8</option>
<option>7</option>
<option>6</option>
<option>5</option>
</select>
停止位:
<select name="select_btn3" id="select_stop">
<option>1</option>
<option>1.5</option>
<option>2</option>
</select>
校验位:
<select name="select_btn4" id="select_mark">
<option>None 无</option>
<option>Odd 奇</option>
<option>Even 偶</option>
<option>Mask 常1</option>
<option>Space 常0</option>
</select>
<input name="butt_openserial" type="submit" id="butt_openserial" style="width:80px" onclick="OpenSerial()" value="打开串口" />
<input name="butt_closeserial" type="submit" id="butt_closeserial" style="width:80px" onclick="CloseSerial()" value="关闭串口" />
</td>
</tr>
<tr>
<td height="36">
<input name="butt_getdevnum" type="submit" id="butt_getdevnum" style="width:100%" onclick="getdevicenumber()" value="读取在线设备机号" />
</td>
<td>
设备机号:
<input style="color:red;text-align:center;" name="deviceno" type="text" id="deviceno" value="0" size="5" maxlength="5" onkeyup="this.value=this.value.replace(/\D/g,'')" />
</td>
</tr>
<tr>
<td height="36" >
<input name="butt_beep" type="submit" id="butt_beep" style="width:100%" onclick="beep()" value="驱动发卡器响声" />
</td>
<td>响声延时:
<input style="color:blue;text-align:center;" name="beepdelay" type="text" id="beepdelay" value="30" size="5" maxlength="4" onkeyup="this.value=this.value.replace(/\D/g,'')"/>
毫秒
<input name="butt_changedevnum" type="submit" id="butt_changedevnum" style="width:120px" onclick="editdevicenumber()" value="修改在线设备机号" />
新机号:
<input style="color:blue;text-align:center;" name="newdeviceno" type="text" id="newdeviceno" value="2" size="5" maxlength="5" onkeyup="this.value=this.value.replace(/\D/g,'')" />
<input name="butt_changepassword" type="submit" id="butt_changepassword" style="width:150px" onclick="editdevicepassword()" value="修改在线设备管理密码" />
密码:<input style="color:blue;text-align:center;" name="newpassword" type="text" id="newpassword" value="123456" size="5" maxlength="6" onkeyup="this.value=this.value.replace(/\D/g,'')" />
</td>
</tr>
<tr>
<td height="36"><input name="butt_request" type="submit" id="butt_request" style="width:100%" onclick="Request()" value="驱动读卡器读一次卡" /></td>
<td>
<label style="color:red;" name="label_disp" id="label_disp">请先选择并打开与读卡器相连的串口!</label>
</td>
</tr>
<tr>
<td height="36"></td>
<td></td>
</tr>
<tr>
<td height="36"><input name="butt_readcardkey" type="submit" id="butt_readcardkey" style="width:170px" onclick="ReadCardKey()" value="驱动读卡器读卡号+按键值" /></td>
<td>
<input name="butt_readkey" type="submit" id="butt_readkey" style="width:160px" onclick="ReadKey()" value="驱动读卡器读取按键值" />
<input name="butt_setdatetime" type="submit" id="butt_setdatetime" style="width:120px" onclick="SetDevDateTime()" value="设置读卡器时钟" />
<label style="color:red;" name="label_datetime" id="label_datetime">2024-07-11 10:08:00</label>
</td>
</tr>
<tr>
<td height="36"><input name="butt_disp_beep" type="submit" id="butt_disp_beep" style="width:100%" onclick="DispBeep()" value="驱动读卡器显示+响声" /></td>
<td>显示文字: <input style="color:blue;text-align:left;" name="text_dispstr" type="text" id="text_dispstr" value="感谢您选用我们 的读卡器!" size="34" maxlength="34" />
声长: <input style="color:blue;text-align:center;" name="beeplen" type="text" id="beeplen" value="100" size="5" maxlength="4" onkeyup="this.value=this.value.replace(/\D/g,'')" />
停顿: <input style="color:blue;text-align:center;" name="stoplen" type="text" id="stoplen" value="100" size="5" maxlength="4" onkeyup="this.value=this.value.replace(/\D/g,'')" />
次数: <input style="color:blue;text-align:center;" name="beepcount" type="text" id="beepcount" value="1" size="5" maxlength="4" onkeyup="this.value=this.value.replace(/\D/g,'')" />
</td>
</tr>
<tr>
<td height="36"><input name="butt_switchon" type="submit" id="butt_switchon" style="width:100%" onclick="SwitchOn()" value="驱动读卡器开启继电器" /></td>
<td>
开启延时:
<input style="color:blue;text-align:center;" name="switchdelay" type="text" id="switchdelay" value="30" size="5" maxlength="4" onkeyup="this.value=this.value.replace(/\D/g,'')" />
毫秒
<input name="butt_switchoff" type="submit" id="butt_switchoff" style="width:120px" onclick="SwitchOff()" value="关闭已开启继电器" />
<input name="butt_readstatus" type="submit" id="butt_readstatus" style="width:120px" onclick="ReadStatus()" value="读取设备当前状态" />
</td>
</tr>
<tr>
<td height="70" scope="row"><p align="center">发送的数据</p></td>
<td><textarea style="width:800px;color:blue;" name="SendData" id="SendData" cols="100" rows="4" ></textarea></td>
</tr>
<tr>
<td height="70" scope="row"><p align="center">接收的数据</p></td>
<td><textarea style="width:800px" name="ReceiveData" id="ReceiveData" cols="100" rows="4" ></textarea></td>
</tr>
</table>
</body>
</html>