|
01.10.2008, 11:02 | #1 |
Участник
|
RS232 com port
Здраствуйте ,
По поиску нашёл классы от EVGL ( SF_MSComm32 ) . Но никак не могу найти решения , как считать информацию из СОМ порта и поставить инфо в нужное поле в форме . Имеем здесь несколько старых рабочих сканеров , которые привязанные к СОМ портам . Надо считать баркоды и поставить их в форму . Обьект классы создаеться , СОМ порт открываеться - дальше не понимаю , как описать опознание и наблюдение процесса СОМ порта ... Заранее спасибо за помочь ! С уважением , Римантас |
|
01.10.2008, 11:23 | #2 |
Участник
|
А разве он сам этого не делает?
Откройте Word поднесите штрих код к аппарату. Разве он ничего не напишет в Word-е.
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему. |
|
01.10.2008, 11:33 | #3 |
Участник
|
|
|
01.10.2008, 11:37 | #4 |
Участник
|
Цитата:
Может у вас драйвер под него просто не стоит.
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему. |
|
01.10.2008, 11:46 | #5 |
Участник
|
А вот подключите какой нибудь старый модем в СОМ порт и попросите его написать всю инфо в Word ... Без спецяльной програмки такое не выдет ... И здесь - есть старые сканеры - нету никакого софта , драиверов с ними . Голый hardware . Раньше написана програмка под Clipper работала , но надо всё ето перенести в Ахапту ...
|
|
01.10.2008, 13:02 | #6 |
Участник
|
Когда то писал програму на C++ Builder, которая работала с разными устройствами, через com port(Табло, пульты и др.) всё через один com-порт.
Принцип простой нужно три функции: инициализация порта, запись в файл, чтение из файла. С портом работается как с обычным файлом. Но там нужно было знать протокол работы с устройством. Не на все сигнады они отзываются только на свои. Т.е. типа адресс_устройства+команда_для_этого_типа устройства+параметры_для_этой_команды+контрольная_сумма. Возможно вам никаких команд не надо посылать на устройство. Просто считывать данные отправляемые устройством. Вечером покапаюсь в архиве, выложу эти функции. Правда они на C++ Builder. Может пригодяться.
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему. |
|
01.10.2008, 11:28 | #7 |
Злыдни
|
Я в свое время вешал в appl.startupPost() инициализацию обертки для MSCOMM32 и там же запуск опроса ком-порта через setTimeOut(). При наличии данных в буфере порта через xInfo.parmLastActivatedForm() получал экземпляр активной формы и проверял, есть ли там спец. метод (например, activateBarcode() или какой-нить другой). Если есть - передавал управление в этод метод вместе со считанным штрих-кодом, а в нем уже писал обработчик штрих-кода. Примерно так.
PS разработку от EVGL не смотрел :-( |
|
01.10.2008, 11:41 | #8 |
Участник
|
Цитата:
Сообщение от Yprit
Я в свое время вешал в appl.startupPost() инициализацию обертки для MSCOMM32 и там же запуск опроса ком-порта через setTimeOut(). При наличии данных в буфере порта через xInfo.parmLastActivatedForm() получал экземпляр активной формы и проверял, есть ли там спец. метод (например, activateBarcode() или какой-нить другой). Если есть - передавал управление в этод метод вместе со считанным штрих-кодом, а в нем уже писал обработчик штрих-кода. Примерно так.
PS разработку от EVGL не смотрел :-( Римантас |
|
01.10.2008, 13:08 | #9 |
Злыдни
|
Цитата:
Сообщение от Rimantas
Простите , но для моей головы такое слишком сложно - непонял я здесь многое ... По моему здесь , как и должно быть всё попроще - 1. пускаю форму , 2. иницирую нужный СОМ порт , 3. во времени работы формы наблюдаю за СОМ порт . Вот етой 3-ей части и нехватает мне ... . Как активировать наблюдение СОМ порта в форме ? Там в классе EVGL дальше всё хорошо - есть методы опознания Input . Но я неимею сделать наблюдение и непонимаю как ето сделать ...
Римантас |
|
01.10.2008, 14:16 | #10 |
Участник
|
Цитата:
Сообщение от Yprit
Чтобы во время работы формы реагировать на прерывания ком-порта, проще всего повесить на форму ActiveX MSComm.ocx (по-моему, он так назывался) и перекрыть у него метод onEvent_OnComm(), который срабатывает при считывании данных ш/к сканером. Если Вы хотите работать без ActiveX, то Вам придется самому организовывать периодический опрос ком-порта на предмет наличия в буфере данных. На форуме обсуждался вопрос об организации такого механизма в отдельном потоке - но, кажется, универсального решения не получилось.
|
|
01.10.2008, 13:17 | #11 |
Ищущий знания...
|
у нас это реализовано с помощью element.setTimeOut("GetBarcode", TimeOut);
на формах геде должно быть сканирование добавляется метод GetBarcode(); в init() формы инициализируется ком порт и выставляется таймер на просмотр метода GetBarcode(); в этом методе проверяем есть ли что в ком порте, а далле получаем штрих код, и делаем всё что нам надо.
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
01.10.2008, 13:23 | #12 |
Злыдни
|
Во-во, я про это и говорил в своем первом посте. Просто поскольку у нас работа со сканером разве что в ГК не велась, то я прикрутил более универсальный механизм, чтобы каждый раз на форме одни и те же методы не писать.
|
|
01.10.2008, 14:18 | #13 |
Участник
|
Цитата:
Сообщение от lev
у нас это реализовано с помощью element.setTimeOut("GetBarcode", TimeOut);
на формах геде должно быть сканирование добавляется метод GetBarcode(); в init() формы инициализируется ком порт и выставляется таймер на просмотр метода GetBarcode(); в этом методе проверяем есть ли что в ком порте, а далле получаем штрих код, и делаем всё что нам надо. |
|
02.10.2008, 15:30 | #14 |
Участник
|
Цитата:
Сообщение от lev
у нас это реализовано с помощью element.setTimeOut("GetBarcode", TimeOut);
на формах геде должно быть сканирование добавляется метод GetBarcode(); в init() формы инициализируется ком порт и выставляется таймер на просмотр метода GetBarcode(); в этом методе проверяем есть ли что в ком порте, а далле получаем штрих код, и делаем всё что нам надо. Код : Код: public void init() { ; cRez = "1"; if ( element.args().parm() ) cRez = element.args().parm(); super(); if ( cRez == "2" ) { comPrt = new CommaIo( "COM1:", "r" ); comPrt.outRecordDelimiter('\r\n'); element.setTimeOut( "GetBarkod", 100, true ); } } void GetBarkod() { Container aRead; ; if ( comPrt.status() == IO_Status::Ok ) { [cBarkod] = comPrt.read(); //aRead = comPrt.read(); //cBarkod = conpeek( aRead, 1 ); Barkod.text( cBarkod ); Barkod.modified(); } element.setTimeOut( "GetBarkod", 100 ); } |
|
01.10.2008, 13:21 | #15 |
Участник
|
Цитата:
А несколько сканеров - это сколько? Насколько они "специфичны"? И не дешевле ли будет купить каких-нить Metrologic'ов по 100 баксов штука, чем кодить работу с com портом под Аксапту? |
|
01.10.2008, 14:20 | #16 |
Участник
|
В том и беда , кто никто несобираеться покупать новые - они работают на старой системе , значит они должны работать и на Ахапте ... Деньги считать при замедленной економике полезно ...
|
|
01.10.2008, 17:23 | #17 |
Участник
|
Цитата:
Стоимость "допиливания" Аксапты на работу c компортовым сканером равна стоимости времени потраченному на эту доработку, и вполне может превысить эту $1000. |
|
02.10.2008, 09:05 | #18 |
Участник
|
Вот несколько функций для работы с com портом на С++ Builder.
Мож что пригодиться. X++: DCB dcb; HANDLE hComm; //Установка настроек com-порта bool __fastcall InstallComm(int iPort) //номер порта { BOOL fSuccess; char szCommPattern[8]; if (iPort == 0) return false; sprintf(szCommPattern, "COM%d", iPort); hComm = CreateFile(szCommPattern, GENERIC_READ | GENERIC_WRITE,0,0, OPEN_EXISTING,0,0); if (hComm == INVALID_HANDLE_VALUE) return false; fSuccess = GetCommState(hComm, &dcb); if (!fSuccess) return false; dcb.BaudRate = CBR_57600; dcb.ByteSize = 8; dcb.fParity = FALSE; dcb.Parity = NOPARITY; dcb.StopBits = TWOSTOPBITS; dcb.fOutxCtsFlow = FALSE; dcb.fOutxDsrFlow = FALSE; dcb.fDtrControl = DTR_CONTROL_DISABLE; dcb.fDsrSensitivity = FALSE; dcb.fRtsControl = RTS_CONTROL_DISABLE; fSuccess = SetCommState(hComm, &dcb); if (!fSuccess) return false; SetupComm(hComm, 1024, 1024); COMMTIMEOUTS TO; TO.ReadIntervalTimeout = 80;// 50 TO.ReadTotalTimeoutMultiplier = 1; ///1 TO.ReadTotalTimeoutConstant = 100; ///500 TO.WriteTotalTimeoutMultiplier = 200; ///10 TO.WriteTotalTimeoutConstant = 2000; ///100 SetCommTimeouts(hComm, &TO); return true; } //Запись в com-порт bool __fastcall WriteBuffer(byte* lpBufWrite,DWORD dwToWrite) { DWORD dwWritten; GetCommState(hComm,&dcb); dcb.fDtrControl=DTR_CONTROL_DISABLE; SetCommState(hComm,&dcb); GetCommState(hComm,&dcb); dcb.fDtrControl=DTR_CONTROL_ENABLE; SetCommState(hComm,&dcb); for(unsigned i=0;i<dwToWrite;i++) { if (i==dwToWrite-1) { GetCommState(hComm,&dcb); dcb.fDtrControl=DTR_CONTROL_DISABLE; SetCommState(hComm,&dcb); } WriteFile(hComm,lpBufWrite+i,1,&dwWritten,NULL); Sleep(1); } return true; } //------------------------------------------------------------------------------- //Чтение из com-порта int __fastcall ReadBuffer(byte* lpBufRead,DWORD dwToRead) { DWORD dwRead=0; Sleep(2); ReadFile(hComm,lpBufRead,dwToRead,&dwRead,NULL);//Читаем буффер PurgeComm(hComm,PURGE_RXCLEAR);//Очищаем буффер return dwRead; } //Использование DWORD dwBytesReceived; byte buf[64]; dwBytesReceived = ReadBuffer((char *)buf,13); byte OutText[22]; OutText[0]=adr; ----------------- OutText[22]= X; WriteBuffer(OutText,22);
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему. |
|
02.10.2008, 12:53 | #19 |
Участник
|
Цитата:
Сообщение от Gihar
Ну, просто как то странно, если допустим у вас используется десять старых сканеров, что в моем понимании и есть "несколько". Тогда стоимость новых будет $1000.
Стоимость "допиливания" Аксапты на работу c компортовым сканером равна стоимости времени потраченному на эту доработку, и вполне может превысить эту $1000. |
|
01.10.2008, 13:53 | #20 |
Участник
|
Вот небольшое консольное приложение на .Net написанное на C#. Тут показано как писать в COM-порт или читать из него. Если у Вас Ax4, то работайте с Net прямо из аксапты.
X++: using System; using System.IO.Ports; using System.Threading; public class PortChat { static bool _continue; static SerialPort _serialPort; public static void Main() { string name; string message; StringComparer stringComparer = StringComparer.OrdinalIgnoreCase; Thread readThread = new Thread(Read); _serialPort = new SerialPort(); _serialPort.PortName = "COM1"; // Пишим нужный порт _serialPort.BaudRate = 38400; _serialPort.Parity = Parity.None; _serialPort.DataBits = 8; _serialPort.StopBits = StopBits.One; _serialPort.Handshake = Handshake.RequestToSend; _serialPort.ReadTimeout = 500; _serialPort.WriteTimeout = 500; _serialPort.Open(); _continue = true; readThread.Start(); Console.WriteLine("Type QUIT to exit"); while (_continue) { message = Console.ReadLine(); if (stringComparer.Equals("quit", message)) { _continue = false; } else if (stringComparer.Equals("ctrlz", message)) { _serialPort.WriteLine("\x1A"); //Код Ctrl+Z } else { _serialPort.WriteLine(message + "\r\n"); } } readThread.Join(); _serialPort.Close(); } public static void Read() { while (_continue) // Ждем данные { try { string message = _serialPort.ReadExisting(); if (message != "") { Console.WriteLine(message); } } catch (TimeoutException) { } } } } |
|