Открываете ящик MS-Cash, неправильный код?Плохой код?
-
19-09-2019 - |
Вопрос
Опыт здесь унизительный, и я думаю, что этот человек выставит меня дураком, но... Я пытаюсь преобразовать древнюю кассовую программу в .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!")
Я получаю сообщения «Сигнал отправлен», «Готово Pop Drawer».
Черт побери, просто не лопнет.Это денежный ящик MS (EP125KC).Определенно подключен к COM1, питание определенно есть.Chr(65) — это старый код, используемый для открытия ящика, и он работает:
Open drawerComPort For Output Access Write As #1
Print #1, Chr$(65); "A";
Close #1
ПРИМЕЧАНИЕ:Приведенный выше код сработал успешно.Основная проблема была вызвана перепутанным шнуром питания (минус был не с той стороны).
Спасибо за всю помощь, ребята!
Решение
Вы установили для рукопожатия значение «Нет», но у денежного ящика, вероятно, есть своя идея.Также установите для DtrEnable значение True.Chr(65) — это код ASCII для буквы «A», ваш код VB предполагает, что настоящая команда — «AA».
В руководстве указано, что денежный ящик автоматически настраивает скорость передачи данных.Рекомендуется отправлять не менее 20 символов @.И что настоящая команда — это Ctrl+G (Chr(7)).Команда «AA» могла работать раньше из-за несоответствия скорости передачи данных.Возможно.
Другие советы
Если я вспомню свою очень ржавый БАЗОВЫЙ.
Print #1, Chr$(65); "A";
означает печать на порт1 символа 65, за которым следует строка «A». Теперь символ 65 — это «A», так что мне кажется, что вы должны отправлять «AA» на порт1
port.Write("AA");
или попеременно,
port.Write(new byte[]{65,'A'}, 0, 2);
Возможно, он отправляет Unicode 65, который будет 0065, что не закончится хорошо.
Просто мысль, можете ли вы попробовать отправить необработанный int?
Я не использую .net, но буферизуется ли порт?вам нужно отправить флеш/fflush()?
Вы уверены, что вам нужно отправить этот код?Я всегда думал, что код имеет префикс ESC, т.е.0x1b шестнадцатеричный... для денежных ящиков...
"\x1bA"
Интересно, что использовано двойное «А»… ну ладно…:)
Редактировать: Подумав об этом, я понял, что есть другой способ сделать это, читайте дальше...Я изменил ваш исходный код 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 можно найти здесь.Теперь на вас лежит ответственность сделать это пуленепробиваемым, т.е.что произойдет, если запись на 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.
Имейте в виду, что вам, возможно, придется включить библиотеку времени выполнения QB4.5 в тот же каталог... не уверен на 100%... прошли годы...
Что вы думаете?
Надеюсь, это поможет, с уважением, Том.