Как разработать функцию «чтение / запись» с использованием libmodbus? (Код c) - PullRequest
0 голосов
/ 31 октября 2019

Я собираюсь читать / писать в соответствии со спецификацией modbus-tcp. Итак, я пытаюсь кодировать клиент и сервер в среде Linux. (Я бы связывался с программой Windows (как клиент), используя modbus-tcp.)

, но она не работает так, как я хочу, поэтому я прошу вас здесь.

  1. Я тестирую клиентский код для linux как клиента и easymodbus как сервер.
  2. Я использовал код libmodbus.
  3. Я хотел бы прочитать катушку (0x01) и написатьcoil (0x05).
  4. Когда код выполняется с использованием libmodbus, из части «Идентификатор устройства» выводится «ff» (в соответствии с руководством, для modbus-tcp должен быть выведен «01». Не знаю, почему печатается «ff» (фотография прилагается).

Неверный результат:

Wrong result

Ожидаемый результат:

Expected result

'[00] [00] .... [00]';Знаете ли вы, где управлять этой частью? У вас есть или вы знаете пример кода, который реализует функцию «чтение / запись» с использованием libmodbus?

, пожалуйста, дайте мнезнать информацию, если вы это знаете.

ctx = modbus_new_tcp("192.168.0.99", 502);
modbus_set_debug(ctx, TRUE);

if (modbus_connect(ctx) == -1) {
    fprintf(stderr, "Connection failed: %s\n",
            modbus_strerror(errno));
    modbus_free(ctx);
    return -1;
}

tab_rq_bits = (uint8_t *) malloc(nb * sizeof(uint8_t));
memset(tab_rq_bits, 0, nb * sizeof(uint8_t));

tab_rp_bits = (uint8_t *) malloc(nb * sizeof(uint8_t));
memset(tab_rp_bits, 0, nb * sizeof(uint8_t));

nb_loop = nb_fail = 0;

/* WRITE BIT */
rc = modbus_write_bit(ctx, addr, tab_rq_bits[0]);
if (rc != 1) {
    printf("ERROR modbus_write_bit (%d)\n", rc);
    printf("Address = %d, value = %d\n", addr, tab_rq_bits[0]);
    nb_fail++;
} else {
    rc = modbus_read_bits(ctx, addr, 1, tab_rp_bits);
    if (rc != 1 || tab_rq_bits[0] != tab_rp_bits[0]) {
        printf("ERROR modbus_read_bits single (%d)\n", rc);
        printf("address = %d\n", addr);
        nb_fail++;
    }
}   
printf("Test: ");
if (nb_fail)
    printf("%d FAILS\n", nb_fail);
else
    printf("SUCCESS\n");

free(tab_rq_bits);
free(tab_rp_bits);

/* Close the connection */
modbus_close(ctx);
modbus_free(ctx);

return 0;

Ответы [ 2 ]

1 голос
/ 31 октября 2019

То, что FF вы видите прямо перед тем, как функция Modbus на самом деле верна. Цитирование Руководства по внедрению Modbus , стр. 23:

В TCP / IP адрес сервера MODBUS адресован с использованием его IP-адреса;поэтому идентификатор устройства MODBUS бесполезен. Значение 0xFF должно быть использовано.

Итак, libmodbus просто придерживается спецификации Modbus. Я предполагаю, что проблема в easymodbus , который, очевидно, ожидает, что вы будете использовать 0x01 в качестве идентификатора устройства в своих запросах.

Я полагаю, что вы этого не делаетехотите связываться с easymodbus , чтобы вы могли довольно легко решить эту проблему с libmodbus : просто измените идентификатор устройства по умолчанию:

modbus_set_slave(ctx, 1);

Вы также можете пойти с:

 rc = modbus_set_slave(ctx, MODBUS_BROADCAST_ADDRESS);
 ASSERT_TRUE(rc != -1, "Invalid broadcast address");

, чтобы ваш клиент обратился ко всем ведомым в сети, если у вас их больше одного.

У вас есть дополнительная информация и краткое объяснение того, откуда возникает эта проблема. справочная страница libmodbus для функции modbus_set_slave .

Для очень подробного примера вы можете проверить libmodbus unit tests

А что касается вашего вопроса № 5, я не знаю, как на него ответить, вы подразумеваете, что нули - это состояния (истинные или ложные), которые вы хотите записать (или прочитать) вкатушки. Для записи вы можете изменить их в поле значения функции modbus_write_bit(ctx, address, value).

0 голосов
/ 01 ноября 2019

Я очень благодарен за ваш ответ.

Я протестировал функцию чтения / записи, используя рекомендованный вами код 'unit-test-server / client'. Я рассмотрел код, но есть еще много вещей, которые я не знаю.

Однако есть значение адреса, которое действует после тестирования друг друга с помощью кода unit-test-server / client, и естьзначение адреса, которое не работает (Знаете ли вы, почему?).

-Проверено и обнаружено, что значение UT_BITS_ADDRESS (значение адреса) работает от 0x130 до 0x150 - «Недопустимый адрес данных» встречается при значениях ниже -0x130 и выше 0x150 -адрес, который я хочу прочитать / записать, составляет от 0x0001 до 0x0004 (вы знаете, как это сделать?).

Я хочу знать, как обрабатывать и передавать данные, например, правую часть TXpicture.

введите описание изображения здесь

Я работаю как с клиентом, так и с сервером в моей среде Linux, и я тестирую чтение / запись. Среди неправильных изображений ... [06] [FF] ... <- Я хочу знать, как изменить часть FF (чтобы изменить значение на 01, как показано на рисунке) </p>

введите описание изображения здесь

и "modbus_set_slave" это функция для Modbus RTU? В конце я бы хотел пообщаться с программой для ПК и устройством с Linux. Итак, в какой части я использую эту функцию?

Еще раз спасибо за вашу заботу.

...