当前位置: 移动技术网 > IT编程>开发语言>c# > 通过C#实现自动售货机接口

通过C#实现自动售货机接口

2019年07月18日  | 移动技术网IT编程  | 我要评论

下面分几部分介绍c#实现自动售货机接口的方法,代码写的非常详细,不懂的地方有注释可以参考下。

machinejp类:

第1部分:串口初始化,串口数据读写

using system;
using system.collections.generic;
using system.io.ports;
using system.linq;
using system.text;
using system.threading;
using system.threading.tasks;
using system.windows.forms;
using machinejpdll.models;
using machinejpdll.utils;

namespace machinejpdll
{
  /// <summary>
  /// 售货机接口(接口)
  /// </summary>
  public partial class machinejp
  {
    #region 变量
    /// <summary>
    /// 串口资源
    /// </summary>
    private serialport m_serialport = null;
    /// <summary>
    /// 待发送给串口的命令列表
    /// </summary>
    private list<cmd> m_commandlist = new list<cmd>();
    /// <summary>
    /// 等待ack_rpt或nak_rpt的pc端向vmc端发送的消息列表
    /// </summary>
    private list<mt> m_waitresultmtlist = new list<mt>();
    /// <summary>
    /// 从串口接收的数据集合(数据已通过验证)
    /// </summary>
    private receivedatacollection m_receivedatacollection = new receivedatacollection();
    #endregion

    #region 构造函数与析构函数
    /// <summary>
    /// 售货机接口(接口)
    /// </summary>
    public machinejp()
    {

    }

    ~machinejp()
    {
      if (m_serialport != null)
      {
        m_serialport.close();
        m_serialport.dispose();
        m_serialport = null;
      }
    }
    #endregion

    #region 读取串口数据
    /// <summary>
    /// 读取串口数据
    /// </summary>
    /// <returns>从串口读取的数据</returns>
    private byte[] readport()
    {
      //读取串口数据
      datetime dt = datetime.now;
      while (m_serialport.bytestoread < 2)
      {
        thread.sleep(1);

        if (datetime.now.subtract(dt).totalmilliseconds > 1500) //超时
        {
          return new byte[0];
        }
      }
      list<byte> reclist = new list<byte>();
      byte[] recdata = new byte[m_serialport.bytestoread];
      m_serialport.read(recdata, 0, recdata.length);
      reclist.addrange(recdata);
      int length = recdata[1] + 2; //报文数据总长度
      while (reclist.count < length)
      {
        if (m_serialport.bytestoread > 0)
        {
          recdata = new byte[m_serialport.bytestoread];
          m_serialport.read(recdata, 0, recdata.length);
          reclist.addrange(recdata);
        }
        thread.sleep(1);
      }

      return reclist.toarray();
    }
    #endregion

    #region 向串口发送数据
    /// <summary>
    /// 向串口发送数据
    /// </summary>
    /// <param name="cmd">待发送的命令</param>
    /// <param name="sn">序列号</param>
    private void writeport(cmd cmd, byte sn)
    {
      //发送数据
      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>
    /// <param name="sn">序列号</param>
    private void sendack(byte sn)
    {
      list<byte> senddata = new list<byte>() { 0xe5, 0x00, 0x00, 0x40, 0x80 };
      writeport(new cmd(senddata), sn);
    }
    #endregion

    #region init 初始化
    /// <summary>
    /// 初始化
    /// </summary>
    /// <param name="com">串口号(例:com1)</param>
    public void init(string com)
    {
      if (m_serialport == null)
      {
        m_serialport = new serialport(com, 9600, parity.none, 8, stopbits.one);
        m_serialport.readbuffersize = 1024;
        m_serialport.writebuffersize = 1024;
        m_serialport.datareceived += new serialdatareceivedeventhandler(serialport_datareceived);
      }

      if (!m_serialport.isopen)
      {
        m_serialport.open();
      }

      get_setup();
      control_ind(0x13, new byte[] { 0x00 }); //初始化完成标志
      get_status();

      setdecimalplaces(2); //设置小数点位数
    }
    #endregion

    #region close 关闭连接
    /// <summary>
    /// 关闭连接
    /// </summary>
    public void close()
    {
      m_serialport.close();
    }
    #endregion

    #region 接收串口数据
    /// <summary>
    /// 接收串口数据
    /// </summary>
    /// <param name="type">消息类型</param>
    /// <param name="subtype">消息子类型</param>
    public byte[] receive(byte type, byte subtype)
    {
      return m_receivedatacollection.get(type, subtype);
    }

    /// <summary>
    /// 接收串口数据
    /// </summary>
    /// <param name="type">消息类型</param>
    /// <param name="subtype">消息子类型</param>
    public byte[] waitreceive(byte type, byte subtype)
    {
      datetime time = datetime.now;
      while (true)
      {
        byte[] receivedata = m_receivedatacollection.get(type, subtype);
        if (receivedata != null) return receivedata;

        if (datetime.now.subtract(time).totalminutes > 3) return null;

        thread.sleep(50);
      }
    }

    /// <summary>
    /// 接收串口数据
    /// </summary>
    /// <param name="type">消息类型</param>
    public byte[] waitreceive(byte type)
    {
      datetime time = datetime.now;
      while (true)
      {
        byte[] receivedata = m_receivedatacollection.get(type);
        if (receivedata != null) return receivedata;

        if (datetime.now.subtract(time).totalminutes > 3) return null;

        thread.sleep(50);
      }
    }
    #endregion

    #region 判断消息是否发送成功
    /// <summary>
    /// 判断消息是否发送成功
    /// </summary>
    public bool sendsuccess(byte type, byte subtype)
    {
      datetime time = datetime.now;
      while (true)
      {
        if (datetime.now.subtract(time).totalminutes > 3)
        {
          return false;
        }
        byte[] ack = m_receivedatacollection.get(type, subtype);
        byte[] nak = m_receivedatacollection.get(type, subtype);
        if (ack != null) return true;
        if (nak != null) return false;

        thread.sleep(1);
      }
    }
    #endregion

  }
}

第2部分:接收串口数据,并响应货机,向货机发送数据 

 

using system;
using system.collections.generic;
using system.io.ports;
using system.linq;
using system.text;
using machinejpdll.models;
using machinejpdll.utils;

/*
 * vmc->pc数据的接收,货机事件的分发
 */

namespace machinejpdll
{
  partial class machinejp
  {
    #region serialport_datareceived
    /// <summary>
    /// 数据接收事件的方法
    /// </summary>
    public void serialport_datareceived(object obj, serialdatareceivedeventargs args)
    {
      byte[] receivedata = readport();

      if (commonutil.validreceivedata(receivedata)) //只处理验证正确的数据,不正确的数据抛弃不处理
      {
        loghelper.log(logmsgtype.info, false, receivedata);
        byte sn = commonutil.getsn(receivedata);
        mt mt = new mt(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

        #region vmc系统参数
        if (mt.type == 0x05)
        {
          m_receivedatacollection.add(mt.type, mt.subtype, receivedata);
        }
        #endregion

        #region ack_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

        #region info_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

        #region vendout_rpt 出货报告
        if (mt.type == 0x08)
        {
          m_receivedatacollection.add(mt.type, mt.subtype, receivedata);
        }
        #endregion

        #region status_rpt vmc整机状态报告
        if (mt.type == 0x0d)
        {
          m_receivedatacollection.add(mt.type, mt.subtype, receivedata);
        }
        #endregion

        #region saleprice_ind 设置当前商品售价
        if (mt.type == 0x8e)
        {
          m_receivedatacollection.add(mt.type, mt.subtype, receivedata);
        }
        #endregion

        #region payin_rpt vmc发送现金投币报告给pc
        if (mt.type == 0x06)
        {
          m_receivedatacollection.add(mt.type, mt.subtype, receivedata);
        }
        #endregion

        #region payout_rpt 出币报告
        if (mt.type == 0x07)
        {
          m_receivedatacollection.add(mt.type, mt.subtype, receivedata);
        }
        #endregion

        #region cost_rpt vmc扣款报告
        if (mt.type == 0x10)
        {
          m_receivedatacollection.add(mt.type, mt.subtype, receivedata);
        }
        #endregion

        #region action_rpt 售货机行为报告
        if (mt.type == 0x0b)
        {
          m_receivedatacollection.add(mt.type, mt.subtype, receivedata);
        }
        #endregion

        #region huodao_rpt vmc货道报告
        if (mt.type == 0x0e)
        {
          m_receivedatacollection.add(mt.type, mt.subtype, receivedata);
        }
        #endregion
      }
      else //接收到的数据没有验证通过
      {
        loghelper.logexception(logmsgtype.error, false, "数据异常", receivedata);
      }
    }
    #endregion

  }
}

 第3部分:货机状态、投币、出货等接口

using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.threading;
using machinejpdll.enums;
using machinejpdll.models;
using machinejpdll.utils;

/*
 * pc->vmc数据的发送(并非直接发送,只是添加到发送列表)
 */

namespace machinejpdll
{
  partial class machinejp
  {
    #region get_setup
    /// <summary>
    /// pc通知vmc发送vmc_setup
    /// </summary>
    public vmcsetup get_setup()
    {
      list<byte> senddata = new list<byte>() { 0xe5, 0x00, 0x00, 0x40, 0x90 };
      m_commandlist.add(new cmd(senddata));

      byte[] receivedata = waitreceive(0x05);
      if (receivedata != null)
      {
        return new vmcsetup(receivedata);
      }
      return null;
    }
    #endregion

    #region control_ind pc控制售货机完成对应的动作
    /// <summary>
    /// pc控制vmc
    /// </summary>
    public bool control_ind(byte subtype, byte[] value)
    {
      list<byte> senddata = new list<byte>() { 0xe5, 0x00, 0x00, 0x41, 0x85 };
      senddata.add(subtype);
      if (value != null && value.length > 0)
      {
        senddata.addrange(value);
      }
      m_commandlist.add(new cmd(senddata, new mt(senddata)));

      return sendsuccess(0x85, subtype);
    }
    #endregion

    #region 设置小数点位数
    /// <summary>
    /// 设置小数点位数
    /// 用于pc 通知vmc,双方的金额数据比例系数关系,pc 每次启动时,都会给
    /// vmc 下发一次type=18 的消息,vmc 需要自己永久保存该数据,直到被pc 再
    /// 次更新。
    /// 取值范围:0、1、2 分别表示以 元、 角 、分 为单位
    /// </summary>
    public bool setdecimalplaces(int data)
    {
      return control_ind(18, new byte[] { (byte)data });
    }
    #endregion

    #region get_status pc通知vmc发送status_rpt
    /// <summary>
    /// pc通知vmc发送status_rpt
    /// </summary>
    public statusrpt get_status()
    {
      list<byte> senddata = new list<byte>() { 0xe5, 0x00, 0x00, 0x40, 0x86 };
      m_commandlist.add(new cmd(senddata));

      byte[] receivedata = waitreceive(0x0d);
      if (receivedata != null)
      {
        return new statusrpt(receivedata);
      }
      return null;
    }
    #endregion

    #region get_info pc通知vmc发送info_rpt
    /// <summary>
    /// pc通知vmc发送info_rpt
    /// </summary>
    public byte[] get_info(byte subtype)
    {
      list<byte> senddata = new list<byte>() { 0xe5, 0x00, 0x00, 0x40, 0x8c };
      senddata.add(subtype);
      m_commandlist.add(new cmd(senddata));

      return waitreceive(0x11);
    }
    #endregion

    #region vendout_ind 出货
    /// <summary>
    /// pc出货指示
    /// </summary>
    /// <param name="device">售货机的箱体号 例如柜1 为 0x01 以此类推</param>
    /// <param name="method">method =1:vmc 通过商品id 指示出货,如果商品id 不存在,回复nak_rpt method =2:vmc 通过货道id 指示vmc 出货,如果货道id 不存在,回复nak_rpt</param>
    /// <param name="sp_id_hd_id">sp_id:通过商品id 指示vmc 出货 hd_id:通过货道id 指示vmc 出货</param>
    /// <param name="type">如果type=0,cost 代表本次出货扣款金额 如果type 不为0,则cost 必须为0</param>
    /// <param name="cost">cost 代表本次出货扣款金额</param>
    public vendoutrpt vendout_ind(byte device, byte method, byte sp_id_hd_id, byte type, int cost)
    {
      list<byte> senddata = new list<byte>() { 0xe5, 0x00, 0x00, 0x41, 0x83 };
      senddata.addrange(new byte[] { device, method, sp_id_hd_id, type });
      senddata.addrange(commonutil.int2bytearray(cost, 2));
      m_commandlist.add(new cmd(senddata, new mt(senddata)));

      if (sendsuccess(0x83, 0x00))
      {
        byte[] receivedata = waitreceive(0x08);
        if (receivedata != null)
        {
          return new vendoutrpt(receivedata);
        }
      }
      return null;
    }
    #endregion

    #region huodao_set_ind 设置货道商品数量
    /// <summary>
    /// pc通知vmc,当前货道对应商品的数量等信息
    /// </summary>
    /// <param name="device">表示箱柜号</param>
    /// <param name="huodao">zyxxxxxx “z”固定填0 “y”固定填0 “xxxxxx”,表示商品余量,如果商品余量大于63,则统一为63</param>
    public bool huodao_set_ind(byte device, list<int> huodao)
    {
      list<byte> senddata = new list<byte>() { 0xe5, 0x00, 0x00, 0x41, 0x8f };
      senddata.add(device);
      for (int i = 0; i < huodao.count; i++)
      {
        if (huodao[i] > 63)
        {
          huodao[i] = 63;
        }
      }
      senddata.addrange(huodao.convertall<byte>(a => (byte)a));
      m_commandlist.add(new cmd(senddata, new mt(senddata)));

      return sendsuccess(0x8f, 0x00);
    }
    #endregion

    #region saleprice_ind 设置当前商品售价
    /// <summary>
    /// pc通知vmc,当前商品售价
    /// </summary>
    /// <param name="device">表示箱柜号</param>
    /// <param name="type">表示设置单价的方式;type = 0:为按商品id 发送单价,可以变长发送,商品种类最大不超过80 个;type = 1: 为按货道号发送,固定发送80 个货道的单价信息</param>
    /// <param name="sp_price">商品售价</param>
    public bool saleprice_ind(byte device, byte type, list<int> sp_price)
    {
      list<byte> senddata = new list<byte>() { 0xe5, 0x00, 0x00, 0x41, 0x8e };
      senddata.add(device);
      senddata.add(type);
      senddata.addrange(sp_price.convertall<byte>(a => (byte)a));
      m_commandlist.add(new cmd(senddata, new mt(senddata)));

      return sendsuccess(0x8e, 0x00);
    }
    #endregion

    #region payout_ind pc指示vmc出币
    /// <summary>
    /// pc指示vmc出币
    /// </summary>
    /// <param name="device">出币设备</param>
    /// <param name="value">本次出币总金额</param>
    /// <param name="type">出币类型 无需理解type 的含义,只需要在出币完成后的payout_rpt 中将该type 值回传给pc 即可</param>
    public payoutrpt payout_ind(payouttype device, int value, byte type)
    {
      list<byte> senddata = new list<byte>() { 0xe5, 0x00, 0x00, 0x41, 0x89 };
      senddata.add((byte)device);
      senddata.addrange(commonutil.int2bytearray(value, 2));
      senddata.add(type);
      m_commandlist.add(new cmd(senddata, new mt(senddata)));

      if (sendsuccess(0x89, 0x00))
      {
        byte[] receivedata = waitreceive(0x07);
        if (receivedata != null)
        {
          return new payoutrpt(receivedata);
        }
      }
      return null;
    }
    #endregion

    #region cost_ind pc扣款指示
    /// <summary>
    /// pc扣款指示
    /// </summary>
    /// <param name="device">device=0,从用户投币总额中扣款;优先从用户非暂存金额中扣除(纸币尽量滞后压钞),参见《现金扣款顺序》</param>
    /// <param name="value">扣款金额</param>
    /// <param name="type">vmc 不用理解type 的含义,只需上报对应的cost_rpt 时回传即可</param>
    public costrpt cost_ind(byte device, int value, byte type)
    {
      list<byte> senddata = new list<byte>() { 0xe5, 0x00, 0x00, 0x41, 0x8b };
      senddata.add(device);
      senddata.addrange(commonutil.int2bytearray(value, 2));
      senddata.add(type);
      m_commandlist.add(new cmd(senddata, new mt(senddata)));

      if (sendsuccess(0x8b, 0x00))
      {
        byte[] receivedata = waitreceive(0x10);
        if (receivedata != null)
        {
          return new costrpt(receivedata);
        }
      }
      return null;
    }
    #endregion

    #region get_huodao pc通知vmc上报huodao_rpt
    /// <summary>
    /// pc通知vmc上报huodao_rpt
    /// </summary>
    /// <param name="device">箱柜号</param>
    public huodaorpt get_huodao(byte device)
    {
      list<byte> senddata = new list<byte>() { 0xe5, 0x00, 0x00, 0x40, 0x8a };
      senddata.add(device);
      m_commandlist.add(new cmd(senddata));

      byte[] receivedata = waitreceive(0x0e);
      if (receivedata != null)
      {
        return new huodaorpt(receivedata);
      }
      return null;
    }
    #endregion

    #region set_huodao pc发送配置货道信息
    /// <summary>
    /// pc发送配置货道信息
    /// </summary>
    /// <param name="cabinet">箱柜号</param>
    /// <param name="hd_no">货道逻辑编号,十进制</param>
    /// <param name="hd_id">商品id号</param>
    /// <param name="hd_count">货道剩余量</param>
    /// <param name="hd_price">货道单价</param>
    /// <param name="reserved">保留字段vmc忽略此字段,pc最好将此字段置为0</param>
    public bool set_huodao(byte cabinet, int hd_no, int hd_id, int hd_count, int hd_price, int reserved = 0)
    {
      list<byte> senddata = new list<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(new cmd(senddata, new mt(senddata)));

      return sendsuccess(0x93, 0x00);
    }
    #endregion

    #region 开启纸硬币器
    /// <summary>
    /// 现金收银模组(纸币器、硬币器)开关
    /// </summary>
    /// <param name="open">true:开,false:关</param>
    public bool ctrlcoinpaper(bool open)
    {
      if (open)
      {
        return control_ind(2, new byte[] { 1 });
      }
      else
      {
        return control_ind(2, new byte[] { 0 });
      }
    }
    #endregion

    #region 找零
    /// <summary>
    /// 找零
    /// 与手工拨弄物理找零开关相同
    /// </summary>
    public bool makechange()
    {
      return control_ind(6, new byte[] { 0 });
    }
    #endregion

    #region 获取硬币器信息
    /// <summary>
    /// 获取硬币器信息
    /// </summary>
    public inforpt_17 getcoininfo()
    {
      return new inforpt_17(get_info(17));
    }
    #endregion

    #region 获取纸币器信息
    /// <summary>
    /// 获取纸币器信息
    /// </summary>
    public inforpt_16 getpaperinfo()
    {
      return new inforpt_16(get_info(16));
    }
    #endregion

    #region 获取现金投币报告
    /// <summary>
    /// 获取现金投币报告
    /// </summary>
    public payinrpt getpayinrpt()
    {
      byte[] receivedata = receive(0x06, 0x00);
      if (receivedata != null)
      {
        return new payinrpt(receivedata);
      }
      return null;
    }
    #endregion

    #region 获取用户投币余额
    /// <summary>
    /// 获取用户投币余额
    /// </summary>
    public inforpt_3 getremaideramount()
    {
      byte[] receivedata = waitreceive(0x11, 0x003);
      if (receivedata != null)
      {
        return new inforpt_3(receivedata);
      }
      return null;
    }
    #endregion

  }
}

receivedatacollection类和receivedata类: 

 

using system;
using system.collections.generic;
using system.linq;
using system.text;

namespace machinejpdll.models
{
  /// <summary>
  /// 从串口接收到的数据(数据已通过验证)
  /// </summary>
  public class receivedata
  {
    /// <summary>
    /// 从串口接收到的数据(数据已通过验证)
    /// </summary>
    public byte[] data { get; set; }
    /// <summary>
    /// 添加到集合receivedatacollection的时间
    /// </summary>
    public datetime addtime { get; set; }
    /// <summary>
    /// 消息类型
    /// </summary>
    public byte type { get; set; }
    /// <summary>
    /// 消息子类型
    /// </summary>
    public byte subtype { get; set; }

    /// <summary>
    /// 从串口接收到的数据(数据已通过验证)
    /// </summary>
    /// <param name="type">消息类型</param>
    /// <param name="subtype">消息子类型</param>
    /// <param name="data">从串口接收到的数据(数据已通过验证)</param>
    /// <param name="addtime">添加到集合receivedatacollection的时间</param>
    public receivedata(byte type, byte subtype, byte[] data, datetime addtime)
    {
      this.type = type;
      this.subtype = subtype;
      this.data = data;
      this.addtime = addtime;
    }
  }
}
using system;
using system.collections.generic;
using system.linq;
using system.text;

namespace machinejpdll.models
{
  /// <summary>
  /// 从串口接收到的数据集合(数据已通过验证)
  /// </summary>
  public class receivedatacollection
  {
    /// <summary>
    /// 从串口接收到的数据集合(数据已通过验证)
    /// </summary>
    private list<receivedata> m_receivedatalist = new list<receivedata>();
    /// <summary>
    /// 数据过期时间
    /// </summary>
    private int m_timeout = 3;
    private static object _lock = new object();

    /// <summary>
    /// 添加到集合
    /// </summary>
    /// <param name="type">消息类型</param>
    /// <param name="subtype">消息子类型</param>
    /// <param name="data">从串口接收到的数据(数据已通过验证)</param>
    public void add(byte type, byte subtype, byte[] data)
    {
      lock (_lock)
      {
        receivedata receivedata = new receivedata(type, subtype, data, datetime.now);
        m_receivedatalist.add(receivedata);
        for (int i = m_receivedatalist.count - 1; i >= 0; i--)
        {
          if (datetime.now.subtract(m_receivedatalist[i].addtime).totalminutes > m_timeout)
          {
            m_receivedatalist.removeat(i);
          }
        }
      }
    }

    /// <summary>
    /// 从集合中获取串口接收到的数据(数据已通过验证)
    /// </summary>
    /// <param name="type">消息类型</param>
    /// <param name="subtype">消息子类型</param>
    /// <returns>从串口接收到的数据(数据已通过验证)</returns>
    public byte[] get(byte type, byte subtype)
    {
      lock (_lock)
      {
        receivedata receivedata = null;
        for (int i = 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);
            return receivedata.data;
          }
        }
        return null;
      }
    }

    /// <summary>
    /// 从集合中获取串口接收到的数据(数据已通过验证)
    /// </summary>
    /// <param name="type">消息类型</param>
    /// <returns>从串口接收到的数据(数据已通过验证)</returns>
    public byte[] get(byte type)
    {
      lock (_lock)
      {
        receivedata receivedata = null;
        for (int i = 0; i < m_receivedatalist.count; i++)
        {
          if (m_receivedatalist[i].type == type)
          {
            receivedata = m_receivedatalist[i];
            m_receivedatalist.removeat(i);
            return receivedata.data;
          }
        }
        return null;
      }
    }
  }
}

models:

statusrpt类:

using system;
using system.collections.generic;
using system.linq;
using system.text;
using machinejpdll;
using machinejpdll.enums;
using machinejpdll.utils;

namespace machinejpdll.models
{
  /// <summary>
  /// vmc状态报告
  /// </summary>
  public class statusrpt
  {
    /// <summary>
    /// 从串口读取的通过验证的数据
    /// </summary>
    private byte[] m_data;

    /// <summary>
    /// vmc状态报告
    /// </summary>
    /// <param name="data">从串口读取的通过验证的数据</param>
    public statusrpt(byte[] data)
    {
      m_data = data;
    }

    public override string tostring()
    {
      stringbuilder sb = new stringbuilder();
      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);

      return sb.tostring();
    }

    /// <summary>
    /// 出货检测设备状态
    /// </summary>
    public checkst check_st
    {
      get
      {
        byte val = m_data[5];
        return (checkst)commonutil.getfrombyte(val, 0, 2);
      }
    }

    /// <summary>
    /// 纸币器状态
    /// </summary>
    public devicest bv_st
    {
      get
      {
        byte val = m_data[5];
        return (devicest)commonutil.getfrombyte(val, 2, 2);
      }
    }

    /// <summary>
    /// 硬币器状态
    /// </summary>
    public devicest cc_st
    {
      get
      {
        byte val = m_data[5];
        return (devicest)commonutil.getfrombyte(val, 4, 2);
      }
    }

    /// <summary>
    /// vmc状态
    /// </summary>
    public vmcst vmc_st
    {
      get
      {
        byte val = m_data[5];
        return (vmcst)commonutil.getfrombyte(val, 6, 2);
      }
    }

    /// <summary>
    /// 展示位状态
    /// </summary>
    public list<devicest> pos_st
    {
      get
      {
        list<devicest> devicestlist = new list<devicest>();

        byte val = m_data[6];
        for (int i = 0; i < 4; i++)
        {
          devicest devicest = (devicest)commonutil.getfrombyte(val, i * 2, 2);
          devicestlist.add(devicest);
        }

        return devicestlist;
      }
    }

    /// <summary>
    /// 机器中,可用的找零量总金额(包括硬币和纸币)
    /// </summary>
    public int change
    {
      get
      {
        return commonutil.bytearray2int(m_data, 7, 2);
      }
    }

    /// <summary>
    /// 货仓1 温度,8 位有符号数,该温度通过货仓内传感器获取,单位:℃
    /// </summary>
    public temsub tem1
    {
      get
      {
        return new temsub(m_data[9]);
      }
    }

    /// <summary>
    /// 货仓2 温度,8 位有符号数,该温度通过货仓内传感器获取,单位:℃
    /// </summary>
    public temsub tem2
    {
      get
      {
        return new temsub(m_data[10]);
      }
    }

    /// <summary>
    /// 货仓3 温度,8 位有符号数,该温度通过货仓内传感器获取,单位:℃
    /// </summary>
    public temsub tem3
    {
      get
      {
        return new temsub(m_data[11]);
      }
    }

    /// <summary>
    /// 货仓4 温度,8 位有符号数,该温度通过货仓内传感器获取,单位:℃
    /// </summary>
    public temsub tem4
    {
      get
      {
        return new temsub(m_data[12]);
      }
    }

    /// <summary>
    /// 货仓状态设置值,共支持4 个货仓
    /// </summary>
    public list<temst> tem_st
    {
      get
      {
        list<temst> temstlist = new list<temst>();
        for (int i = 0; i < 4; i++)
        {
          temst temst = (temst)commonutil.getfrombyte(m_data[13], i * 2, 2);
          temstlist.add(temst);
        }
        return temstlist;
      }
    }

    /// <summary>
    /// 自动退币时间。
    /// 0:表示商品出货后,立即自动退币
    /// 255:表示永不自动退币
    /// 1-254:表示商品出货后,自动退币时间(单位:秒)
    /// </summary>
    public int 自动退币
    {
      get
      {
        return m_data[14];
      }
    }

    /// <summary>
    /// 找零余量“找零量1#”…“找零量6#”,分别对应硬币器信息info_rpt.type=17 的“找零
    /// 1#”…“找零6#”中每种钱币的找零数量;
    /// * 找零量最大为255,超过255 时上报为255;
    /// * 找零量单位为“个”,代表可找零硬币的个数。
    /// </summary>
    public int 找零余量1
    {
      get
      {
        return m_data[15];
      }
    }

    /// <summary>
    /// 找零余量“找零量1#”…“找零量6#”,分别对应硬币器信息info_rpt.type=17 的“找零
    /// 1#”…“找零6#”中每种钱币的找零数量;
    /// * 找零量最大为255,超过255 时上报为255;
    /// * 找零量单位为“个”,代表可找零硬币的个数。
    /// </summary>
    public int 找零余量2
    {
      get
      {
        return m_data[16];
      }
    }

    /// <summary>
    /// 找零余量“找零量1#”…“找零量6#”,分别对应硬币器信息info_rpt.type=17 的“找零
    /// 1#”…“找零6#”中每种钱币的找零数量;
    /// * 找零量最大为255,超过255 时上报为255;
    /// * 找零量单位为“个”,代表可找零硬币的个数。
    /// </summary>
    public int 找零余量3
    {
      get
      {
        return m_data[17];
      }
    }

    /// <summary>
    /// 找零余量“找零量1#”…“找零量6#”,分别对应硬币器信息info_rpt.type=17 的“找零
    /// 1#”…“找零6#”中每种钱币的找零数量;
    /// * 找零量最大为255,超过255 时上报为255;
    /// * 找零量单位为“个”,代表可找零硬币的个数。
    /// </summary>
    public int 找零余量4
    {
      get
      {
        return m_data[18];
      }
    }

    /// <summary>
    /// 找零余量“找零量1#”…“找零量6#”,分别对应硬币器信息info_rpt.type=17 的“找零
    /// 1#”…“找零6#”中每种钱币的找零数量;
    /// * 找零量最大为255,超过255 时上报为255;
    /// * 找零量单位为“个”,代表可找零硬币的个数。
    /// </summary>
    public int 找零余量5
    {
      get
      {
        return m_data[19];
      }
    }

    /// <summary>
    /// 找零余量“找零量1#”…“找零量6#”,分别对应硬币器信息info_rpt.type=17 的“找零
    /// 1#”…“找零6#”中每种钱币的找零数量;
    /// * 找零量最大为255,超过255 时上报为255;
    /// * 找零量单位为“个”,代表可找零硬币的个数。
    /// </summary>
    public int 找零余量6
    {
      get
      {
        return m_data[20];
      }
    }

  }
}

以上就是c#实现自动售货机接口的代码,需要的朋友可以来学习。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网