最近在弄一个投币器的插件,使用的是威佛微脉冲式投币器WF-700-RELAY。
c++项目WF-700-RELAY:
头文件:WF-700-RELAY.h
#ifndef __WF700RELAY_H__
#define __WF700RELAY_H__
#define CINTERFACEAPI extern "C" __declspec(dllexport)
#include <string>
#include <Windows.h>
#include <tchar.h>
#include <cstddef>
#include <cstdlib>
#include <cassert>
class WF700RELAY
{
public:
WF700RELAY(char* configPath);
~WF700RELAY();
BOOL openWF700RELAY(char* result);
BOOL closeWF700RELAY(char* result);
BOOL writeToWF700RELAY(char* result);
BOOL readFromWF700RELAY(char* result);
int getCoinCount();
void setCoinCount();
void resetCoinCount();
void Dispose();
private:
HANDLE m_hComm; // 通信设备
std::string m_portNum; // 串口号
DWORD m_dwBaudRate; // 波特率
BYTE m_byteSize; // 数据位
BYTE m_parityBit; // 校验位
BYTE m_stopBit; // 停止位
int m_coinCount; // 投币数
bool m_bOpen; // 串口开关标志
};
CINTERFACEAPI WF700RELAY* Init(char* configPath);
CINTERFACEAPI void Dispose(void* pWF700RELAYManager);
CINTERFACEAPI BOOL openWF700RELAY(void* pWF700RELAYManager,char* result);
CINTERFACEAPI BOOL closeWF700RELAY(void* pWF700RELAYManager,char* result);
CINTERFACEAPI BOOL writeToWF700RELAY(void* pWF700RELAYManager,char* result);
CINTERFACEAPI BOOL readFromWF700RELAY(void* pWF700RELAYManager,char* result);
CINTERFACEAPI int getCoinCount(void* pWF700RELAYManager);
CINTERFACEAPI void setCoinCount(void* pWF700RELAYManager);
CINTERFACEAPI void resetCoinCount(void* pWF700RELAYManager);
#endif // !__WF700RELAY_H__
源文件:WF-700-RELAY.cpp
#include "WF-700-RELAY.h"
WF700RELAY::WF700RELAY(char* configPath)
{
int iLength;
TCHAR WF700RELAY_CFGPATH[MAX_PATH];
iLength = MultiByteToWideChar (CP_ACP, 0, configPath, strlen (configPath) + 1, NULL, 0);
MultiByteToWideChar (CP_ACP, 0, configPath, strlen (configPath) + 1, WF700RELAY_CFGPATH, iLength);
//读取配置文件
int ComPort;
ComPort = GetPrivateProfileInt(L"WF700RELAY", L"ComPort", 0, WF700RELAY_CFGPATH);
char port[32] = {0};
sprintf(port,"\\\\.\\COM%d",ComPort);
m_portNum = port; // 串口号
m_dwBaudRate = 9600; // 波特率
m_byteSize = 8; // 数据位
m_parityBit = NOPARITY; // 检验位
m_stopBit = ONESTOPBIT; // 停止位
m_bOpen = false;
m_coinCount = 0;
}
WF700RELAY::~WF700RELAY()
{
}
BOOL WF700RELAY::openWF700RELAY(char* result)
{
m_hComm = CreateFileA(m_portNum.c_str(),
GENERIC_READ | GENERIC_WRITE, //允许读和写
0, //独占方式
NULL,
OPEN_EXISTING, //打开而不是创建
0, //同步方式
NULL
);
PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_TXABORT | PURGE_TXABORT);
std::string szRes;
char szBuf[256] = { 0 };
if (m_hComm == INVALID_HANDLE_VALUE)
{
sprintf_s(szBuf,"Open %s Failed,The Error Code: %d", m_portNum.c_str(), GetLastError());
szRes.append(szBuf);
strcpy(result,const_cast<char*>(szRes.c_str()));
return false;
}
else
{
SetupComm(m_hComm, 8192, 8192); // 设置读写缓冲区大小
COMMTIMEOUTS TimeOuts; //设定读超时
TimeOuts.ReadIntervalTimeout = MAXDWORD;
TimeOuts.ReadTotalTimeoutMultiplier = 0;
TimeOuts.ReadTotalTimeoutConstant = 0; //设定写超时
TimeOuts.WriteTotalTimeoutMultiplier = 500;
TimeOuts.WriteTotalTimeoutConstant = 2000;
SetCommTimeouts(m_hComm, &TimeOuts); //设置超时
DCB dcb;
//SetupComm(m_hComm, MAX_BUFFER_SIZE, MAX_BUFFER_SIZE); // 设置读写缓冲区大小
GetCommState(m_hComm, &dcb);
dcb.BaudRate = m_dwBaudRate;
dcb.ByteSize = m_byteSize;
dcb.Parity = m_parityBit;
dcb.StopBits = m_stopBit;
if (!SetCommState(m_hComm, &dcb))
{
sprintf_s(szBuf,"Serial Port Setting Failed,The Error Code: %d", GetLastError());
szRes.append(szBuf);
strcpy(result,const_cast<char*>(szRes.c_str()));
return false;
}
}
//在读写串口前,用 PurgeComm 函数清空缓冲区
PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_TXABORT | PURGE_TXABORT);
m_bOpen = true;
szRes.append("Open WF-700-RELAY Success!");
strcpy(result,const_cast<char*>(szRes.c_str()));
return true;
}
BOOL WF700RELAY::closeWF700RELAY(char* result)
{
assert(m_bOpen);
bool ret = CloseHandle(m_hComm);
std::string szRes;
if (ret == FALSE)
{
char szBuf[256] = { 0 };
sprintf_s(szBuf,"Close WF-700-RELAY Failed,The Error Code:%d", GetLastError());
szRes.append(szBuf);
strcpy(result,const_cast<char*>(szRes.c_str()));
return false;
}
else
{
szRes.append("Close WF-700-RELAY Success!");
strcpy(result,const_cast<char*>(szRes.c_str()));
m_bOpen = false;
return true;
}
}
BOOL WF700RELAY::writeToWF700RELAY(char* result)
{
assert(m_bOpen);
BYTE data[] = {0x02,0x08,0x10,0x00,0x10,0x00,0x03,0x08};
DWORD dwError = 0;
if (ClearCommError(m_hComm, &dwError, NULL) && dwError > 0)
{
PurgeComm(m_hComm, PURGE_TXABORT | PURGE_TXCLEAR);
}
DWORD dwTx = 0;
BOOL ret = FALSE;
ret = WriteFile(m_hComm, data, sizeof(data), &dwTx, NULL);
if (ret == FALSE)
{
std::string szRes;
char szBuf[256] = { 0 };
sprintf_s(szBuf,"Data Writing Failure,The Error Code:%d", GetLastError());
szRes.append(szBuf);
strcpy(result,const_cast<char*>(szRes.c_str()));
return false;
}
return true;
}
BOOL WF700RELAY::readFromWF700RELAY(char* result)
{
assert(m_bOpen);
COMSTAT comStat;
DWORD dwError = 0;
if (ClearCommError(m_hComm, &dwError, &comStat) && dwError > 0)
{
PurgeComm(m_hComm, PURGE_RXABORT | PURGE_RXCLEAR);
}
DWORD dwRx = 0; // 读入的字节数
BOOL ret = FALSE;
BYTE byReadData[1024] = {0};
memset(byReadData, 0, sizeof(byReadData));
ret = ReadFile(m_hComm, byReadData, 1024, &dwRx, NULL); // 读入数据
std::string szRes;
char szBuf[256] = { 0 };
if (ret == TRUE)
{
if ((BYTE)(byReadData[3]) == 0x10)
{
m_coinCount++;
}
sprintf_s(szBuf,"Current Coin Offerings:%d", m_coinCount);
szRes.append(szBuf);
strcpy(result,const_cast<char*>(szRes.c_str()));
return true;
}
else
{
sprintf_s(szBuf,"Data Read Failure, The Error Code:%d", GetLastError());
szRes.append(szBuf);
strcpy(result,const_cast<char*>(szRes.c_str()));
return false;
}
}
int WF700RELAY::getCoinCount()
{
return m_coinCount;
}
void WF700RELAY::setCoinCount()
{
m_coinCount -= 1;
}
void WF700RELAY::resetCoinCount()
{
m_coinCount = 0;
}
void WF700RELAY::Dispose()
{
if (m_bOpen)
{
char res[256] = {0};
closeWF700RELAY(res);
}
}
CINTERFACEAPI WF700RELAY* Init(char* configPath)
{
WF700RELAY* pWF700RELAYManager = new WF700RELAY(configPath);
return pWF700RELAYManager;
}
CINTERFACEAPI void Dispose(void* pWF700RELAYManager)
{
WF700RELAY* mWF700RELAYManager = (WF700RELAY*)pWF700RELAYManager;
mWF700RELAYManager->Dispose();
}
CINTERFACEAPI BOOL openWF700RELAY(void* pWF700RELAYManager, char* result)
{
WF700RELAY* mWF700RELAYManager = (WF700RELAY*)pWF700RELAYManager;
return mWF700RELAYManager->openWF700RELAY(result);
}
CINTERFACEAPI BOOL closeWF700RELAY(void* pWF700RELAYManager,char* result)
{
WF700RELAY* mWF700RELAYManager = (WF700RELAY*)pWF700RELAYManager;
return mWF700RELAYManager->closeWF700RELAY(result);
}
CINTERFACEAPI BOOL writeToWF700RELAY(void* pWF700RELAYManager,char* result)
{
WF700RELAY* mWF700RELAYManager = (WF700RELAY*)pWF700RELAYManager;
return mWF700RELAYManager->writeToWF700RELAY(result);
}
CINTERFACEAPI BOOL readFromWF700RELAY(void* pWF700RELAYManager,char* result)
{
WF700RELAY* mWF700RELAYManager = (WF700RELAY*)pWF700RELAYManager;
return mWF700RELAYManager->readFromWF700RELAY(result);
}
CINTERFACEAPI int getCoinCount(void* pWF700RELAYManager)
{
WF700RELAY* mWF700RELAYManager = (WF700RELAY*)pWF700RELAYManager;
return mWF700RELAYManager->getCoinCount();
}
CINTERFACEAPI void setCoinCount(void* pWF700RELAYManager)
{
WF700RELAY* mWF700RELAYManager = (WF700RELAY*)pWF700RELAYManager;
mWF700RELAYManager->setCoinCount();
}
CINTERFACEAPI void resetCoinCount(void* pWF700RELAYManager)
{
WF700RELAY* mWF700RELAYManager = (WF700RELAY*)pWF700RELAYManager;
mWF700RELAYManager->resetCoinCount();
}
C#项目:WF-700-RELAY-Manager
WF_700_RELAY_Native.cs
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace WF_700_RELAY_Manager
{
internal class WF_700_RELAY_Native
{
internal const string WF700RELAY = "WF-700-RELAY";
[DllImport(WF700RELAY)]
internal static extern IntPtr Init(string configPath);
[DllImport(WF700RELAY)]
internal static extern void Dispose(IntPtr pWF700RELAY);
[DllImport(WF700RELAY)]
internal static extern bool openWF700RELAY(IntPtr pWF700RELAY, StringBuilder result);
[DllImport(WF700RELAY)]
internal static extern bool closeWF700RELAY(IntPtr pWF700RELAY, StringBuilder result);
[DllImport(WF700RELAY)]
internal static extern bool writeToWF700RELAY(IntPtr pWF700RELAY, StringBuilder result);
[DllImport(WF700RELAY)]
internal static extern bool readFromWF700RELAY(IntPtr pWF700RELAY, StringBuilder result);
[DllImport(WF700RELAY)]
internal static extern int getCoinCount(IntPtr pWF700RELAY);
[DllImport(WF700RELAY)]
internal static extern void setCoinCount(IntPtr pWF700RELAY);
[DllImport(WF700RELAY)]
internal static extern void resetCoinCount(IntPtr pWF700RELAY);
}
}
WF700RELAYManager.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace WF_700_RELAY_Manager
{
/// <summary>
/// 威佛微投币器管理者
/// </summary>
public class WF700RELAYManager
{
private IntPtr pWF700RELAY = IntPtr.Zero;
/// <summary>
/// 初始化
/// </summary>
/// <param name="configPath">配置文件路径</param>
public void Init(string configPath)
{
pWF700RELAY = WF_700_RELAY_Native.Init(configPath);
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose()
{
WF_700_RELAY_Native.Dispose(pWF700RELAY);
pWF700RELAY = IntPtr.Zero;
}
/// <summary>
/// 打开威佛微投币器
/// </summary>
/// <param name="result">操作失败提示信息</param>
/// <returns>true代表成功,false代表失败</returns>
public bool openWF700RELAY(StringBuilder result)
{
return WF_700_RELAY_Native.openWF700RELAY(pWF700RELAY, result);
}
/// <summary>
/// 关闭威佛微投币器
/// </summary>
/// <param name="result">操作失败提示信息</param>
/// <returns>true代表成功,false代表失败</returns>
public bool closeWF700RELAY(StringBuilder result)
{
return WF_700_RELAY_Native.closeWF700RELAY(pWF700RELAY, result);
}
/// <summary>
/// 向威佛微投币器发送消息
/// </summary>
/// <param name="result">操作失败提示信息</param>
/// <returns>true代表成功,false代表失败</returns>
public bool writeToWF700RELAY(StringBuilder result)
{
return WF_700_RELAY_Native.writeToWF700RELAY(pWF700RELAY, result);
}
/// <summary>
/// 从威佛微投币器读取消息
/// </summary>
/// <param name="result">操作失败提示信息</param>
/// <returns>true代表成功,false代表失败</returns>
public bool readFromWF700RELAY(StringBuilder result)
{
return WF_700_RELAY_Native.readFromWF700RELAY(pWF700RELAY, result);
}
/// <summary>
/// 获取投币数
/// </summary>
/// <returns>返回当前投币数</returns>
public int getCoinCount()
{
return WF_700_RELAY_Native.getCoinCount(pWF700RELAY);
}
/// <summary>
/// 设置投币数
/// </summary>
public void setCoinCount()
{
WF_700_RELAY_Native.setCoinCount(pWF700RELAY);
}
/// <summary>
/// 重置投币数
/// </summary>
public void resetCoinCount()
{
WF_700_RELAY_Native.resetCoinCount(pWF700RELAY);
}
}
}
config配置文件格式:
文件名:WF700RELAY.ini
文件内容:
[WF700RELAY]
ComPort=10
记录一下,仅供参考,ComPort为设备端口号。
威佛微脉冲式投币器WF-700-RELAY中文使用说明书.pdf
注:在Win10可能会由于驱动问题导致无法打开COM端口,需要安装旧版的驱动 PL2303_Prolific_DriverInstaller_v110.exe
可以看看这个帖子 https://jingyan.baidu.com/article/3d69c551585b89f0cf02d7b2.html