#c #embedded #modbus #rs485
#c #встроенный #modbus #rs485
Вопрос:
Требование: Соберите данные с последовательного порта-1 по Modbus, зеркально отобразите их на последовательном порту-2.
Я могу обмениваться данными между Master и slave, но не могу зеркально отобразить данные на последовательный порт 2. Пожалуйста, подскажите мне, как этого добиться.
Код :
Master :
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h> /* File Control Definitions */
#include <termios.h> /* POSIX Terminal Control Definitions */
#include <unistd.h> /* UNIX Standard Definitions */
#include <errno.h> /* ERROR Number Definitions */
#include <sys/ioctl.h>
#include "modbus.h"
int main()
{
uint8_t req[MODBUS_RTU_MAX_ADU_LENGTH];// request buffer
int len;// length of the request/response
printf("Modbus server example.n");
//Create a new RTU context with proper serial parameters (in this example,
//device name /dev/ttyS0, baud rate 9600, no parity bit, 8 data bits, 1 stop bit)
modbus_t *ctx = modbus_new_rtu("/dev/ttyUSB3", 9600, 'N', 8, 1);
if (!ctx) {
fprintf(stderr, "Failed to create the context: %sn", modbus_strerror(errno));
exit(1);
}
if (modbus_connect(ctx) == -1) {
fprintf(stderr, "Unable to connect: %sn", modbus_strerror(errno));
modbus_free(ctx);
exit(1);
}
else
{
printf("Modbus server connected successfullyn");
}
//Set the Modbus address of the remote slave (to 3)
int rc=modbus_set_slave(ctx, 3);
printf("Modbus set remote slave return code : %dn",rc);
uint16_t reg[5];// will store read registers values
//Read 5 holding registers starting from address 10
int num = modbus_read_registers(ctx, 10, 5, reg);
printf("Result of modbus_read_registers : %dn",num);
for(int i=10;i<=15;i )
{
printf("reg [%d] : %Xt",i,reg[i]);
}
printf("n");
if (num != 5)
{// number of read registers is not the one expected
fprintf(stderr, "Failed to read: %sn", modbus_strerror(errno));
}
modbus_close(ctx);
modbus_free(ctx);
}
================================================================
Подчинение :
#include <stdio.h>
#include <fcntl.h> /* File Control Definitions */
#include <termios.h> /* POSIX Terminal Control Definitions */
#include <unistd.h> /* UNIX Standard Definitions */
#include <errno.h> /* ERROR Number Definitions */
#include <sys/ioctl.h>
#include "modbus/modbus.h"
int main()
{
int len1=-1;
printf("Modbus slave example");
//Prepare a Modbus mapping with 30 holding registers
//(plus no output coil, one input coil and two input registers)
//This will also automatically set the value of each register to 0
modbus_mapping_t *mapping = modbus_mapping_new(0, 1, 30, 2);
if (!mapping) {
fprintf(stderr, "Failed to allocate the mapping: %sn", modbus_strerror(errno));
exit(1);
}
else
{
printf("Mapping allocated successfully.n");
}
//Example: set register 12 to integer value 623
mapping->tab_registers[12] = 623;
modbus_t *ctx = modbus_new_rtu("/dev/ttyHSL1", 9600, 'N', 8, 1);
if (!ctx) {
fprintf(stderr, "Failed to create the context: %sn", modbus_strerror(errno));
exit(1);
}
//Set the Modbus address of this slave (to 3)
int rc= modbus_set_slave(ctx, 3);
printf("Result code of Modbus set slave address :%dn",rc);
if (modbus_connect(ctx) == -1) {
fprintf(stderr, "Unable to connect: %sn", modbus_strerror(errno));
modbus_free(ctx);
exit(1);
}
else
{
printf("Modbus slave connected successfullyn");
}
uint8_t req[MODBUS_RTU_MAX_ADU_LENGTH];// request buffer
int len;// length of the request/response
while(1) {
len = modbus_receive(ctx, req);
printf("Modbus receive len : %dn",len);
if (len == -1)
break;
len1 = modbus_reply(ctx, req, len, mapping);
printf("req: %Xn",*req);
printf("len : %dn",len);
printf("mapping->tab_registers[12] : %dn",mapping->tab_registers[12]);
printf("Result Modbus reply len : %dn",len1);
if (len == -1) break;
}
printf("Exit the loop: %sn", modbus_strerror(errno));
modbus_mapping_free(mapping);
modbus_close(ctx);
modbus_free(ctx);
}
o/p :
Ведущий :
shilpa@RT:~/Desktop/Modbus_master/Modbus_masterComponent/src$ sudo ./Modbus_masterComponent
Modbus server example.
Modbus server connected successfully
Modbus set remote slave return code : 0
Result of modbus_read_registers : 5
reg [10] : 0 reg [11] : 0 reg [12] : AAC6 reg [13] : CDB5 reg [14] : 7F6D reg [15] : 0
Подчинение :
root@swi-mdm9x15:~# /legato/systems/current/apps/Modbus_slave/read-only/bin/modbus_slave
Modbus slave exampleMapping allocated successfully.
Result code of Modbus set slave address :0
Modbus slave connected successfully
Modbus receive len : 8
req: 3
len : 8
mapping->tab_registers[12] : 623
Result Modbus reply len : 15
Комментарии:
1. Это требует дополнительных разъяснений. Какова настройка вашего оборудования. что к чему подключено? и почему вы хотите просто повторить одни и те же данные. Вы создаете шлюз или что-то в этом роде, или у вас есть этот последовательный порт, подключенный к вашему ПК для мониторинга. Насколько я могу догадаться, вы используете libmodbus, скорее всего, на одноплатном компьютере (поправьте меня, если я ошибаюсь).
2. Да, я создаю шлюз. Спасибо.
Ответ №1:
Вы не можете просто проиндексировать массив с 5 слотами из 10-15, как вы сделали в цикле for. Нет, это неправильно. Его индексация будет варьироваться от 0 до 4.
uint16_t reg[5];// will store read registers values
//Read 5 holding registers starting from address 10
int num = modbus_read_registers(ctx, 10, 5, reg);
printf("Result of modbus_read_registers : %dn",num);
for(int i=10;i<=15;i )
{
printf("reg [%d] : %Xt",i,reg[i]);
}
Цикл For должен выглядеть следующим образом. а также %X предназначен для печати данных в шестнадцатеричном формате. если вы хотите видеть те же 623 (десятичные), которые вы сохранили на стороне slave, напечатанные на стороне master в десятичной форме, тогда используйте %d, как я сделал ниже.
for(int i=0;i<5;i )
{
printf("reg [%d] : %dt",i 10, reg[i]);
}