Skip to content

Instantly share code, notes, and snippets.

@jnareb
Created June 19, 2012 12:11
Show Gist options
  • Select an option

  • Save jnareb/2953805 to your computer and use it in GitHub Desktop.

Select an option

Save jnareb/2953805 to your computer and use it in GitHub Desktop.
libmodbus - reading from many slave_ids via RTU (expanded)
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <modbus.h>
#include "timing.h"
#define SM4_ID 3
#define P120_ID 2
#define SM1_ID 1
#define MODE_SET_SLAVE 1
#define MODE_FLUSH 2
#define MODE_RECONNECT 3
#define MODE_MULTI_CTX 4
#define CURRENT_MODE MODE_FLUSH
#define STR(x) #x
#define XSTR(x) STR(x)
int main(int argc, char *argv[])
{
modbus_t *ctx;
#if defined(CURRENT_MODE) && CURRENT_MODE == MODE_MULTI_CTX
modbus_t *ctxs[4];
#endif
uint16_t buf[4];
uint8_t bits[0x25];
int registers_address;
int id_address[4] = {0, 7000, 7000, 4200};
int i, nsteps = 2;
int slave_id = MODBUS_BROADCAST_ADDRESS;
useconds_t sleep_tick = 100, time_slept = 0;
int rc;
init_timers_main();
printf("mode [%s] = %s\n", STR(CURRENT_MODE), XSTR(CURRENT_MODE));
#if defined(CURRENT_MODE) && CURRENT_MODE == MODE_MULTI_CTX
for (slave_id = SM1_ID; slave_id <= SM4_ID; slave_id++) {
main_start_timer();
ctxs[slave_id] = modbus_new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
if (ctxs[slave_id] == NULL) {
fprintf(stderr, "Unable to allocate libmodbus context %d: %s\n",
slave_id, modbus_strerror(errno));
return -1;
}
modbus_set_debug(ctxs[slave_id], FALSE);
modbus_set_slave(ctxs[slave_id], slave_id);
if (modbus_connect(ctxs[slave_id]) == -1) {
printf("Connection failed for %d: %s\n",
slave_id, modbus_strerror(errno));
return -1;
}
main_stop_timer();
printf("Created ctx = %p and connected [%d] in %f\n",
ctxs[slave_id], slave_id, main_elapsed_time());
}
#else /* !MODE_MULTI_CTX */
ctx = modbus_new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
if (ctx == NULL) {
fprintf(stderr, "Unable to allocate libmodbus context\n");
return -1;
}
modbus_set_debug(ctx, FALSE);
# if 0
modbus_set_error_recovery(ctx,
MODBUS_ERROR_RECOVERY_LINK |
MODBUS_ERROR_RECOVERY_PROTOCOL);
printf("modbus_set_error_recovery(ctx, LINK | PROTOCOL)\n");
# endif
modbus_set_slave(ctx, SM4_ID);
printf("slave_id = %d\n", SM4_ID);
if (modbus_connect(ctx) == -1) {
printf("Connection failed: %s\n",
modbus_strerror(errno));
modbus_free(ctx);
return -1;
}
printf("connected\n");
#endif /* !MODE_MULTI_CTX */
printf("****************************************\n\n");
slave_id = SM4_ID;
#if defined(CURRENT_MODE) && CURRENT_MODE == MODE_MULTI_CTX
ctx = ctxs[slave_id];
#else /* !MODE_MULTI_CTX */
modbus_set_slave(ctx, slave_id);
#endif /* !MODE_MULTI_CTX */
registers_address = id_address[SM4_ID];
memset(buf, 0, 4*sizeof(uint16_t));
main_start_timer();
if (modbus_read_registers(ctx, registers_address, 2, buf) == -1) {
printf("Read failed (%d): %s\n",
slave_id, modbus_strerror(errno));
printf("%4d = %04X %04X ???\n", registers_address, buf[0], buf[1]);
goto close;
}
main_stop_timer();
printf("modbus_read_registers(ctx = %p, %d, %d, %p) in %f sec\n",
ctx, registers_address, 2, buf,
main_elapsed_time());
printf("Identyfikator SM4 [%d] (wyjscia binarne): 0x%04X 0x%04X (0x8C)\n\n",
slave_id, buf[0], buf[1]);
printf("----------------------------------------\n\n");
sleep_tick = 10; /* msec */
#if defined(CURRENT_MODE) && CURRENT_MODE == MODE_RECONNECT
main_start_timer();
modbus_close(ctx);
main_stop_timer();
printf("modbus_close(ctx) in %f sec\n", main_elapsed_time());
#endif
slave_id = P120_ID;
#if defined(CURRENT_MODE) && CURRENT_MODE == MODE_MULTI_CTX
ctx = ctxs[slave_id];
#else /* !MODE_MULTI_CTX */
printf("modbus_set_slave(ctx, %d)", slave_id);
fflush(stdout);
main_start_timer();
modbus_set_slave(ctx, slave_id);
main_stop_timer();
printf(" in %f sec\n", main_elapsed_time());
#endif /* !MODE_MULTI_CTX */
#if defined(CURRENT_MODE) && CURRENT_MODE == MODE_RECONNECT
main_start_timer();
modbus_connect(ctx);
main_stop_timer();
printf("modbus_connect(ctx) in %f sec\n", main_elapsed_time());
#elif defined(CURRENT_MODE) && CURRENT_MODE == MODE_FLUSH
main_start_timer();
rc = modbus_flush(ctx);
main_stop_timer();
printf("modbus_flush(ctx) = %d in %f sec\n", rc, main_elapsed_time());
#endif
registers_address = id_address[slave_id];
for (i = 0; i < nsteps; i++) {
memset(buf, 0, 4*sizeof(uint16_t));
printf("modbus_read_registers(ctx = %p, %d, %d, %p)",
ctx, registers_address, 2, buf);
fflush(stdout);
time_slept = 0;
main_start_timer();
while (modbus_read_registers(ctx, registers_address, 2, buf) == -1) {
usleep(sleep_tick);
time_slept += sleep_tick;
//printf(".");
//fflush(stdout);
}
main_stop_timer();
printf(" in %f sec\n", main_elapsed_time());
printf("wait: %d +/- %d msec (%d calls)\n",
time_slept, sleep_tick, time_slept/sleep_tick + 1);
}
printf("Identyfikator P120 [%d] (przetwornik obrotow): 0x%04X 0x%04X (0x73)\n\n",
slave_id, buf[0], buf[1]);
#if defined(CURRENT_MODE) && CURRENT_MODE == MODE_RECONNECT
main_start_timer();
modbus_close(ctx);
main_stop_timer();
printf("modbus_close(ctx) in %f sec\n", main_elapsed_time());
#endif
slave_id = SM1_ID;
#if defined(CURRENT_MODE) && CURRENT_MODE == MODE_MULTI_CTX
ctx = ctxs[slave_id];
#else /* !MODE_MULTI_CTX */
printf("modbus_set_slave(ctx, %d)", slave_id);
fflush(stdout);
main_start_timer();
modbus_set_slave(ctx, slave_id);
main_stop_timer();
printf(" in %f sec\n", main_elapsed_time());
#endif /* !MODE_MULTI_CTX */
#if defined(CURRENT_MODE) && CURRENT_MODE == MODE_RECONNECT
main_start_timer();
modbus_connect(ctx);
main_stop_timer();
printf("modbus_connect(ctx) in %f sec\n", main_elapsed_time());
#elif defined(CURRENT_MODE) && CURRENT_MODE == MODE_FLUSH
main_start_timer();
rc = modbus_flush(ctx);
main_stop_timer();
printf("modbus_flush(ctx) = %d in %f sec\n", rc, main_elapsed_time());
#endif
registers_address = id_address[slave_id];
for (i = 0; i < nsteps; i++) {
memset(buf, 0, 4*sizeof(uint16_t));
printf("modbus_read_registers(ctx = %p, %d, %d, %p)",
ctx, registers_address, 2, buf);
fflush(stdout);
time_slept = 0;
main_start_timer();
while (modbus_read_registers(ctx, registers_address, 2, buf) == -1) {
usleep(sleep_tick);
time_slept += sleep_tick;
//printf(".");
//fflush(stdout);
}
main_stop_timer();
printf(" in %f sec\n", main_elapsed_time());
printf("wait: %d +/- %d msec (%d calls)\n",
time_slept, sleep_tick, time_slept/sleep_tick + 1);
}
printf("Identyfikator SM1 [%d] (wejsc analogowych): 0x%04X 0x%04X (0x880x)\n\n",
slave_id, buf[0], buf[1]);
close:
/* Close the connection */
modbus_close(ctx);
modbus_free(ctx);
/* Free timers */
done_timers_main();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment