Abrindo uma gaveta do MS-Cash, código errado? Código ruim?
-
19-09-2019 - |
Pergunta
Expiente humilhante aqui e acho que este fará um bobo de mim, mas ... estou tentando converter um antigo programa de caixa registradora para .NET. Conquistou todo o resto, mas não consigo abrir a caixa registradora. Está conectado ao COM1, você deve enviar um texto "gatilho" com 1 que fará com que o registro seja aberto.
Aqui está o código .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!")
Eu recebo msgboxes "sinal enviado", "gaveta pop"
Coisa, simplesmente não vai aparecer. É uma gaveta do MS-Cash (EP125KC). Definitivamente conectado ao COM1, definitivamente tem poder. CHR (65) é o código antigo usado para a gaveta pop e funciona:
Open drawerComPort For Output Access Write As #1
Print #1, Chr$(65); "A";
Close #1
Nota: O código acima funcionou com sucesso. O problema da raiz foi causado por um cabo de alimentação reverenciado (negativo estava do lado errado).
Obrigado por toda a ajuda pessoal!
Solução
Você definiu seu aperto de mão para ninguém, exceto a gaveta de dinheiro provavelmente tem sua própria idéia. Também defina dttrenable como true. Chr (65) é o código ASCII para um "A", seu código VB sugere que o comando real é "AA".
O manual documenta que a gaveta de dinheiro ajusta automaticamente seu baudrate. Recomenda enviar pelo menos 20 caracteres @. E que o comando real é Ctrl+G (Chr (7)). O comando "AA" pode ter funcionado anteriormente devido a uma incompatibilidade Baudrate. Talvez.
Outras dicas
Se eu me lembro do meu muito enferrujado Básico.
Print #1, Chr$(65); "A";
significa imprimir para porta1 o personagem 65 seguido pela string "a", agora o personagem 65 é 'a', então isso me parece que você deveria estar enviando "aa" para porta1
port.Write("AA");
ou alternadamente,
port.Write(new byte[]{65,'A'}, 0, 2);
Pode estar enviando Unicode 65, que seria 0065, o que não terminaria bem.
Apenas um pensamento, você pode tentar enviar um Int Raw?
Eu não uso .NET, mas a porta é tamponada? você precisa enviar um flush/fflush ()?
Tem certeza de que deve enviar este código? Eu sempre pensaria que o código é prefixado pelo ESC IE 0x1b hexadecimal ... para gavetas em dinheiro ...
"\x1bA"
Interessante que o dobro 'a' seja usado ... oh bem ... :)
Editar: Depois de pensar nisso, percebi que há outra maneira de fazê-lo, continue lendo ... eu modifiquei seu código básico original com um pouco de prova de balas ... salve-o para 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
Baixe o antigo compilador básico QB4.5 MS-Quick e compile para um executável, em opendrawer.exe
, o qb4.5 pode ser encontrado aqui. Agora, o ônus está em você para fazer essa prova de balas, ou seja, o que acontece se escrever para o COM1 falhar, emita uma mensagem como no exemplo de código básico que modifiquei
Então você pode usar o System.Diagnostics.Process
Para desembolsar usando uma janela escondida
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); }
O processo é eliminado para uma janela oculta e toda a saída é redirecionada e manuseada no manipulador de eventos ... que deve fazer o truque. Observe, como a saída redirecionada entra no sbRedirectedOutput
(uma instância de Stringbuilder). No proc_ProcExited
manipulador de eventos, ele verifica o sbRedirectedOutput
Para a mensagem 'Oops Write falhou', que seria emitido no programa QB4.5.
Esteja ciente de que você pode precisar incluir a biblioteca de tempo de execução do QB4.5 no mesmo diretório ... não 100% de certeza ... está sendo anos ...
O que você acha?
Espero que isso ajude, cumprimentos, Tom.