static int ctx_set_response_timeout(lua_State *L) { ctx_t *ctx = ctx_check(L, 1); int opt = luaL_checkinteger(L, 2); int opt2 = luaL_optinteger(L, 3, 0); #if LIBMODBUS_VERSION_CHECK(3,1,0) modbus_set_response_timeout(ctx->modbus, opt, opt2); #else struct timeval t = { opt, opt2 }; modbus_set_response_timeout(ctx->modbus, &t); #endif return 0; }
modbus_ctrl::modbus_ctrl(modbus_t* context) : next_write_time(0), shadow_registers() { this->context = context; if(context == NULL) { throw modbus_exception(); } //set timeout struct timeval timeout_end; struct timeval timeout_begin; modbus_get_byte_timeout(context, &timeout_end); timeout_end.tv_usec = TIMEOUT_END; modbus_set_byte_timeout(context, &timeout_end); modbus_get_response_timeout(context, &timeout_begin); timeout_begin.tv_usec = TIMEOUT_BEGIN; modbus_set_response_timeout(context, &timeout_begin); //connect if(modbus_connect(context) == -1) { throw modbus_exception(); } }
int main() { modbus_t *ctx; uint16_t tab_reg[64]; int rc; int i; ctx = modbus_new_rtu("/dev/ttyUSB0", 9600, 'N', 8,1); if (modbus_connect(ctx) == -1) { fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); modbus_free(ctx); return -1; } rc = modbus_set_slave(ctx, 1); if (rc == -1) { fprintf(stderr, "%s\n", modbus_strerror(errno)); return -1; } struct timeval response_timeout; response_timeout.tv_sec = 5; response_timeout.tv_usec = 0; modbus_set_response_timeout(ctx, &response_timeout); while(1){ modbus_connect(ctx); rc = modbus_read_registers(ctx, 13952, 1, &tab_reg[0]); if (rc == -1) { fprintf(stderr, "%s\n", modbus_strerror(errno)); return -1; } usleep(17000); //max transaction timing. rc = modbus_read_registers(ctx, 13954, 1, &tab_reg[1]); if (rc == -1) { fprintf(stderr, "%s\n", modbus_strerror(errno)); return -1; } for (i=0; i < 2; i++) { printf("reg[%d]=%d (0x%X)\n", i, tab_reg[i], tab_reg[i]); } //modbus_flush(ctx); //modbus_close(ctx); usleep(10000); modbus_close(ctx); } modbus_free(ctx); return 0; }
bool Modbus::poll(int tm) { timeval tv = { 0, tm }; modbus_set_response_timeout(_modbus, &tv); int recv_bytes = modbus_receive(_modbus, _query); if (recv_bytes == -1) { return false; } DeviceModbus* pdev = findDevice(_query[0]); if (!pdev) { LOG_ERROR("Unknown slave ID: %d", _query[0]); return false; } if (pdev->board()) pdev->board()->HandleRequest(_query, recv_bytes, pdev->modbusMap()); modbus_set_slave(_modbus, pdev->slaveId()); switch (_query[modbus_get_header_length(_modbus)]) { case MODBUS_READ_COILS: case MODBUS_READ_DISCRETE_INPUTS: case MODBUS_READ_INPUT_REGISTERS: case MODBUS_READ_HOLDING_REGISTERS: pdev->updateValues(); modbus_reply(_modbus, _query, recv_bytes, pdev->modbusMap()); break; case MODBUS_WRITE_SINGLE_COIL: //LOG_INFO("MODBUS_WRITE_SINGLE_COIL"); modbus_reply(_modbus, _query, recv_bytes, pdev->modbusMap()); break; case MODBUS_WRITE_SINGLE_REGISTER: LOG_INFO("MODBUS_WRITE_SINGLE_REGISTER"); modbus_reply(_modbus, _query, recv_bytes, pdev->modbusMap()); break; case MODBUS_WRITE_MULTIPLE_COILS: LOG_INFO("MODBUS_WRITE_MULTIPLE_COILS"); break; case MODBUS_WRITE_MULTIPLE_REGISTERS: LOG_INFO("MODBUS_WRITE_MULTIPLE_REGISTERS"); break; default: LOG_ERROR("UNKNOWN FUNCTION"); return false; } pdev->updateWidgets(); return true; }
// Function for changing Modbus response timeout void ModbusClientV1::change_response_timeout(int sec, int usec) { struct timeval t; modbus_get_response_timeout(ctx, &t); printTimeTV("Initial response timeout", &t); t.tv_sec = sec; t.tv_usec = usec; modbus_set_response_timeout(ctx, &t); modbus_get_response_timeout(ctx, &t); printTimeTV("New response timeout", &t); }
static int openSerial(const char *device, int baudrate, char parity, int data_bits, int stop_bits) { int ret = 0; if (!mb) { mb = modbus_new_rtu(device, baudrate, parity, data_bits, stop_bits); struct timeval tv = { 0, 100000 }; modbus_set_response_timeout(mb, &tv); modbus_set_debug(mb, 1); ret = modbus_connect(mb); if (ret < 0) closeSerial(); } return ret; }
TLibModbusContext::TLibModbusContext(const TSerialPortSettings& settings) : Inner(modbus_new_rtu(settings.Device.c_str(), settings.BaudRate, settings.Parity, settings.DataBits, settings.StopBits)) { modbus_set_error_recovery(Inner, MODBUS_ERROR_RECOVERY_PROTOCOL); // FIXME if (settings.ResponseTimeout.count() > 0) { std::chrono::milliseconds response_timeout = settings.ResponseTimeout; struct timeval tv; tv.tv_sec = response_timeout.count() / 1000; tv.tv_usec = (response_timeout.count() % 1000) * 1000; modbus_set_response_timeout(Inner, &tv); } }
TDefaultModbusContext::TDefaultModbusContext(const TModbusConnectionSettings& settings) { InnerContext = modbus_new_rtu(settings.Device.c_str(), settings.BaudRate, settings.Parity, settings.DataBits, settings.StopBits); if (!InnerContext) throw TModbusException("failed to create modbus context"); modbus_set_error_recovery(InnerContext, MODBUS_ERROR_RECOVERY_PROTOCOL); // FIXME if (settings.ResponseTimeoutMs > 0) { struct timeval tv; tv.tv_sec = settings.ResponseTimeoutMs / 1000; tv.tv_usec = (settings.ResponseTimeoutMs % 1000) * 1000; modbus_set_response_timeout(InnerContext, &tv); } }
uint8_t *raw_data_command(int *re_size,int size,uint8_t *raw_req) { modbus_t *sdl; int req_length,re_try = 0; //int rc; uint8_t *rsp; //raw_req = malloc(MODBUS_RTU_MAX_ADU_LENGTH); rsp = malloc(MODBUS_RTU_MAX_ADU_LENGTH); sdl_wifi: sdl = modbus_new_tcp("169.254.114.25",502); //sdl = modbus_new_tcp("192.168.1.25",502); struct timeval old_response_timeout; struct timeval response_timeout; /* Save original timeout */ modbus_get_response_timeout(sdl, &old_response_timeout); /* Define a new and too short timeout! */ response_timeout.tv_sec = 2; response_timeout.tv_usec = 0; modbus_set_response_timeout(sdl, &response_timeout); modbus_set_debug(sdl, TRUE); modbus_set_error_recovery(sdl, MODBUS_ERROR_RECOVERY_LINK | MODBUS_ERROR_RECOVERY_PROTOCOL); modbus_set_slave(sdl,1); if (modbus_connect(sdl) == -1) { if(re_try < 2){re_try++; sleep(2);goto sdl_wifi;} return NULL; } req_length = modbus_send_raw_request(sdl, raw_req, size*sizeof(uint8_t)); //rc = modbus_receive_confirmation(sdl, rsp); *re_size = modbus_receive_confirmation(sdl, rsp); //printf("%s\n",rsp); //printf("%d\n",*re_size); modbus_close(sdl); modbus_free(sdl); return rsp; }
bool mbtcp_init_handle(mbtcp_handle_s **ptr_handle, char *ip, char *port) { BEGIN(enable_syslog); // create a mbtcp context modbus_t *ctx = modbus_new_tcp_pi(ip, port); if (ctx == NULL) { ERR(enable_syslog, "Unable to allocate mbtcp context"); return false; // fail to allocate context } // set tcp connection timeout modbus_set_response_timeout(ctx, 0, tcp_conn_timeout_usec); // @add context to mbtcp hashtable mbtcp_handle_s *handle; handle = (mbtcp_handle_s*)malloc(sizeof(mbtcp_handle_s)); // let alignment bytes being set to zero-value!! memset(handle, 0, sizeof(mbtcp_handle_s)); handle->connected = false; strcpy(handle->key.ip, ip); strcpy(handle->key.port, port); handle->ctx = ctx; HASH_ADD(hh, mbtcp_htable, key, sizeof(mbtcp_key_s), handle); LOG(enable_syslog, "Add %s:%s to mbtcp hashtable", handle->key.ip, mbtcp_htable->key.port); // call by reference to `mbtcp handle address` *ptr_handle = handle; // @connect to server char * reason = NULL; mbtcp_do_connect(handle, &reason); return true; }
bool RbCtrlIface::connectModbus( int retryCount/*=-1*/) { // >>>>> Simulation? if(mSimulActive) { ROS_WARN_STREAM( "ModBus replies are simulated!" ); ros::Duration(1).sleep(); // sleep for a second return true; } // <<<<< Simulation? if( !mModbus ) { ROS_FATAL_STREAM( "ModBus data structure not initialized!" ); return false; } // Closing to reset active connections //modbus_close( mModbus); if( modbus_connect( mModbus ) == -1 ) { ROS_FATAL_STREAM( "Modbus connection failed" ); mBoardConnected = false; return false; } int res=-1; // res = modbus_flush( mModbus ); ros::Duration(1).sleep(); // sleep for a second timeval new_timeout; new_timeout.tv_sec = 2; new_timeout.tv_usec = 0; modbus_set_response_timeout( mModbus, &new_timeout ); modbus_set_byte_timeout( mModbus, &new_timeout ); res = modbus_set_slave( mModbus, mBoardIdx ); if( res != 0 ) { ROS_FATAL_STREAM( "modbus_set_slave error -> " << modbus_strerror( errno ) ); modbus_flush( mModbus ); mBoardConnected = false; return false; } int tryCount=0; bool ok = false; mBoardConnected = true; while(1) { ROS_WARN_STREAM( "- testBoardConnection - Attempt: " << (tryCount+1) ); ok = testBoardConnection(); tryCount++; if( tryCount==retryCount || ok ) break; else ROS_WARN_STREAM( "Trying again..."); } if( !ok ) { ROS_FATAL_STREAM( "Error on modbus: " << modbus_strerror( errno ) ); mBoardConnected = false; return false; } return true; }
void ModbusMaster::readRegisterList(QList<quint16> registerList) { QMap<quint16, ModbusResult> resultMap; quint32 success = 0; quint32 error = 0; /* Open port */ modbus_t * pCtx = openPort(_pSettingsModel->ipAddress(), _pSettingsModel->port()); if (pCtx) { /* Set modbus slave */ modbus_set_slave(pCtx, _pSettingsModel->slaveId()); // Disable byte time-out uint32_t sec = -1; uint32_t usec = 0; modbus_set_byte_timeout(pCtx, sec, usec); // Set response timeout sec = _pSettingsModel->timeout() / 1000; usec = (_pSettingsModel->timeout() % 1000) * 1000uL; modbus_set_response_timeout(pCtx, sec, usec); // Do optimized reads qint32 regIndex = 0; while (regIndex < registerList.size()) { quint32 count = 0; // get number of subsequent registers if ( ((registerList.size() - regIndex) > 1) && (_pSettingsModel->consecutiveMax() > 1) ) { bool bSubsequent; do { bSubsequent = false; // if next is current + 1, dan subsequent = true if (registerList.at(regIndex + count + 1) == registerList.at(regIndex + count) + 1) { bSubsequent = true; count++; } // Break loop when end of list if ((regIndex + count) >= ((uint)registerList.size() - 1)) { break; } // Limit number of register in 1 read if (count > (_pSettingsModel->consecutiveMax() - 1u - 1u)) { break; } } while(bSubsequent == true); } // At least one register count++; // Read registers QList<quint16> registerDataList; qint32 returnCode = readRegisters(pCtx, registerList.at(regIndex) - 40001, count, ®isterDataList); if (returnCode == 0) { success++; for (uint i = 0; i < count; i++) { const quint16 registerAddr = registerList.at(regIndex) + i; const ModbusResult result = ModbusResult(registerDataList[i], true); resultMap.insert(registerAddr, result); } } else { /* only split on specific modbus exception (invalid value and invalid address) */ if ( (returnCode == (MODBUS_ENOBASE + MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS)) || (returnCode == (MODBUS_ENOBASE + MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE)) ) { /* Consecutive read failed */ if (count == 1) { /* Log error */ error++; const quint16 registerAddr = registerList.at(regIndex); const ModbusResult result = ModbusResult(0, false); resultMap.insert(registerAddr, result); } else { error++; /* More than one => read all separately */ for (quint32 i = 0; i < count; i++) { const quint16 registerAddr = registerList.at(regIndex + i); if (readRegisters(pCtx, registerAddr - 40001, 1, ®isterDataList) == 0) { success++; const ModbusResult result = ModbusResult(registerDataList[0], true); resultMap.insert(registerAddr, result); } else { /* Log error */ error++; const ModbusResult result = ModbusResult(0, false); resultMap.insert(registerAddr, result); } } } } else { error++; for (qint32 i = 0; i < registerList.size(); i++) { const quint16 registerAddr = registerList.at(i); const ModbusResult result = ModbusResult(0, false); resultMap.insert(registerAddr,result); } break; } } // Set register index to next register regIndex += count; } closePort(pCtx); /* Close port */ } else { error++; for (qint32 i = 0; i < registerList.size(); i++) { const quint16 registerAddr = registerList.at(i); const ModbusResult result = ModbusResult(0, false); resultMap.insert(registerAddr,result); } } _pGuiModel->setCommunicationStats(_pGuiModel->communicationSuccessCount() + success, _pGuiModel->communicationErrorCount() + error); emit modbusPollDone(resultMap); }
uint8_t * sdl_read_buffsize(int *size) { int resend=0,re_con=0; int rc, size_per_record,num_parameter,i,j; unsigned long num_record, num_byte; modbus_t *sdl; uint16_t * SDL_DATA_BUFF; uint8_t * rsp = malloc(MODBUS_RTU_MAX_ADU_LENGTH); reconnect: sdl = modbus_new_tcp("169.254.114.25",502); struct timeval old_response_timeout; struct timeval response_timeout; /* Save original timeout */ modbus_get_response_timeout(sdl, &old_response_timeout); /* Define a new and too short timeout! */ response_timeout.tv_sec = 2; response_timeout.tv_usec = 0; modbus_set_response_timeout(sdl, &response_timeout); modbus_set_debug(sdl, TRUE); modbus_set_error_recovery(sdl, MODBUS_ERROR_RECOVERY_LINK | MODBUS_ERROR_RECOVERY_PROTOCOL); modbus_set_slave(sdl,1); if (modbus_connect(sdl) == -1) { if(re_con < 3) { re_con++; sleep(2); goto reconnect; } else return NULL; } tryagain: SDL_DATA_BUFF = (uint16_t*)malloc(4*sizeof(uint16_t)); rc = modbus_read_input_registers(sdl,UT_REGISTERS_RD_DATA_BUFFSIZE_ADDRESS,2,SDL_DATA_BUFF); if (rc != 2) { if(resend < 3) { resend++; sleep(2); goto tryagain; } else return -100000; } i = 0; for(j=0;j<rc;j++) { rsp[i+1] = SDL_DATA_BUFF[j] & 0x00ff; rsp[i] = SDL_DATA_BUFF[j]>>8; i = i+2; } *size = 2*rc; return rsp; }
/* * * MAIN process * */ int main(int argc, char* argv[]) { char serial_port[32] = SERIAL_PORT_PREFIX; int baud_rate; int num_slaves; int i, k; if ((argc < 6) || ((argc>6) && (argc<NUM_REG_PER_SLAVE+5))) { printf("Usage:\n\n"); printf(" Single slave (passthrough) mode:\n"); printf(" mbrtud <serial dev> <baudrate> <num_regs> <reg_offset> <slave addr>\n"); printf(" serial dev: name of the serial device used for connection to the Modbus converter (e.g. USB0 or S0)\n"); printf(" baudrate: baudrate used for serial connection\n"); printf(" num_regs: number of consecutive registers to read\n"); printf(" reg_offset: register address offset to add for slave request\n"); printf(" slave addr: address of Modbus slave device\n\n"); printf(" Multiple slave (register mapping) mode:\n"); printf(" mbrtud <serial dev> <baudrate> <num_regs> <reg 1> ... <reg %d> <slave addr> [<slave addr> ...]\n", NUM_REG_PER_SLAVE); printf(" serial dev: name of the serial device used for connection to the Modbus converter (e.g. USB0 or S0)\n"); printf(" baudrate: baudrate used for serial connection\n"); printf(" num_regs: number of consecutive registers to read\n"); printf(" reg x: register map to use for slave request\n"); printf(" slave addr: address of Modbus slave devices (up to %d)\n", MAX_SLAVES); return 0; } openlog("mbrtud", LOG_PID|LOG_CONS, LOG_USER); syslog(LOG_DAEMON | LOG_NOTICE, "Starting Modbus RTU daemon (version %s)\n", VERSION); /* Install signal handler for SIGTERM and SIGINT ("CTRL C") to be used to terminate */ signal(SIGTERM, doExit); signal(SIGINT, doExit); /* Get input parameters */ i=1; strcat(serial_port, argv[i++]); baud_rate = atoi(argv[i++]); num_regs = atoi(argv[i++]); if (argc == 6) { /* Single slave (passthrough) mode */ mode=MODE_SINGLESLAVE; reg_offset = atoi(argv[i++]); slave_addr_table[0] = atoi(argv[i++]); } else { /* Multiple slave (register mapping) mode */ mode=MODE_MULTISLAVE; for (k=0; (i<argc)&&(k<NUM_REG_PER_SLAVE); i++, k++) custom_reg_table[k] = atoi(argv[i]); memset(slave_addr_table, 0, sizeof(slave_addr_table)); for (k=0; (i<argc)&&(k<MAX_SLAVES); i++, k++) slave_addr_table[k] = atoi(argv[i]); num_slaves = k; } /* Init the Modbus RTU connection */ mb = modbus_new_rtu(serial_port, baud_rate, 'N', 8, 1); if (mb == NULL) { syslog(LOG_DAEMON | LOG_ERR, "Unable to create RTU485 context\n"); modbus_free(mb); return 1; } if (modbus_connect(mb) == -1) { syslog(LOG_DAEMON | LOG_ERR, "Connection failed: %s\n", modbus_strerror(errno)); return 2; } /* Set Modbus timeouts */ modbus_set_response_timeout(mb, 20, 0); modbus_set_byte_timeout(mb, 1, 0); /* Specific setting for direction control of the RS485 transceiver */ if (strstr(serial_port, "USB") == NULL) { /* Enable RS485 direction control via RTS line */ if (modbus_rtu_set_rts(mb, MODBUS_RTU_RTS_DOWN) == -1) { syslog(LOG_DAEMON | LOG_ERR, "Setting RTS mode failed: %s\n", modbus_strerror(errno)); modbus_free(mb); return 3; } /* Set RTS control delay (before and after transmission) */ if (DEFAULT_RTS_DELAY > 0) { if (modbus_rtu_set_rts_delay(mb, DEFAULT_RTS_DELAY) == -1) { syslog(LOG_DAEMON | LOG_ERR, "Setting RTS delay failed: %s\n", modbus_strerror(errno)); modbus_free(mb); return 4; } } syslog(LOG_DAEMON | LOG_NOTICE, "using direction control via RTS line"); } //modbus_set_debug(mb, TRUE); syslog(LOG_DAEMON | LOG_NOTICE, "Using Modbus connection on serial port %s at %dbaud", serial_port, baud_rate); if (mode == MODE_SINGLESLAVE) { syslog(LOG_DAEMON | LOG_NOTICE, "Single slave mode - slave address: %d", slave_addr_table[0]); } else { syslog(LOG_DAEMON | LOG_NOTICE, "Multiple slave mode - register map for each slave:"); syslog(LOG_DAEMON | LOG_NOTICE, " Reg | Id "); syslog(LOG_DAEMON | LOG_NOTICE, " ---------"); for (i=0; i<NUM_REG_PER_SLAVE; i++) syslog(LOG_DAEMON | LOG_NOTICE, " %02d | %02d", i+1, custom_reg_table[i]); syslog(LOG_DAEMON | LOG_NOTICE, "List of slaves:"); for (i=0; i<num_slaves; i++) syslog(LOG_DAEMON | LOG_NOTICE, " slave %d: %d (regs[%d...%d])\n", i+1, slave_addr_table[i], i*NUM_REG_PER_SLAVE+1, i*NUM_REG_PER_SLAVE+NUM_REG_PER_SLAVE); } /* Start Modbus TCP server loop */ modbustcp_server(MODBUS_SLAVE_ADDRESS, // Modbus slave address read_register_handler, // Read register handler write_register_handler // Write register handler ); return 0; }
int main( int argc, char **argv ) { int a, rc; int ec = 0; options_t options; modbus_t *ctx; uint8_t *tab_bit; uint16_t *tab_reg; if(argc > 1) { options_init(&options); for (a = 1; a < argc; a++) { options_execute(&options, argv[a], strlen(argv[a])+1); rc = options_finish(&options); DEBUG("argument: '%s' end state: %d\n",argv[a], rc); if (rc == -1) { options_err_disp(&options,argv[a]); ec = 1; goto exit; } } if(rc == 0) { fprintf(stderr, "Missing action argument\n"); ec = 1; goto exit; } if(options.action == _UNDEF) goto exit; // Options are valid options_dump(&options); ctx = modbus_init_con(&options); modbus_set_debug(ctx, options.debug); modbus_set_response_timeout(ctx, &options.timeout); if (modbus_connect(ctx) == -1) { fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); ec = 1; goto destroy; } switch(options.action) { case _RC: case _RD: tab_bit = (uint8_t *) malloc(options.count * sizeof(uint8_t)); DBG_ASSERT(tab_bit != NULL, "Unable to allocate tab_bit!"); memset(tab_bit, 0, options.count * sizeof(uint8_t)); switch(options.action) { case _RC: rc = modbus_read_bits(ctx, options.address, options.count, tab_bit); break; case _RD: rc = modbus_read_input_bits(ctx, options.address, options.count, tab_bit); break; } if (rc == -1) { fprintf(stderr, "%s\n", modbus_strerror(errno)); ec = 1; } else { display_8bit(&options, tab_bit); } free(tab_bit); break; case _RH: case _RI: tab_reg = (uint16_t *) malloc(options.count * sizeof(uint16_t)); DBG_ASSERT(tab_reg != NULL, "Unable to allocate tab_reg!"); switch(options.action) { case _RH: rc = modbus_read_registers(ctx, options.address, options.count, tab_reg); break; case _RI: rc = modbus_read_input_registers(ctx, options.address, options.count, tab_reg); break; } if (rc == -1) { fprintf(stderr, "%s\n", modbus_strerror(errno)); ec = 1; } else { display_16bit(&options, tab_reg); } free(tab_reg); break; case _WC: if(options.count == 1) rc = modbus_write_bit(ctx, options.address, options.coil_values[0]); else { rc = modbus_write_bits(ctx, options.address, options.count, options.coil_values); } if (rc == -1) { fprintf(stderr, "%s\n", modbus_strerror(errno)); ec = 1; } else { printf("Success\n"); } break; case _WH: if(options.count == 1) rc = modbus_write_register(ctx, options.address, options.reg_values[0]); else { rc = modbus_write_registers(ctx, options.address, options.count, options.reg_values); } if (rc == -1) { fprintf(stderr, "%s\n", modbus_strerror(errno)); ec = 1; } else { printf("Success\n"); } break; default: DBG_ASSERT(0,"Unhandled action enum constant!"); } } else { options_help(); ec = 1; goto exit; } close: modbus_close(ctx); destroy: modbus_free(ctx); exit: return ec; }
int settimeouts(void){ modbus_set_byte_timeout(ctx,TIMEOUTDURATION,0); modbus_set_response_timeout(ctx,TIMEOUTDURATION,0); return 1; }
int main(int argc, char *argv[]) { modbus_t *ctx; struct timeval timeout; int ret, ii; /*uint8_t bits[MODBUS_MAX_READ_BITS] = {0};*/ uint16_t regs[MODBUS_MAX_READ_REGISTERS] = {0}; char regs2[MODBUS_MAX_READ_REGISTERS]={0}; FILE *fp = NULL; if(argc != 3){ printf("INsufficient argument"); return 1; } ctx = modbus_new_tcp(MODBUS_CLIENT_IP, MODBUS_CLIENT_PORT); /* set device ID */ modbus_set_slave(ctx, MODBUS_DEVICE_ID); /* Debug mode */ modbus_set_debug(ctx, MODBUS_DEBUG); /* set timeout */ timeout.tv_sec = MODBUS_TIMEOUT_SEC; timeout.tv_usec = MODBUS_TIMEOUT_USEC; modbus_get_byte_timeout(ctx, &timeout); timeout.tv_sec = MODBUS_TIMEOUT_SEC; timeout.tv_usec = MODBUS_TIMEOUT_USEC; modbus_set_response_timeout(ctx, &timeout); if (modbus_connect(ctx) == -1) { fprintf(stderr, "Connexion failed: %s\n", modbus_strerror(errno)); modbus_free(ctx); exit(-1); } /* write data in test.txt */ fp = fopen("test.txt", "w"); if(fp == NULL) { printf("fail to open file!\n"); return -1; } /* read holding registers (0x03 function code) */ ret = modbus_read_registers(ctx, strtol(argv[1], NULL, 16), strtol(argv[2], NULL, 10), regs); if (ret < 0) { fprintf(stderr, "%s\n", modbus_strerror(errno)); } else { printf("HOLDING REGISTERS:\n"); for (ii=0; ii < ret; ii++) { sprintf(regs2, "%d", regs[ii]); fputs(regs2, fp); fputs("\n", fp); printf("[%d]=%d\n", ii, regs[ii]); } } fclose(fp); /* Close the connection */ modbus_close(ctx); modbus_free(ctx); exit(0); }
uint8_t *sdl_read_data(int *size,int register_num) { int retry=0; int rc,read_num,i,j; int created_time; float parameter; long long_value; uint16_t *SDL_Paramenters; read_num = 2*register_num; modbus_t *sdl; uint8_t * rsp = malloc(MODBUS_RTU_MAX_ADU_LENGTH); sdl = modbus_new_tcp("169.254.114.25",502); struct timeval old_response_timeout; struct timeval response_timeout; /* Save original timeout */ modbus_get_response_timeout(sdl, &old_response_timeout); /* Define a new and too short timeout! */ response_timeout.tv_sec = 2; response_timeout.tv_usec = 0; modbus_set_response_timeout(sdl, &response_timeout); modbus_set_debug(sdl, TRUE); modbus_set_error_recovery(sdl, MODBUS_ERROR_RECOVERY_LINK | MODBUS_ERROR_RECOVERY_PROTOCOL); modbus_set_slave(sdl,1); if (modbus_connect(sdl) == -1) { return NULL; } try_more: // The number 6 is the extra bytes that we need to store the data such as checksum SDL_Paramenters = (uint16_t*)malloc(read_num*sizeof(uint16_t)); rc = modbus_read_input_registers(sdl,UT_REGISTERS_RD_DATA_BUFF_ADDRESS,read_num,SDL_Paramenters); //*size = modbus_receive_confirmation(sdl, rsp); if (rc != read_num) { if(retry < 3) { retry++; sleep(2); goto try_more; } else return -100000; } i = 0; for(j=0;j<rc;j++) { rsp[i+1] = SDL_Paramenters[j] & 0x00ff; rsp[i] = SDL_Paramenters[j]>>8; i = i+2; //printf("%x %x\n",rsp[i+1],rsp[i]); } *size = 2*rc; return rsp; }
retCode get_tx_connection(const int this_mb_tx_num, int *ret_connected) { char *fnct_name = "get_tx_connection"; int ret; mb_tx_t *this_mb_tx; mb_link_t *this_mb_link; int this_mb_link_num; struct timeval timeout; if (this_mb_tx_num < 0 || this_mb_tx_num > gbl.tot_mb_tx) { ERR(gbl.init_dbg, "parameter out of range this_mb_tx_num[%d]", this_mb_tx_num); return retERR; } this_mb_tx = &gbl.mb_tx[this_mb_tx_num]; if (ret_connected == NULL) { ERR(this_mb_tx->cfg_debug, "NULL pointer"); return retERR; } this_mb_link_num = this_mb_tx->mb_link_num; if (this_mb_link_num < 0 || this_mb_link_num >= gbl.tot_mb_links) { ERR(this_mb_tx->cfg_debug, "parameter out of range this_mb_link_num[%d]", this_mb_link_num); return retERR; } this_mb_link = &gbl.mb_links[this_mb_link_num]; *ret_connected = 0; //defaults to not connected if (modbus_get_socket(this_mb_link->modbus) < 0) { ret = modbus_connect(this_mb_link->modbus); if (ret != 0 || modbus_get_socket(this_mb_link->modbus) < 0) { modbus_set_socket(this_mb_link->modbus, -1); //some times ret was < 0 and fd > 0 ERR(this_mb_tx->cfg_debug, "mb_tx_num[%d] mb_links[%d] cannot connect to link, ret[%d] fd[%d]", this_mb_tx_num, this_mb_tx->mb_link_num, ret, modbus_get_socket(this_mb_link->modbus)); return retOK; //not connected } DBG(this_mb_tx->cfg_debug, "mb_tx_num[%d] mb_links[%d] new connection -> fd[%d]", this_mb_tx_num, this_mb_tx->mb_link_num, modbus_get_socket(this_mb_link->modbus)); } else { DBG(this_mb_tx->cfg_debug, "mb_tx_num[%d] mb_links[%d] already connected to fd[%d]", this_mb_tx_num, this_mb_tx->mb_link_num, modbus_get_socket(this_mb_link->modbus)); } //set slave id according to each mb_tx ret = modbus_set_slave(this_mb_link->modbus, this_mb_tx->mb_tx_slave_id); if (ret != 0) { ERR(this_mb_tx->cfg_debug, "mb_tx_num[%d] mb_links[%d] cannot set slave [%d]", this_mb_tx_num, this_mb_tx->mb_link_num, this_mb_tx->mb_tx_slave_id); return retOK; //not connected } //set the low level mb_link debug according to each mb_tx modbus_set_debug(this_mb_link->modbus, this_mb_tx->protocol_debug); //set response and byte timeout according to each mb_tx timeout.tv_sec = this_mb_tx->mb_response_timeout_ms / 1000; timeout.tv_usec = (this_mb_tx->mb_response_timeout_ms % 1000) * 1000; #if (LIBMODBUS_VERSION_CHECK(3, 1, 2)) modbus_set_response_timeout(this_mb_link->modbus, timeout.tv_sec, timeout.tv_usec); #else modbus_set_response_timeout(this_mb_link->modbus, &timeout); #endif //DBG(this_mb_tx->cfg_debug, "mb_tx_num[%d] mb_links[%d] response timeout [%d] ([%d] [%d])", // this_mb_tx_num, this_mb_tx->mb_link_num, this_mb_tx->mb_response_timeout_ms, // (int) timeout.tv_sec, (int) timeout.tv_usec); timeout.tv_sec = this_mb_tx->mb_byte_timeout_ms / 1000; timeout.tv_usec = (this_mb_tx->mb_byte_timeout_ms % 1000) * 1000; #if (LIBMODBUS_VERSION_CHECK(3, 1, 2)) modbus_set_byte_timeout(this_mb_link->modbus, timeout.tv_sec, timeout.tv_usec); #else modbus_set_byte_timeout(this_mb_link->modbus, &timeout); #endif //DBG(this_mb_tx->cfg_debug, "mb_tx_num[%d] mb_links[%d] byte timeout [%d] ([%d] [%d])", // this_mb_tx_num, this_mb_tx->mb_link_num, this_mb_tx->mb_byte_timeout_ms, // (int) timeout.tv_sec, (int) timeout.tv_usec); *ret_connected = 1; //is connected (fd >= 0) return retOK; }