在这里谦卑地说,我认为这个会让我变得愚蠢,但是......我正试图将一个古老的收银机程序转换为.net。征服了其他一切,但我无法打开收银机。它连接到COM1,你应该向COM1发送一个“触发”文本,这将导致寄存器打开。
这是.net代码。
MsgBox("Opening Drawer")
Dim port As System.IO.Ports.SerialPort
port = New System.IO.Ports.SerialPort("Com1")
port.PortName = "COM1"
port.BaudRate = 9600
port.Parity = IO.Ports.Parity.None
port.DataBits = 8
port.StopBits = IO.Ports.StopBits.One
'port.Handshake = IO.Ports.Handshake.RequestToSend
port.RtsEnable = True
'port.DtrEnable = True
port.Open()
If port.IsOpen Then
'MsgBox("Attempt 1")
port.Write("@@@@@@@@@@@@@@@@@@@@")
MsgBox("Signal Sent: " & Chr(65))
Else
MsgBox("Port is not open")
End If
port.Close()
MsgBox("Pop, durn it!")
我得到msgboxes“Signal Sent”,“Done Pop Drawer”
当事,只是不会流行。这是一个MS-Cash Drawer(EP125KC)。绝对连接到COM1,绝对有力量。 Chr(65)是用于弹出抽屉的旧代码,它起作用:Open drawerComPort For Output Access Write As #1
Print #1, Chr$(65); "A";
Close #1
注意:上面的代码成功运行。根本问题是由一个受到尊敬的电源线引起的(负面是错误的一面)。
感谢所有帮助人员!
答案 0 :(得分:1)
您已将握手设置为无,但现金抽屉可能有自己的想法。同时将DtrEnable设置为True。 Chr(65)是“A”的ASCII码,你的VB代码表明真正的命令是“AA”。
现金抽屉自动调整其波特率的手册文件。它建议发送至少20个@字符。并且真正的命令是Ctrl + G(Chr(7))。由于波特率不匹配,“AA”命令可能先前有效。也许
答案 1 :(得分:0)
如果我记得我的非常生锈的 BASIC。
Print #1, Chr$(65); "A";
表示打印到port1,字符65后跟字符串“A”,现在字符65为'A',所以这对我来说就像你应该向port1发送“AA”
port.Write("AA");
或者,
port.Write(new byte[]{65,'A'}, 0, 2);
答案 2 :(得分:0)
您确定要发送此代码吗?我一直认为代码以ESC为前缀,即0x1b十六进制......用于现金抽屉......
"\x1bA"
有趣的是使用了双倍'A'......哦......:)
编辑:在想到这一点后,我意识到还有另一种方法,请继续阅读......
我已经修改了原始的BASIC代码并进行了一些防弹......将其保存到opendrawer.bas
Sub OpenDrawer() drawerComPort = "COM1" Open drawerComPort For Output Access Write As #1 REM ADDED ERROR HANDLING ON ERROR GOTO ErrHandler Print #1, Chr$(65); "A"; Close #1 print "Drawer Ok" OpenDrawer_Exit: On Error Goto 0 Exit Sub ErrHandler: print "Oops, Write Failed" Goto OpenDrawer_Exit End Sub REM The Main.... OpenDrawer
下载旧的QB4.5 MS-Quick Basic编译器,并将其编译为可执行文件,进入opendrawer.exe
,可以找到QB4.5 here。现在,你有责任使这个防弹,即如果写入COM1失败会发生什么,发出一个消息,如我修改的示例BASIC代码
然后你可以使用System.Diagnostics.Process
使用隐藏窗口进行炮轰
public class TestDrawer { private StringBuilder sbRedirectedOutput = new StringBuilder(); public string OutputData { get { return this.sbRedirectedOutput.ToString(); } } public void Run() { System.Diagnostics.ProcessStartInfo ps = new System.Diagnostics.ProcessStartInfo(); ps.FileName = "opendrawer"; ps.ErrorDialog = false; ps.CreateNoWindow = true; ps.UseShellExecute = false; ps.RedirectStandardOutput = true; ps.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; using (System.Diagnostics.Process proc = new System.Diagnostics.Process()) { proc.StartInfo = ps; proc.Exited += new EventHandler(proc_Exited); proc.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(proc_OutputDataReceived); proc.Start(); proc.WaitForExit(); proc.BeginOutputReadLine(); while (!proc.HasExited) ; } } void proc_Exited(object sender, EventArgs e) { System.Diagnostics.Debug.WriteLine("proc_Exited: Process Ended"); if (this.sbRedirectedOutput.ToString().IndexOf("Oops, write failed") > -1){ MessageBox.Show(this, "Error in opening Cash Drawer"); } if (this.sbRedirectedOutput.ToString().IndexOf("Drawer Ok") > -1){ MessageBox.Show(this, "Drawer Ok"); } } void proc_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e) { if (e.Data != null) this.sbRedirectedOutput.Append(e.Data + Environment.NewLine); //System.Diagnostics.Debug.WriteLine("proc_OutputDataReceived: Data: " + e.Data); }
进程弹出一个隐藏的窗口,所有输出都被重定向并在事件处理程序中处理......这应该可以解决问题。请注意,重定向输出如何进入sbRedirectedOutput
(StringBuilder实例)。在proc_ProcExited
事件处理程序中,它检查sbRedirectedOutput
以查找将从QB4.5程序发出的消息'Oops Write failed'。
请注意,您可能需要将QB4.5的运行时库包含在同一目录中...不是100%确定...这是多年......
您怎么看?
希望这有帮助, 最好的祝福, 汤姆。
答案 3 :(得分:0)
它可能正在发送Unicode 65,这将是0065,这不会很好。
只是想一想,你能尝试发送一个原始的int吗?
答案 4 :(得分:0)
我不使用.net,但端口缓冲了吗?你需要发送flush / fflush()吗?