Modbus RTU — BCD Format

Помечено: 

Просмотр 15 сообщений - с 16 по 30 (из 30 всего)
  • Автор
    Записи
  • #5273
    baur
    Участник

    Попробуйте просто int считать для начала с формулой

    в смысле не uint а просто int?
    я так сделал картина не меняется

    • Ответ изменён 9 лет, 4 месяца назад пользователем baur.
    #5275
    manjey73
    Участник

    Странно, 206592 должно быть правильным числом, судя по калькулятору.
    А что не так не въеду пока…

    #5276
    manjey73
    Участник

    я тормоз, оно то уже преобразовалось в десятичное….. соответственно и дополнительное BCD в десятичное не надо….
    У меня пока кроме огорода ничего не получается, сейчас через копирование массива попробую…

    • Ответ изменён 9 лет, 4 месяца назад пользователем manjey73.
    #5278
    manjey73
    Участник

    Не ту функцию нашел для преобразования… Попробуйте вот эту

    public int bcd2dec(double val)
    {
    int index = 0;
    int range = 4;
    int intval = Convert.ToInt32(val);
    byte[] buf_bcd = BitConverter.GetBytes(intval);
    Array.Reverse(buf_bcd);
    List<byte> temp = new List<byte>(buf_bcd);
    byte[] buf_dec = temp.GetRange(index, range).ToArray();
    int result = 0;
    foreach (byte bcd in buf_dec)
    {
    result *= 100;
    result += (10 * (bcd >> 4));
    result += bcd & 0xf;
    }
    return result;
    }

    название bcd2dec, Описание — Преобразование int из BCD в DEC

    Сделал только для int, вызов в формуле так же bcd2dec(Cnl)
    Тестировал на вашем значении 206592

    #5282
    Mikhail
    Модератор

    На всякий случай дополню:
    Т.к. в документации указано, что число 32-битное, то считывать по Модбас нужно как uint (4 байта). Затем преобразовывать с помощью формул в базе конфигурации.
    Внутри Вашей формулы сначала преобразуйте (uint)Cnl, т.к. как правильно написали, все входные каналы имеют тип double. Ну а затем уже можете выделять байты, биты, чтобы перевести из BCD в обычное число.

    #5283
    baur
    Участник

    manjey73, спасибо!!! заработал
    завтра протестирую еще раз …

    • Ответ изменён 9 лет, 4 месяца назад пользователем baur.
    #5284
    baur
    Участник

    Внутри Вашей формулы сначала преобразуйте (uint)Cnl

    получается bcd2dec((uint)Cnl)?

    #5288
    manjey73
    Участник

    Нет, просто bcd2dec(Cnl), так как канал в сервер уже передается в формате double самой системой. На вход формулы значение идет в double, как оно прилетает из Коммуникатора в Сервер.

    То, что вы опрос делаете uint 4 байта это взаимодействие Коммуникатора с прибором, этого входная формула не касается.

    • Ответ изменён 9 лет, 4 месяца назад пользователем manjey73.
    #5297
    manjey73
    Участник

    public int BcdToDec(double val)
    {
    byte[] bcdNumber = BitConverter.GetBytes((UInt32)val);
    Array.Reverse(bcdNumber);
    int result = 0;
    foreach (byte b in bcdNumber)
    {
    int digit1 = b >> 4;
    int digit2 = b & 0x0f;
    result = (result * 100) + digit1 * 10 + digit2;
    }
    return result;
    }

    Вызов так же, BcdToDec(Cnl) — забыл что эта версия кода работает только с 4-х байтными переменными

    #5298
    baur
    Участник

    По документации там 10-ти значный счетчик, как они вмешается в 32bit?

    #5299
    baur
    Участник

    в смысле, как вместится символ 9 999 999 999?

    #5303
    manjey73
    Участник

    Потому что это BCD формат, считается не байт а октет (или как оно там правильно) 4 бита, в которых можно разместить цифры от 0 до 9.

    4 байта это 8 символов.
    Но у вас же вроде всего 4 байта от прибора идет или вы что-то не договорили ?

    Тогда документация или трындит или читать надо 8 байт а не 4, при чтении 8 байт надо вариант формулы bcd2dec возвращать к оригинальному виду с обработкой long типа

    • Ответ изменён 9 лет, 4 месяца назад пользователем manjey73.
    • Ответ изменён 9 лет, 4 месяца назад пользователем manjey73.
    #5306
    manjey73
    Участник

    у вас 2 регистра подряд. 8 знаков и еще какие-то Non Ressetable 10 digit — скорее всего в этом регистре всего 2 знака, либо там уже не BCD формат, как говорит документация.

    #5909
    baur
    Участник

    Можно ли применить эту формулу для BDC 16 bit (ushort 2 байта)?

    #5919
    manjey73
    Участник

    Вроде можно, единственное, может придется добавить еще два нулевых байта вперед или в конец уже внутри формулы, ну или потестировать как есть и посмотреть что получится.

    Вы же всегда можете сделать так ВызовФормулы((UInt32)ваш ushort) — никто же не мешает…

    Если в формулу надо подать double, то надо сделать (double)ваш ushort.

    Ну или подкорректировать просто формулу под вашу задачу, чтобы лишнего не писать…
    Собственно каналы все равно в Сервер прилетают в double.

    • Ответ изменён 9 лет, 3 месяца назад пользователем manjey73.
    • Ответ изменён 9 лет, 3 месяца назад пользователем manjey73.
Просмотр 15 сообщений - с 16 по 30 (из 30 всего)
  • Для ответа в этой теме необходимо авторизоваться.