通过C#实现自动售货机接口
下面分几部分介绍C#实现自动售货机接口的方法,代码写的非常详细,不懂的地方有注释可以参考下。
MachineJP类:
第1部分:串口初始化,串口数据读写
usingSystem;
usingSystem.Collections.Generic;
usingSystem.IO.Ports;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading;
usingSystem.Threading.Tasks;
usingSystem.Windows.Forms;
usingMachineJPDll.Models;
usingMachineJPDll.Utils;
namespaceMachineJPDll
{
///<summary>
///售货机接口(接口)
///</summary>
publicpartialclassMachineJP
{
#region变量
///<summary>
///串口资源
///</summary>
privateSerialPortm_SerialPort=null;
///<summary>
///待发送给串口的命令列表
///</summary>
privateList<Cmd>m_CommandList=newList<Cmd>();
///<summary>
///等待ACK_RPT或NAK_RPT的PC端向VMC端发送的消息列表
///</summary>
privateList<MT>m_WaitResultMTList=newList<MT>();
///<summary>
///从串口接收的数据集合(数据已通过验证)
///</summary>
privateReceiveDataCollectionm_ReceiveDataCollection=newReceiveDataCollection();
#endregion
#region构造函数与析构函数
///<summary>
///售货机接口(接口)
///</summary>
publicMachineJP()
{
}
~MachineJP()
{
if(m_SerialPort!=null)
{
m_SerialPort.Close();
m_SerialPort.Dispose();
m_SerialPort=null;
}
}
#endregion
#region读取串口数据
///<summary>
///读取串口数据
///</summary>
///<returns>从串口读取的数据</returns>
privatebyte[]ReadPort()
{
//读取串口数据
DateTimedt=DateTime.Now;
while(m_SerialPort.BytesToRead<2)
{
Thread.Sleep(1);
if(DateTime.Now.Subtract(dt).TotalMilliseconds>1500)//超时
{
returnnewbyte[0];
}
}
List<byte>recList=newList<byte>();
byte[]recData=newbyte[m_SerialPort.BytesToRead];
m_SerialPort.Read(recData,0,recData.Length);
recList.AddRange(recData);
intlength=recData[1]+2;//报文数据总长度
while(recList.Count<length)
{
if(m_SerialPort.BytesToRead>0)
{
recData=newbyte[m_SerialPort.BytesToRead];
m_SerialPort.Read(recData,0,recData.Length);
recList.AddRange(recData);
}
Thread.Sleep(1);
}
returnrecList.ToArray();
}
#endregion
#region向串口发送数据
///<summary>
///向串口发送数据
///</summary>
///<paramname="cmd">待发送的命令</param>
///<paramname="SN">序列号</param>
privatevoidWritePort(Cmdcmd,byteSN)
{
//发送数据
List<byte>sendData=cmd.Data;
sendData[1]=(byte)sendData.Count;
sendData[2]=SN;
byte[]checkCode=CommonUtil.CalCheckCode(sendData,sendData.Count);
sendData.AddRange(checkCode);
if(cmd.Mt!=null)
{
m_WaitResultMTList.Add(cmd.Mt);
}
m_SerialPort.Write(sendData.ToArray(),0,sendData.Count);
LogHelper.Log(LogMsgType.Info,true,sendData.ToArray());
}
#endregion
#region发送ACK消息
///<summary>
///发送ACK消息
///</summary>
///<paramname="SN">序列号</param>
privatevoidSendACK(byteSN)
{
List<byte>sendData=newList<byte>(){0xE5,0x00,0x00,0x40,0x80};
WritePort(newCmd(sendData),SN);
}
#endregion
#regionInit初始化
///<summary>
///初始化
///</summary>
///<paramname="com">串口号(例:COM1)</param>
publicvoidInit(stringcom)
{
if(m_SerialPort==null)
{
m_SerialPort=newSerialPort(com,9600,Parity.None,8,StopBits.One);
m_SerialPort.ReadBufferSize=1024;
m_SerialPort.WriteBufferSize=1024;
m_SerialPort.DataReceived+=newSerialDataReceivedEventHandler(serialPort_DataReceived);
}
if(!m_SerialPort.IsOpen)
{
m_SerialPort.Open();
}
GET_SETUP();
CONTROL_IND(0x13,newbyte[]{0x00});//初始化完成标志
GET_STATUS();
SetDecimalPlaces(2);//设置小数点位数
}
#endregion
#regionClose关闭连接
///<summary>
///关闭连接
///</summary>
publicvoidClose()
{
m_SerialPort.Close();
}
#endregion
#region接收串口数据
///<summary>
///接收串口数据
///</summary>
///<paramname="type">消息类型</param>
///<paramname="subtype">消息子类型</param>
publicbyte[]Receive(bytetype,bytesubtype)
{
returnm_ReceiveDataCollection.Get(type,subtype);
}
///<summary>
///接收串口数据
///</summary>
///<paramname="type">消息类型</param>
///<paramname="subtype">消息子类型</param>
publicbyte[]WaitReceive(bytetype,bytesubtype)
{
DateTimetime=DateTime.Now;
while(true)
{
byte[]receiveData=m_ReceiveDataCollection.Get(type,subtype);
if(receiveData!=null)returnreceiveData;
if(DateTime.Now.Subtract(time).TotalMinutes>3)returnnull;
Thread.Sleep(50);
}
}
///<summary>
///接收串口数据
///</summary>
///<paramname="type">消息类型</param>
publicbyte[]WaitReceive(bytetype)
{
DateTimetime=DateTime.Now;
while(true)
{
byte[]receiveData=m_ReceiveDataCollection.Get(type);
if(receiveData!=null)returnreceiveData;
if(DateTime.Now.Subtract(time).TotalMinutes>3)returnnull;
Thread.Sleep(50);
}
}
#endregion
#region判断消息是否发送成功
///<summary>
///判断消息是否发送成功
///</summary>
publicboolSendSuccess(bytetype,bytesubtype)
{
DateTimetime=DateTime.Now;
while(true)
{
if(DateTime.Now.Subtract(time).TotalMinutes>3)
{
returnfalse;
}
byte[]ack=m_ReceiveDataCollection.Get(type,subtype);
byte[]nak=m_ReceiveDataCollection.Get(type,subtype);
if(ack!=null)returntrue;
if(nak!=null)returnfalse;
Thread.Sleep(1);
}
}
#endregion
}
}
第2部分:接收串口数据,并响应货机,向货机发送数据
usingSystem;
usingSystem.Collections.Generic;
usingSystem.IO.Ports;
usingSystem.Linq;
usingSystem.Text;
usingMachineJPDll.Models;
usingMachineJPDll.Utils;
/*
*VMC->PC数据的接收,货机事件的分发
*/
namespaceMachineJPDll
{
partialclassMachineJP
{
#regionserialPort_DataReceived
///<summary>
///数据接收事件的方法
///</summary>
publicvoidserialPort_DataReceived(objectobj,SerialDataReceivedEventArgsargs)
{
byte[]receiveData=ReadPort();
if(CommonUtil.ValidReceiveData(receiveData))//只处理验证正确的数据,不正确的数据抛弃不处理
{
LogHelper.Log(LogMsgType.Info,false,receiveData);
byteSN=CommonUtil.GetSN(receiveData);
MTmt=newMT(receiveData);
#region轮询(POLL)
if(mt.Type==0x03)
{
if(m_CommandList.Count>0)
{
WritePort(m_CommandList[0],SN);
m_CommandList.RemoveAt(0);
}
else
{
//发送ACK消息
SendACK(SN);
}
}
#endregion
#region发送ACK消息
if(CommonUtil.NeedACK(receiveData))
{
SendACK(SN);//发送ACK消息
}
#endregion
#regionVMC系统参数
if(mt.Type==0x05)
{
m_ReceiveDataCollection.Add(mt.Type,mt.Subtype,receiveData);
}
#endregion
#regionACK_RPT或NAK_RPT
if(mt.Type==0x01//ACK_RPT
||mt.Type==0x02)//NAK_RPT
{
if(m_WaitResultMTList.Count>0)
{
m_ReceiveDataCollection.Add(m_WaitResultMTList[0].Type,m_WaitResultMTList[0].Subtype,receiveData);
m_WaitResultMTList.RemoveAt(0);
}
}
#endregion
#regionINFO_RPT数据报告
if(mt.Type==0x11)
{
#region纸币器信息
if(mt.Subtype==16)
{
m_ReceiveDataCollection.Add(mt.Type,mt.Subtype,receiveData);
}
#endregion
#region硬币器信息
if(mt.Subtype==17)
{
m_ReceiveDataCollection.Add(mt.Type,mt.Subtype,receiveData);
}
#endregion
#region用户投币余额
if(mt.Subtype==3)
{
m_ReceiveDataCollection.Add(mt.Type,mt.Subtype,receiveData);
}
#endregion
}
#endregion
#regionVENDOUT_RPT出货报告
if(mt.Type==0x08)
{
m_ReceiveDataCollection.Add(mt.Type,mt.Subtype,receiveData);
}
#endregion
#regionSTATUS_RPTVMC整机状态报告
if(mt.Type==0x0D)
{
m_ReceiveDataCollection.Add(mt.Type,mt.Subtype,receiveData);
}
#endregion
#regionSALEPRICE_IND设置当前商品售价
if(mt.Type==0x8E)
{
m_ReceiveDataCollection.Add(mt.Type,mt.Subtype,receiveData);
}
#endregion
#regionPAYIN_RPTVMC发送现金投币报告给PC
if(mt.Type==0x06)
{
m_ReceiveDataCollection.Add(mt.Type,mt.Subtype,receiveData);
}
#endregion
#regionPAYOUT_RPT出币报告
if(mt.Type==0x07)
{
m_ReceiveDataCollection.Add(mt.Type,mt.Subtype,receiveData);
}
#endregion
#regionCOST_RPTVMC扣款报告
if(mt.Type==0x10)
{
m_ReceiveDataCollection.Add(mt.Type,mt.Subtype,receiveData);
}
#endregion
#regionACTION_RPT售货机行为报告
if(mt.Type==0x0B)
{
m_ReceiveDataCollection.Add(mt.Type,mt.Subtype,receiveData);
}
#endregion
#regionHUODAO_RPTVMC货道报告
if(mt.Type==0x0E)
{
m_ReceiveDataCollection.Add(mt.Type,mt.Subtype,receiveData);
}
#endregion
}
else//接收到的数据没有验证通过
{
LogHelper.LogException(LogMsgType.Error,false,"数据异常",receiveData);
}
}
#endregion
}
}
第3部分:货机状态、投币、出货等接口
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading;
usingMachineJPDll.Enums;
usingMachineJPDll.Models;
usingMachineJPDll.Utils;
/*
*PC->VMC数据的发送(并非直接发送,只是添加到发送列表)
*/
namespaceMachineJPDll
{
partialclassMachineJP
{
#regionGET_SETUP
///<summary>
///PC通知VMC发送VMC_SETUP
///</summary>
publicVmcSetupGET_SETUP()
{
List<byte>sendData=newList<byte>(){0xE5,0x00,0x00,0x40,0x90};
m_CommandList.Add(newCmd(sendData));
byte[]receiveData=WaitReceive(0x05);
if(receiveData!=null)
{
returnnewVmcSetup(receiveData);
}
returnnull;
}
#endregion
#regionCONTROL_INDPC控制售货机完成对应的动作
///<summary>
///PC控制VMC
///</summary>
publicboolCONTROL_IND(bytesubtype,byte[]value)
{
List<byte>sendData=newList<byte>(){0xE5,0x00,0x00,0x41,0x85};
sendData.Add(subtype);
if(value!=null&&value.Length>0)
{
sendData.AddRange(value);
}
m_CommandList.Add(newCmd(sendData,newMT(sendData)));
returnSendSuccess(0x85,subtype);
}
#endregion
#region设置小数点位数
///<summary>
///设置小数点位数
///用于PC通知VMC,双方的金额数据比例系数关系,PC每次启动时,都会给
///VMC下发一次type=18的消息,VMC需要自己永久保存该数据,直到被PC再
///次更新。
///取值范围:0、1、2分别表示以元、角、分为单位
///</summary>
publicboolSetDecimalPlaces(intdata)
{
returnCONTROL_IND(18,newbyte[]{(byte)data});
}
#endregion
#regionGET_STATUSPC通知VMC发送STATUS_RPT
///<summary>
///PC通知VMC发送STATUS_RPT
///</summary>
publicStatusRptGET_STATUS()
{
List<byte>sendData=newList<byte>(){0xE5,0x00,0x00,0x40,0x86};
m_CommandList.Add(newCmd(sendData));
byte[]receiveData=WaitReceive(0x0D);
if(receiveData!=null)
{
returnnewStatusRpt(receiveData);
}
returnnull;
}
#endregion
#regionGET_INFOPC通知VMC发送INFO_RPT
///<summary>
///PC通知VMC发送INFO_RPT
///</summary>
publicbyte[]GET_INFO(bytesubtype)
{
List<byte>sendData=newList<byte>(){0xE5,0x00,0x00,0x40,0x8C};
sendData.Add(subtype);
m_CommandList.Add(newCmd(sendData));
returnWaitReceive(0x11);
}
#endregion
#regionVENDOUT_IND出货
///<summary>
///PC出货指示
///</summary>
///<paramname="device">售货机的箱体号例如柜1为0x01以此类推</param>
///<paramname="method">method=1:VMC通过商品ID指示出货,如果商品ID不存在,回复NAK_RPTmethod=2:VMC通过货道ID指示VMC出货,如果货道ID不存在,回复NAK_RPT</param>
///<paramname="sp_id_hd_id">sp_id:通过商品ID指示VMC出货hd_id:通过货道ID指示VMC出货</param>
///<paramname="type">如果type=0,cost代表本次出货扣款金额如果TYPE不为0,则COST必须为0</param>
///<paramname="cost">cost代表本次出货扣款金额</param>
publicVendoutRptVENDOUT_IND(bytedevice,bytemethod,bytesp_id_hd_id,bytetype,intcost)
{
List<byte>sendData=newList<byte>(){0xE5,0x00,0x00,0x41,0x83};
sendData.AddRange(newbyte[]{device,method,sp_id_hd_id,type});
sendData.AddRange(CommonUtil.Int2ByteArray(cost,2));
m_CommandList.Add(newCmd(sendData,newMT(sendData)));
if(SendSuccess(0x83,0x00))
{
byte[]receiveData=WaitReceive(0x08);
if(receiveData!=null)
{
returnnewVendoutRpt(receiveData);
}
}
returnnull;
}
#endregion
#regionHUODAO_SET_IND设置货道商品数量
///<summary>
///PC通知VMC,当前货道对应商品的数量等信息
///</summary>
///<paramname="device">表示箱柜号</param>
///<paramname="huodao">zyxxxxxx“z”固定填0“y”固定填0“xxxxxx”,表示商品余量,如果商品余量大于63,则统一为63</param>
publicboolHUODAO_SET_IND(bytedevice,List<int>huodao)
{
List<byte>sendData=newList<byte>(){0xE5,0x00,0x00,0x41,0x8F};
sendData.Add(device);
for(inti=0;i<huodao.Count;i++)
{
if(huodao[i]>63)
{
huodao[i]=63;
}
}
sendData.AddRange(huodao.ConvertAll<byte>(a=>(byte)a));
m_CommandList.Add(newCmd(sendData,newMT(sendData)));
returnSendSuccess(0x8F,0x00);
}
#endregion
#regionSALEPRICE_IND设置当前商品售价
///<summary>
///PC通知VMC,当前商品售价
///</summary>
///<paramname="device">表示箱柜号</param>
///<paramname="type">表示设置单价的方式;Type=0:为按商品ID发送单价,可以变长发送,商品种类最大不超过80个;Type=1:为按货道号发送,固定发送80个货道的单价信息</param>
///<paramname="sp_price">商品售价</param>
publicboolSALEPRICE_IND(bytedevice,bytetype,List<int>sp_price)
{
List<byte>sendData=newList<byte>(){0xE5,0x00,0x00,0x41,0x8E};
sendData.Add(device);
sendData.Add(type);
sendData.AddRange(sp_price.ConvertAll<byte>(a=>(byte)a));
m_CommandList.Add(newCmd(sendData,newMT(sendData)));
returnSendSuccess(0x8E,0x00);
}
#endregion
#regionPAYOUT_INDPC指示VMC出币
///<summary>
///PC指示VMC出币
///</summary>
///<paramname="device">出币设备</param>
///<paramname="value">本次出币总金额</param>
///<paramname="type">出币类型无需理解type的含义,只需要在出币完成后的PAYOUT_RPT中将该type值回传给PC即可</param>
publicPayoutRptPAYOUT_IND(PayoutTypedevice,intvalue,bytetype)
{
List<byte>sendData=newList<byte>(){0xE5,0x00,0x00,0x41,0x89};
sendData.Add((byte)device);
sendData.AddRange(CommonUtil.Int2ByteArray(value,2));
sendData.Add(type);
m_CommandList.Add(newCmd(sendData,newMT(sendData)));
if(SendSuccess(0x89,0x00))
{
byte[]receiveData=WaitReceive(0x07);
if(receiveData!=null)
{
returnnewPayoutRpt(receiveData);
}
}
returnnull;
}
#endregion
#regionCOST_INDPC扣款指示
///<summary>
///PC扣款指示
///</summary>
///<paramname="device">device=0,从用户投币总额中扣款;优先从用户非暂存金额中扣除(纸币尽量滞后压钞),参见《现金扣款顺序》</param>
///<paramname="value">扣款金额</param>
///<paramname="type">VMC不用理解type的含义,只需上报对应的COST_RPT时回传即可</param>
publicCostRptCOST_IND(bytedevice,intvalue,bytetype)
{
List<byte>sendData=newList<byte>(){0xE5,0x00,0x00,0x41,0x8B};
sendData.Add(device);
sendData.AddRange(CommonUtil.Int2ByteArray(value,2));
sendData.Add(type);
m_CommandList.Add(newCmd(sendData,newMT(sendData)));
if(SendSuccess(0x8B,0x00))
{
byte[]receiveData=WaitReceive(0x10);
if(receiveData!=null)
{
returnnewCostRpt(receiveData);
}
}
returnnull;
}
#endregion
#regionGET_HUODAOPC通知VMC上报HUODAO_RPT
///<summary>
///PC通知VMC上报HUODAO_RPT
///</summary>
///<paramname="device">箱柜号</param>
publicHuoDaoRptGET_HUODAO(bytedevice)
{
List<byte>sendData=newList<byte>(){0xE5,0x00,0x00,0x40,0x8A};
sendData.Add(device);
m_CommandList.Add(newCmd(sendData));
byte[]receiveData=WaitReceive(0x0E);
if(receiveData!=null)
{
returnnewHuoDaoRpt(receiveData);
}
returnnull;
}
#endregion
#regionSET_HUODAOPC发送配置货道信息
///<summary>
///PC发送配置货道信息
///</summary>
///<paramname="Cabinet">箱柜号</param>
///<paramname="hd_no">货道逻辑编号,十进制</param>
///<paramname="Hd_id">商品ID号</param>
///<paramname="Hd_count">货道剩余量</param>
///<paramname="Hd_price">货道单价</param>
///<paramname="Reserved">保留字段VMC忽略此字段,PC最好将此字段置为0</param>
publicboolSET_HUODAO(byteCabinet,inthd_no,intHd_id,intHd_count,intHd_price,intReserved=0)
{
List<byte>sendData=newList<byte>(){0xE5,0x00,0x00,0x41,0x93};
sendData.Add(Cabinet);
sendData.Add((byte)hd_no);
sendData.Add((byte)Hd_id);
sendData.Add((byte)Hd_count);
sendData.AddRange(CommonUtil.Int2ByteArray(Hd_price,2));
sendData.AddRange(CommonUtil.Int2ByteArray(Reserved,2));
m_CommandList.Add(newCmd(sendData,newMT(sendData)));
returnSendSuccess(0x93,0x00);
}
#endregion
#region开启纸硬币器
///<summary>
///现金收银模组(纸币器、硬币器)开关
///</summary>
///<paramname="open">true:开,false:关</param>
publicboolCtrlCoinPaper(boolopen)
{
if(open)
{
returnCONTROL_IND(2,newbyte[]{1});
}
else
{
returnCONTROL_IND(2,newbyte[]{0});
}
}
#endregion
#region找零
///<summary>
///找零
///与手工拨弄物理找零开关相同
///</summary>
publicboolMakeChange()
{
returnCONTROL_IND(6,newbyte[]{0});
}
#endregion
#region获取硬币器信息
///<summary>
///获取硬币器信息
///</summary>
publicInfoRpt_17GetCoinInfo()
{
returnnewInfoRpt_17(GET_INFO(17));
}
#endregion
#region获取纸币器信息
///<summary>
///获取纸币器信息
///</summary>
publicInfoRpt_16GetPaperInfo()
{
returnnewInfoRpt_16(GET_INFO(16));
}
#endregion
#region获取现金投币报告
///<summary>
///获取现金投币报告
///</summary>
publicPayinRptGetPayinRpt()
{
byte[]receiveData=Receive(0x06,0x00);
if(receiveData!=null)
{
returnnewPayinRpt(receiveData);
}
returnnull;
}
#endregion
#region获取用户投币余额
///<summary>
///获取用户投币余额
///</summary>
publicInfoRpt_3GetRemaiderAmount()
{
byte[]receiveData=WaitReceive(0x11,0x003);
if(receiveData!=null)
{
returnnewInfoRpt_3(receiveData);
}
returnnull;
}
#endregion
}
}
ReceiveDataCollection类和ReceiveData类:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
namespaceMachineJPDll.Models
{
///<summary>
///从串口接收到的数据(数据已通过验证)
///</summary>
publicclassReceiveData
{
///<summary>
///从串口接收到的数据(数据已通过验证)
///</summary>
publicbyte[]Data{get;set;}
///<summary>
///添加到集合ReceiveDataCollection的时间
///</summary>
publicDateTimeAddTime{get;set;}
///<summary>
///消息类型
///</summary>
publicbyteType{get;set;}
///<summary>
///消息子类型
///</summary>
publicbyteSubtype{get;set;}
///<summary>
///从串口接收到的数据(数据已通过验证)
///</summary>
///<paramname="type">消息类型</param>
///<paramname="subtype">消息子类型</param>
///<paramname="data">从串口接收到的数据(数据已通过验证)</param>
///<paramname="addTime">添加到集合ReceiveDataCollection的时间</param>
publicReceiveData(bytetype,bytesubtype,byte[]data,DateTimeaddTime)
{
this.Type=type;
this.Subtype=subtype;
this.Data=data;
this.AddTime=addTime;
}
}
}
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
namespaceMachineJPDll.Models
{
///<summary>
///从串口接收到的数据集合(数据已通过验证)
///</summary>
publicclassReceiveDataCollection
{
///<summary>
///从串口接收到的数据集合(数据已通过验证)
///</summary>
privateList<ReceiveData>m_ReceiveDataList=newList<ReceiveData>();
///<summary>
///数据过期时间
///</summary>
privateintm_Timeout=3;
privatestaticobject_lock=newobject();
///<summary>
///添加到集合
///</summary>
///<paramname="type">消息类型</param>
///<paramname="subtype">消息子类型</param>
///<paramname="data">从串口接收到的数据(数据已通过验证)</param>
publicvoidAdd(bytetype,bytesubtype,byte[]data)
{
lock(_lock)
{
ReceiveDatareceiveData=newReceiveData(type,subtype,data,DateTime.Now);
m_ReceiveDataList.Add(receiveData);
for(inti=m_ReceiveDataList.Count-1;i>=0;i--)
{
if(DateTime.Now.Subtract(m_ReceiveDataList[i].AddTime).TotalMinutes>m_Timeout)
{
m_ReceiveDataList.RemoveAt(i);
}
}
}
}
///<summary>
///从集合中获取串口接收到的数据(数据已通过验证)
///</summary>
///<paramname="type">消息类型</param>
///<paramname="subtype">消息子类型</param>
///<returns>从串口接收到的数据(数据已通过验证)</returns>
publicbyte[]Get(bytetype,bytesubtype)
{
lock(_lock)
{
ReceiveDatareceiveData=null;
for(inti=0;i<m_ReceiveDataList.Count;i++)
{
if(m_ReceiveDataList[i].Type==type&&m_ReceiveDataList[i].Subtype==subtype)
{
receiveData=m_ReceiveDataList[i];
m_ReceiveDataList.RemoveAt(i);
returnreceiveData.Data;
}
}
returnnull;
}
}
///<summary>
///从集合中获取串口接收到的数据(数据已通过验证)
///</summary>
///<paramname="type">消息类型</param>
///<returns>从串口接收到的数据(数据已通过验证)</returns>
publicbyte[]Get(bytetype)
{
lock(_lock)
{
ReceiveDatareceiveData=null;
for(inti=0;i<m_ReceiveDataList.Count;i++)
{
if(m_ReceiveDataList[i].Type==type)
{
receiveData=m_ReceiveDataList[i];
m_ReceiveDataList.RemoveAt(i);
returnreceiveData.Data;
}
}
returnnull;
}
}
}
}
Models:
StatusRpt类:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingMachineJPDll;
usingMachineJPDll.Enums;
usingMachineJPDll.Utils;
namespaceMachineJPDll.Models
{
///<summary>
///VMC状态报告
///</summary>
publicclassStatusRpt
{
///<summary>
///从串口读取的通过验证的数据
///</summary>
privatebyte[]m_data;
///<summary>
///VMC状态报告
///</summary>
///<paramname="data">从串口读取的通过验证的数据</param>
publicStatusRpt(byte[]data)
{
m_data=data;
}
publicoverridestringToString()
{
StringBuildersb=newStringBuilder();
sb.AppendFormat("出货检测设备状态:{0}\r\n",check_st.ToString());
sb.AppendFormat("纸币器状态:{0}\r\n",bv_st.ToString());
sb.AppendFormat("硬币器状态:{0}\r\n",cc_st.ToString());
sb.AppendFormat("VMC状态:{0}\r\n",vmc_st.ToString());
sb.AppendFormat("展示位状态:{0}{1}{2}{3}\r\n",pos_st[0].ToString(),pos_st[1].ToString(),pos_st[2].ToString(),pos_st[3].ToString());
sb.AppendFormat("机器中可用的找零量总金额(包括硬币和纸币):{0}\r\n",change.ToString());
sb.AppendFormat("货仓1货仓2货仓3货仓4温度:{0}{1}{2}{3}\r\n",tem1.ToString(),tem2.ToString(),tem3.ToString(),tem4.ToString());
sb.AppendFormat("货仓状态设置值:{0}{1}{2}{3}\r\n",tem_st[0].ToString(),tem_st[1].ToString(),tem_st[2].ToString(),tem_st[3].ToString());
if(this.自动退币==255)
{
sb.AppendFormat("自动退币时间:永不自动退币\r\n");
}
else
{
sb.AppendFormat("自动退币时间:{0}\r\n",自动退币.ToString());
}
sb.AppendFormat("找零余量(1#--6#):{0}{1}{2}{3}{4}{5}\r\n",this.找零余量1,this.找零余量2,this.找零余量3,this.找零余量4,this.找零余量5,this.找零余量6);
returnsb.ToString();
}
///<summary>
///出货检测设备状态
///</summary>
publicCheckStcheck_st
{
get
{
byteval=m_data[5];
return(CheckSt)CommonUtil.GetFromByte(val,0,2);
}
}
///<summary>
///纸币器状态
///</summary>
publicDeviceStbv_st
{
get
{
byteval=m_data[5];
return(DeviceSt)CommonUtil.GetFromByte(val,2,2);
}
}
///<summary>
///硬币器状态
///</summary>
publicDeviceStcc_st
{
get
{
byteval=m_data[5];
return(DeviceSt)CommonUtil.GetFromByte(val,4,2);
}
}
///<summary>
///VMC状态
///</summary>
publicVmcStvmc_st
{
get
{
byteval=m_data[5];
return(VmcSt)CommonUtil.GetFromByte(val,6,2);
}
}
///<summary>
///展示位状态
///</summary>
publicList<DeviceSt>pos_st
{
get
{
List<DeviceSt>deviceStList=newList<DeviceSt>();
byteval=m_data[6];
for(inti=0;i<4;i++)
{
DeviceStdeviceSt=(DeviceSt)CommonUtil.GetFromByte(val,i*2,2);
deviceStList.Add(deviceSt);
}
returndeviceStList;
}
}
///<summary>
///机器中,可用的找零量总金额(包括硬币和纸币)
///</summary>
publicintchange
{
get
{
returnCommonUtil.ByteArray2Int(m_data,7,2);
}
}
///<summary>
///货仓1温度,8位有符号数,该温度通过货仓内传感器获取,单位:℃
///</summary>
publicTemSubtem1
{
get
{
returnnewTemSub(m_data[9]);
}
}
///<summary>
///货仓2温度,8位有符号数,该温度通过货仓内传感器获取,单位:℃
///</summary>
publicTemSubtem2
{
get
{
returnnewTemSub(m_data[10]);
}
}
///<summary>
///货仓3温度,8位有符号数,该温度通过货仓内传感器获取,单位:℃
///</summary>
publicTemSubtem3
{
get
{
returnnewTemSub(m_data[11]);
}
}
///<summary>
///货仓4温度,8位有符号数,该温度通过货仓内传感器获取,单位:℃
///</summary>
publicTemSubtem4
{
get
{
returnnewTemSub(m_data[12]);
}
}
///<summary>
///货仓状态设置值,共支持4个货仓
///</summary>
publicList<TemSt>tem_st
{
get
{
List<TemSt>temStList=newList<TemSt>();
for(inti=0;i<4;i++)
{
TemSttemSt=(TemSt)CommonUtil.GetFromByte(m_data[13],i*2,2);
temStList.Add(temSt);
}
returntemStList;
}
}
///<summary>
///自动退币时间。
///0:表示商品出货后,立即自动退币
///255:表示永不自动退币
///1-254:表示商品出货后,自动退币时间(单位:秒)
///</summary>
publicint自动退币
{
get
{
returnm_data[14];
}
}
///<summary>
///找零余量“找零量1#”…“找零量6#”,分别对应硬币器信息INFO_RPT.type=17的“找零
///1#”…“找零6#”中每种钱币的找零数量;
///*找零量最大为255,超过255时上报为255;
///*找零量单位为“个”,代表可找零硬币的个数。
///</summary>
publicint找零余量1
{
get
{
returnm_data[15];
}
}
///<summary>
///找零余量“找零量1#”…“找零量6#”,分别对应硬币器信息INFO_RPT.type=17的“找零
///1#”…“找零6#”中每种钱币的找零数量;
///*找零量最大为255,超过255时上报为255;
///*找零量单位为“个”,代表可找零硬币的个数。
///</summary>
publicint找零余量2
{
get
{
returnm_data[16];
}
}
///<summary>
///找零余量“找零量1#”…“找零量6#”,分别对应硬币器信息INFO_RPT.type=17的“找零
///1#”…“找零6#”中每种钱币的找零数量;
///*找零量最大为255,超过255时上报为255;
///*找零量单位为“个”,代表可找零硬币的个数。
///</summary>
publicint找零余量3
{
get
{
returnm_data[17];
}
}
///<summary>
///找零余量“找零量1#”…“找零量6#”,分别对应硬币器信息INFO_RPT.type=17的“找零
///1#”…“找零6#”中每种钱币的找零数量;
///*找零量最大为255,超过255时上报为255;
///*找零量单位为“个”,代表可找零硬币的个数。
///</summary>
publicint找零余量4
{
get
{
returnm_data[18];
}
}
///<summary>
///找零余量“找零量1#”…“找零量6#”,分别对应硬币器信息INFO_RPT.type=17的“找零
///1#”…“找零6#”中每种钱币的找零数量;
///*找零量最大为255,超过255时上报为255;
///*找零量单位为“个”,代表可找零硬币的个数。
///</summary>
publicint找零余量5
{
get
{
returnm_data[19];
}
}
///<summary>
///找零余量“找零量1#”…“找零量6#”,分别对应硬币器信息INFO_RPT.type=17的“找零
///1#”…“找零6#”中每种钱币的找零数量;
///*找零量最大为255,超过255时上报为255;
///*找零量单位为“个”,代表可找零硬币的个数。
///</summary>
publicint找零余量6
{
get
{
returnm_data[20];
}
}
}
}
以上就是C#实现自动售货机接口的代码,需要的朋友可以来学习。