Конференция "Corba" » передать в com-порт байты типа 000h [Delphi, Windows]
 
  • 161a © (30.09.10 13:16) [0]
    Прошу прщения, но я только учусь.
    Так вот вопрос:
    необходимо передать черех ком-порт 4 байта "000h, 055h, 017h, 05Fh".
    Это кусок из кода:"

     Buff:=s;
     nBytes:=4;//Length(Buff);
     ok:=WriteFile(  //uses Windows
       hCom,
       Buff[1],
       nBytes,
       wr_cnt,
       nil
     );
     if not ok then RaiseLastOSError;
     if wr_cnt<>nBytes then Raise Exception.Create('Число записанных байтов в COM-порт меньше, чем было затребовано.');
    end;"

    подскажите, плз, как в "s" забить эти байты?
  • Сергей М. © (30.09.10 15:01) [1]
    Никаких Buff тут не нужно.
    Передавай прямо из s:

    s: = #$00#$55#$17#$5F;
    ok:=WriteFile(
      hCom,
      s[1],
      nBytes, // 4
      wr_cnt,
      nil
    );
  • 161a © (30.09.10 15:22) [2]
    увы не сработало...
    я пошел другим путем:

     var Buff: array[0..$FF] of Byte;
     var wr_cnt: DWORD;
     var ok:Boolean;
     var nBytes: DWORD;
    begin

     if bPortIsOpen=False then begin
           Raise Exception.Create('Сначала откройте COM-порт.');
     end;

     Buff[0]:=$00;
     Buff[1]:=$55;
     Buff[2]:=$17;
     Buff[3]:=$5F;

     nBytes:=4;//Length(Buff);
     ok:=WriteFile(  //uses Windows
       hCom,
       Buff,
       nBytes,
       wr_cnt,
       nil
     );
     if not ok then RaiseLastOSError;
     if wr_cnt<>nBytes then Raise Exception.Create('Число записанных байтов в COM-порт меньше, чем было затребовано.');
    end;

    вроде в мониторе он передает, но в ответ от устройства ничего не получаю...
    по паспорту написано:
    "Передача данных инициируется посылкой запроса ведомому устройству от ведущего устройства (компьютер). Передаче запроса должен предшествовать интервал молчания длительностью минимум 4 мс.

    Запрос состоит из 4-х байт:
    1. сетевой адрес ведомого устройства;
    2. байт 055h — код функции запроса текущего веса;
    3. два байта контрольной суммы CRC16.

    Ведомое устройство принимает запрос, контролирует бит паритета для каждого байта данных, сравнивает присвоенный устройству сетевой адрес и адрес в запросе и вычисляет контрольную сумму CRC16."

    вот я и думаю, может где с тайм-аутом не то?
  • 161a © (30.09.10 16:02) [3]
    P.S.
    "Если хотя бы одно условие нарушено, то ответ не генерируется. При выполнении всех условий ведущий посылает ответ, состоящий из 8 байт:
    1. сетевой адрес ведомого устройства;
    2. три байта значения веса (первый байт – младший), целое число со знаком, отрицательные значения представлены в дополнительном коде, т.е. –1 = 0FFFFFFh.
    3. байт служебной информации b1;
    4. байт служебной информации b2;
    5. два байта контрольной суммы CRC16."
  • Сергей М. © (30.09.10 16:02) [4]

    > не сработало


    Что значит "не сработало" ?
    Вот так прямо и говорит - "не срабатываю" ?)
  • 161a © (30.09.10 16:11) [5]
    нет, говорит, фигвам... :0)
    не передает в ответ ничего...
  • Сергей М. © (30.09.10 16:32) [6]

    > 161a ©   (30.09.10 16:11) [5]


    И чего ?
    У тебя и если ты "пошел другим путем" тоже "в ответ от устройства ничего не получаю")
    А если нет разницы, зачем "платить дважды" ?)
  • 161a © (30.09.10 16:41) [7]
    таки и я о том: посыл вроде прошел, но ответ не сгенерировался! вот что обидно! хотя у их "родной" программы все проходит на ура... а от нее есть толькл ехе-шник... как посмотреть где я ошибаюсь... :(
  • Сергей М. © (30.09.10 16:48) [8]

    > посыл вроде прошел


    Что значит "вроде" ?
    Либо он заведомо прошел либо не прошел)

    Ты сравни монитором-то что уходит от твоей программулины с тем что уходит от родного ехе-шника для этой железяки
  • 161a © (30.09.10 16:49) [9]
    уходит одно и то же, но может там по времени какая-то закавыка...
  • Сергей М. © (30.09.10 17:04) [10]
    т.е. монитор показывает что от дивайса вообще ничего не поступает в ответ на твой посыл ?
  • 161a © (30.09.10 17:27) [11]
    ага
  • Сергей М. © (30.09.10 17:31) [12]
    А что за монитор-то ?

    p.s.

    А чего это ты запостил вопрос в "Corba и COM" ?
    Твоя задача кроме фигурирующей аббревиатуры "СОМ" не имеет ни малейшего отношения к теме раздела)
  • 161a © (30.09.10 17:32) [13]
    ну я ж грю тока учусь, монитор "comport toolkit"
  • Сергей М. © (30.09.10 17:48) [14]
    Покажи дампы монитора для случая твоего и не твоего посылов ..
  • 161a © (30.09.10 17:51) [15]
    мой
    000019|15:31:48.375 |COM1  |<<|00 55 17 5F                                    |.U._
    не мой
    000019|15:32:53.906 |COM1  |<<|00 55 17 5F                                    |.U._
    000020|15:32:54.046 |COM1  |>>|00 74 00 00 02 04 BC 76                        |.t....јv
  • 161a © (30.09.10 17:52) [16]
    сорри! не мой
    000019|15:31:48.375 |COM1  |<<|00 55 17 5F                                    |.U._
    000020|15:31:48.531 |COM1  |>>|00 00 00 00 02 14 3A C7                        |......:З
    это нулевое значение ответчика
  • Сергей М. © (30.09.10 17:58) [17]

    > мой
    > 000019|15:31:48.375


    > сорри! не мой
    > 000019|15:31:48.375


    Что-то ты темнишь) ..

    Как это "мой" и "не мой" посылы у тебя были отправлены в одно и тоже время с точностью до миллисекунды ?
  • 161a © (30.09.10 18:03) [18]
    блин, не оттуда скопировал
    Мой
    000001|18:02:51.562 |COM1  |<<|00 55 17 5F                                    |.U._
    не мой
    000001|18:01:53.514 |COM1  |<<|00 55 17 5F                                    |.U._
    000002|18:01:53.655 |COM1  |>>|00 00 00 00 02 14 3A C7                        |......:З
  • Сергей М. © (30.09.10 18:08) [19]
    ну хорошо
    покажи свой код инициализации/открытия порта и чтения из него..
  • 161a © (30.09.10 18:09) [20]
    procedure T_ComPort.OpenPort(PortName: String);
    begin
     if hCom>0 then  Raise Exception.Create('Порт уже инициализирован');
     hCom:=CreateFile( //uses Windows
                       pchar(PortName), //Имя COM-порта
                       GENERIC_READ or GENERIC_WRITE,
                       0, {exclusive access}
                       nil, {no security attrs}
                       OPEN_EXISTING,
                       0,{not overlapped}
                       0 {hTemplate}
                       );
     if hCom=INVALID_HANDLE_VALUE then
         RaiseLastOSError;

     //Выставляем параметры COM-порта

     if not GetCommState(hCom,dcb) //uses Windows
       then RaiseLastOSError;

     dcb.BaudRate:=CBR_9600;
     dcb.ByteSize:=8;
     dcb.Parity:=NOPARITY;
     dcb.StopBits:=ONESTOPBIT;

     if not SetCommState(hCOM,dcb) //uses Windows
       then RaiseLastOSError;

     //Выставляем параметры COM-порта
     if not GetCommTimeOuts(hCom,cto) //uses Windows
       then RaiseLastOSError;

       cto.ReadIntervalTimeout:=1;
       cto.ReadTotalTimeoutMultiplier:=1;
       cto.ReadTotalTimeoutConstant:=10;

       cto.WriteTotalTimeoutMultiplier:=0;
       cto.WriteTotalTimeoutConstant:=0;

     if not SetCommTimeOuts(hCom,cto) //uses Windows
       then RaiseLastOSError;

     bPortIsOpen:=True;

    end;
  • 161a © (30.09.10 18:11) [21]
    до чтения пока не дошел, мне бы в мониторе ответ увидеть... ;0/
  • Сергей М. © (30.09.10 18:16) [22]

    >  dcb.BaudRate:=CBR_9600;
    >  dcb.ByteSize:=8;
    >  dcb.Parity:=NOPARITY;
    >  dcb.StopBits:=ONESTOPBIT;
    >


    Это соответствует документации на железку ?
    Или от балды ?
  • 161a © (30.09.10 18:17) [23]
    Режим работы полудуплексный
    Скорость передачи 9600 бод
    Длина передачи 8 бит
    Бит паритета есть, дополняет байт до чётного числа единиц
    Число стоповых битов 1 бит
    Управление потоком нет
  • Сергей М. © (30.09.10 18:25) [24]

    > Бит паритета есть


    А какого же тогда ты пишешь


    > dcb.Parity:=NOPARITY;


    ?
  • 161a © (30.09.10 18:26) [25]
    а кой правильно?
  • 161a © (30.09.10 18:27) [26]
    УУУУУРРРРРРРРРААААААААААААА!!!!!!!!!!!!
    ЗарРРРРРРаботалООООООООООО!!!! Спасибо огромедное!!!!!!
  • Сергей М. © (30.09.10 20:41) [27]

    > 161a ©   (30.09.10 18:27) [26]


    молодец !
    Я искренне)
  • 161a © (01.10.10 12:35) [28]
    > Сергей М.

    можешь дать еще консультацию?

    При выполнении всех условий ведущий посылает ответ, состоящий из 8 байт:
    1. сетевой адрес ведомого устройства;
    2. три байта значения веса (первый байт – младший), целое число со знаком, отрицательные значения представлены в дополнительном коде, т.е. –1 = 0FFFFFFh.
    3. байт служебной информации b1;
    4. байт служебной информации b2;
    5. два байта контрольной суммы CRC16.
    Три младших бита b1.0, b1.1 и b1.2 байта b1 образуют целое число Dec. Значение Dec от 0 до 6 показы-вают количество десятичных знаков после запятой в показаниях индикатора, т.е. целое значение веса необ-ходимо разделить на 10 в степени Dec.

    накорябал следущее:

    function T_ComPort.ReadString: String;
     var Buff: Array[1..8] of Byte;// String dword
     var rd_cnt: DWORD;
     var ok: Boolean;
     var i: Integer;
     var p: Integer;
     var x1, x2, x3, x4, x5, x6, x7, x8: Byte; //  String dword PChar
    begin

     if bPortIsOpen=False then begin
           Raise Exception.Create('Сначала откройте COM-порт.');
     end;

     if hCom=0 then Raise Exception.Create('Порт не был открыт.');

     ok:=ReadFile(  //uses Windows
       hCom, //Файл
       Buff, //Буфер куда считываем
       8, //Число байтов для считывания
       rd_cnt, //Число считанных байтов
       nil
     );

     if not ok then RaiseLastOSError;

     if rd_cnt=0 then begin
       BufferIsEmpty:=True;
       Result:='';
       exit;
     end;
     x1:=Buff[1];
     x2:=Buff[2];
     x3:=Buff[3];
     x4:=Buff[4];
     x5:=Buff[5];
     x6:=Buff[6];
     x7:=Buff[7];
     x8:=Buff[7];

     BufferIsEmpty:=False;
    end;

    ответ получаю в точке останова Buff = 0,0,0,0,2,20,58,199, а в мониторе
    000020|18:01:55.811 |COM1  |>>|00 00 00 00 02 14 3A C7                        |......:З
    это нулевой вес. как мне раздобить или вытащить байты, чевой-то я собсем запутался...
  • Сергей М. © (01.10.10 13:16) [29]

    > как мне раздобить или вытащить байты


    Ты же уже все "раздобыл" и "вытащил" ? Вот же они, в массиве Buff[], все восемь ..
    Что еще то ты собрался "раздобывать" и "вытаскивать" ?)
  • 161a © (01.10.10 13:37) [30]
    дело в том, что эти х-ы ничего не содержат внутри! когда на точке останова смотрю - они пустые... но даже если, предположим, что нет то как мне из них по хаданию вытащить этот Dec?

    ответ получаю в точке останова
    Buff = 0,0,0,0,2,20,58,199

    в мониторе
    000020|18:01:55.811 |COM1  |>>|00 00 00 00 02 14 3A C7                        |......:З
    это нулевой вес.

    ответ получаю в точке останова
    Buff = 0,206,0,0,2,4,212,230

    в мониторе
    000022|13:34:22.397 |COM1  |>>|00 CE 00 00 02 04 D4 E6                        |.О....Фж

    это 2060 кг

    как мне вытащить этот вес?
  • Сергей М. © (01.10.10 14:07) [31]

    > эти х-ы ничего не содержат внутри! когда на точке останова
    > смотрю - они пустые


    Да быть того не может)

    Ставь точку останова на BufferIsEmpty:=False и еще раз посмотри.


    > как мне из них по хаданию вытащить этот Dec?


    n: Integer;
    Weight: Double;
    ...
    n := PInteger(@Buff[2])^ and $FFFFFF;
    if (Buff[4] and $80) = $80 then n := n or $FF000000;
    Weight := n / Power(10, Buff[5] and 7);
  • 161a © (01.10.10 14:34) [32]
    [Warning] uComPort.pas(153): Unsafe code '@ operator' (это про "n := PInteger(@Buff[2])^ and $FFFFFF;")
    [Warning] uComPort.pas(154): Combining signed and unsigned types - widened both operands (это про "if (Buff[4] and $80) = $80 then n := n or $FF000000;")
    [Error] uComPort.pas(155): Undeclared identifier: 'Power' ( это про "Weight := n / Power(10, Buff[5] and 7);
    ")

    :0((
  • 161a © (01.10.10 14:34) [33]
    у меня 7-ка
  • 161a © (01.10.10 14:36) [34]
    он у меня чево-то даже на это стал ругаться...
    [Error] uComPort.pas(157): Undeclared identifier: 'ShowMessage'
  • 161a © (01.10.10 15:03) [35]
    я тут потести малость и заметил одну вещь (отбросив последние 2 байта)
    Buff = 0,206,0,0,2,4 - 2060кг -2,06т
    Buff = 0,18,0,0,2,4 - 180кг - 0,18т
    Buff = 0,8,0,0,2,4 - 80кг - 0,08т.
    т.е. получается, что если брать 2 байт и делить на 100, тоя получаю вес...в тоннах, а если умножить на 10 то в кг...
  • 161a © (01.10.10 15:10) [36]
    в инспекторе он мне показал : Buff[2]: Byte $12FDB1, как это дело в целое превратить?
  • Сергей М. © (01.10.10 15:11) [37]

    > [Warning]


    На это не обращай внимание


    > Undeclared identifier: 'Power'


    uses Math


    > Undeclared identifier: 'ShowMessage'


    uses Dialogs
  • 161a © (01.10.10 15:12) [38]
    это 110, или 1,1 т - 1100 кг
  • Сергей М. © (01.10.10 15:16) [39]

    > 161a ©   (01.10.10 15:10) [36]


    вот это

    PInteger(@Buff[2])^ and $FFFFFF

    все выдели.

    И подведи мышь к выделенному
  • 161a © (01.10.10 16:09) [40]
    спасибо друг!!! если встретимся с меня поляна!!!
  • 161a © (01.10.10 16:17) [41]
    и последний вопрос, если мона, как из одной процедуры запустить другую?
  • 161a © (01.10.10 16:20) [42]
    да, у меня прием идет по таймеру, а возможно ли в одной процедуре, ну скажем "послать/получить" послать запрос а потом сразу получить?
  • Сергей М. © (01.10.10 16:31) [43]

    > как из одной процедуры запустить другую?


    Из какой какую ?


    > а возможно ли


    Всё возможно)
  • 161a © (01.10.10 16:42) [44]
    все разобрался, сеньку!!!!! теперь буду пытаться передать в форму путь к файлу в который надо записать значение...
  • 161a © (01.10.10 18:28) [45]
    не могу нигде найти как передать в форму путь к файлу для сохранения... можа поможешь? плиииз...
  • Сергей М. © (03.10.10 20:52) [46]
    Это отдельный вопрос, никак не связанный с COM-портом.
    Задавай в "Начинающие"
 
Конференция "Corba" » передать в com-порт байты типа 000h [Delphi, Windows]
Есть новые Нет новых   [134427   +34][b:0][p:0.001]