/*! * \fn setLight(int light, int state); * \param light what color * \param state on or off */ void MPSDeliver::setLight(int light, int state, int blink) { int rc; uint16_t send[1] = {0}; if(state == 1 && blink == 0) { send[0] = 1; } else if(state == 1 && blink == 1) { send[0] = 2; } //uint16_t sendblink[1] = {(uint16_t)blink}; if(light == 1) { rc = modbus_write_registers(mb, 3, 1, send); //rc = modbus_write_registers(mb, 6, 1, sendblink); } else if(light == 2) { rc = modbus_write_registers(mb, 4, 1, send); //rc = modbus_write_registers(mb, 7, 1, sendblink); } else if(light == 3) { rc = modbus_write_registers(mb, 5, 1, send); //rc = modbus_write_registers(mb, 8, 1, sendblink); } else { throw fawkes::Exception("Light state not available"); } if(rc == -1) { machineState = DISCONNECTED; } }
/*! * \fn sendDeliver(int lane) * \brief send deliver command * \param lane on which lane have to be deliver */ void MPSDeliver::sendDeliver(int lane) { uint16_t send[1] = {(uint16_t)lane}; int rc = modbus_write_registers(mb, 0, 1, send); if(rc == -1) { machineState = DISCONNECTED; } }
void MPSPickPlace1::deliverProduct() { uint16_t send1[1] = {(uint16_t) 1}; int rc = modbus_write_registers(mb, 1, 1, send1); if (rc != 1) { machineState = DISCONNECTED; } }
/** * @brief Help function. FC15, FC16 request handler * * @fc Function code 15 and 16 only. * @param handle Mbtcp handle. * @param req cJSON request object. * @return Modbus response string in JSON format. */ static char * mbtcp_multi_write_req(int fc, mbtcp_handle_s *handle, cJSON *req) { BEGIN(enable_syslog); int addr = json_get_int(req, "addr"); int len = json_get_int(req, "len"); int tid = json_get_int(req, "tid"); uint8_t *bits; // FC15 uint16_t *regs; // FC16 cJSON * data = NULL; int ret = 0; switch (fc) { case 15: // memory reset for variable length array bits = (uint8_t *) malloc(len * sizeof(uint8_t)); memset(bits, 0, len * sizeof(uint8_t)); // handle uint8_t array data = cJSON_GetObjectItem(req, "data"); for (int i = 0 ; i < cJSON_GetArraySize(data) ; i++) { uint8_t subitem = cJSON_GetArrayItem(data, i)->valueint; bits[i] = subitem; LOG(enable_syslog, "[%d]=%d", i, bits[i]); } ret = modbus_write_bits(handle->ctx, addr, len, bits); free(bits); break; case 16: // memory reset for variable length array regs = (uint16_t *) malloc(len * sizeof(uint16_t)); memset(regs, 0, len * sizeof(uint16_t)); // handle uint16_t array data = cJSON_GetObjectItem(req, "data"); for (int i = 0 ; i < cJSON_GetArraySize(data) ; i++) { uint16_t subitem = cJSON_GetArrayItem(data, i)->valueint; regs[i] = subitem; LOG(enable_syslog, "[%d]=%d", i, regs[i]); } ret = modbus_write_registers(handle->ctx, addr, len, regs); free(regs); break; default: return set_modbus_error_resp(tid, "Wrong function code"); } if (ret < 0) { return set_modbus_errno_resp(tid, handle, errno); } else { return set_modbus_no_data_ok_resp(tid); } }
/*! * \fn produceEnd(int updown) * \param updown set workpiece(1) or get workpiece(2) * \brief send produce message over Modbus */ void MPSPickPlace1::produceEnd(int updown) { uint16_t send1[1] = {(uint16_t)updown}; std::cout << updown << std::endl; int rc = modbus_write_registers(mb, 0, 1, send1); if (rc != 1) { machineState = DISCONNECTED; } }
void MPSPickPlace1::clearRegister() { uint16_t send[3] = {0}; int rc = modbus_write_registers(mb, 0, 3, send); if(rc == -1) { machineState = DISCONNECTED; } }
void ModBusTCP::WriteMultipleHoldingRegisters(quint16 slave, quint16 addr, quint16 num, quint16 *data) { quint16 tmp_data[128]; quint16 repeat = NumberOfRepeat; qDebug() << "Write MultiHoldingRegisters from slave: " << slave << " Addr: " << addr << " Number: " << num; while(repeat) { if (modbus_set_slave(ctx, slave) == -1) { if (--repeat == 0) { qDebug() << "Error set slave: " << errno; emit ModBusError(errno); return; } } else { repeat = 0; } } for (int i = 0; i < num; i++) { tmp_data[i] = qToBigEndian<quint16>(data[i]); } repeat = NumberOfRepeat; while(repeat) { if (modbus_write_registers(ctx, addr, num, tmp_data) == -1) { if (--repeat == 0) { qDebug() << "Error write HoldingRegisters: " << errno; emit ModBusError(errno); return; } } else { repeat = 0; } } qDebug() << "Write OK" << repeat; emit ModBusOK(); }
int EnergyCam_TriggerInstallation(void) { uint32_t wroteRegCnt; const uint32_t regCnt = 2; uint16_t holdingRegs[2] = {100,1}; wroteRegCnt = modbus_write_registers(m_ctx, MODBUS_GET_INTERNAL_ADDR_FROM_OFFICIAL(MODBUS_SLAVE_HOLDINGREG_MEMMAP_ACTIONOCRINSTALLATIONTO), regCnt, &holdingRegs[0]); if (wroteRegCnt == -1) { fprintf(stderr, "TriggerInstallation failed with '%s'\n", modbus_strerror(errno)); return MODBUSERROR; } else { fprintf(stdout, "TriggerInstallation \n"); return MODBUSOK; } return MODBUSERROR; }
/* * This Function sends modbus request and returns the response * Arguments: * unsigned char * fn :- Modbus request array. 1st byte is function code, next 2 bytes is address of register * 4th 5th byte is no. of register. 6th 7th byte is data. Modbus response is sent back on * 6th and 7th byte * Return Value :- 0 : On successful * -1 : on error */ int MBSendRequest(unsigned char *fn) { uint16_t address,NIitem,*data,data1 ; int ret=0; address = *(fn+1); address = address<<8; // This is done so that data recieved is in big indian format. address = address | (*(fn+2)); //It should be converted to little indian format NIitem = *(fn+3); NIitem = NIitem<<8; NIitem = NIitem | *(fn+4); data1 = *(fn+5); data1 = data1<<8; data1 = data1 | *(fn+6); data = &data1; printf("Function code = %d \n",*fn); printf("register address = %x \n",address); printf("NIitem = %x \n",NIitem); printf("Data=%d\n",*data); switch(*fn) { case 1:ret = modbus_read_bits(ctx,address,NIitem,(uint8_t*) data); break; case 2:ret = modbus_read_input_bits(ctx,address,NIitem,(uint8_t*) data); break; case 3:ret = modbus_read_registers(ctx,address,NIitem,data); break; case 4:ret = modbus_read_input_registers(ctx,address,NIitem,data); break; case 5:ret = modbus_write_bit(ctx,address,*data); break; case 6:ret = modbus_write_register(ctx,address,*data); break; case 15:ret = modbus_write_bits(ctx,address,NIitem,(uint8_t*) data); break; case 16:ret = modbus_write_registers(ctx,address,NIitem,data); break; } *(fn+6)=((*data) >> 8)& 0x00ff; *(fn+5)= (*data) & 0x00ff; return ret; }
int write_registers(int address, int length, uint16_t data[]){ int retries = 4; do { if (modbus_write_registers(ctx,address,length,data)==length){ qWarning() << "Successful Write"; return 1; }else{ retries--; qWarning() << "Failed to Write, re-attempting"; qWarning() << address; qWarning() << length; } } while( retries > 0); qWarning() << "Failed to Write, reached retry limit!"; return 0; }
static int ctx_write_registers(lua_State *L) { ctx_t *ctx = ctx_check(L, 1); int addr = luaL_checknumber(L, 2); int rc; int rcount; /* * TODO - could allow just a series of arguments too? easier for * smaller sets? (more compatible with "write_register"?) */ luaL_checktype(L, 3, LUA_TTABLE); /* array style table only! */ int count = lua_objlen(L, 3); if (count > MODBUS_MAX_WRITE_REGISTERS) { return luaL_argerror(L, 3, "requested too many registers"); } /* Convert table to uint16_t array */ uint16_t *buf = malloc(count * sizeof(uint16_t)); assert(buf); for (int i = 1; i <= count; i++) { lua_rawgeti(L, 3, i); /* user beware! we're not range checking your values */ if (lua_type(L, -1) != LUA_TNUMBER) { free(buf); return luaL_argerror(L, 3, "table values must be numeric yo"); } buf[i-1] = lua_tonumber(L, -1); lua_pop(L, 1); } rc = modbus_write_registers(ctx->modbus, addr, count, buf); if (rc == count) { rcount = 1; lua_pushboolean(L, true); } else { rcount = libmodbus_rc_to_nil_error(L, rc, count); } free(buf); return rcount; }
//========================================================================================== int MainWindow::SetTimeToICPDAS(QString IPaddr,QDateTime icpNewDT) { int res; modbus_t *mb; uint16_t tab_reg[200]; const uint number_write_registers=7; tab_reg[0]=icpNewDT.date().year(); tab_reg[1]=icpNewDT.date().month(); tab_reg[2]=icpNewDT.date().day(); tab_reg[3]=icpNewDT.time().hour(); tab_reg[4]=icpNewDT.time().minute(); tab_reg[5]=icpNewDT.time().second(); tab_reg[6]=1; //flag //inialized context mb = modbus_new_tcp(IPaddr.toStdString().c_str(), 502); if (mb==NULL) {return -1;} res=modbus_connect(mb); modbus_set_slave(mb, 1); if (res==-1) {modbus_free(mb); return -2;} res=modbus_write_registers(mb, 11, number_write_registers, tab_reg);// 7 reg from 40012 if (res!=number_write_registers){modbus_close(mb);modbus_free(mb); return -3;} modbus_close(mb); modbus_free(mb); return 1; }
bool RbCtrlIface::writeMultiReg( uint16_t startAddr, uint16_t nReg, vector<uint16_t> vals ) { if(mSimulActive) { //mBoardMutex.lock(); { ros::Duration(0.001).sleep(); // sleep for a msec } //mBoardMutex.unlock(); return true; } if( !mBoardConnected ) { ROS_ERROR_STREAM( "RoboController is not connected!" ); return false; } //mBoardMutex.lock(); { int res = modbus_write_registers( mModbus, startAddr, nReg, vals.data() ); if(res!=nReg) { ROS_ERROR_STREAM( "modbus_write_registers error -> " << modbus_strerror( errno ) << "[First regAddress: " << startAddr << "- #reg: " << nReg << "]" ); //mBoardMutex.unlock(); return false; } } //mBoardMutex.unlock(); return true; }
int ModbusClientV1::writePacket(RSPacket::PacketStruct * p, int size) { if (verbose > 2) { printf("SENDING PACKET\n"); } if (verbose > 3) printPacket(*p); if (!isInitialized) { fprintf(stderr, "writePacket failed! Modbus is not initialized!\n"); return -1; } int rc = modbus_write_registers(ctx, 0, size, (uint16_t*) p); if (rc == -1) { fprintf(stderr, "Failed to write BallsCount data [%s]\n", modbus_strerror(errno)); } return rc; }
/* Read values from modbus */ uint8_t read_modbus(modbus_t *ctx, uint8_t readOrWrite, uint16_t modbusRegister, GenDataType_t typeOfValue, MoBuRegType_t typeOfReg, uint8_t desiredBit, uint16_t* valueArray) { uint8_t noOfRegisters = 0; uint16_t modbusValueArray[2]; uint16_t modbusTmpValue; //used for bit values read from registers memset(modbusValueArray, 0x00, (sizeof(uint16_t) * 2)); if (readOrWrite > 0) { log_entry(APP_NAME, "invalid parameter in read_modbus: Only reading values supported"); printf("invalid parameter in read_modbus: Only reading values supported"); return -1; } switch (typeOfValue) { case bitCoil: case sint16: // read one address case uint16: //read one address noOfRegisters = 1; break; case sint32: //read 2 registers case uint32: case float32: noOfRegisters = 2; break; default: log_entry(APP_NAME, "MODBUSD; unknown dataType"); printf("MODBUSD; unknown dataType: %d", typeOfValue); } switch (typeOfReg) { case coil: if (0 == readOrWrite) { //read if (1 != modbus_read_bits(ctx, modbusRegister, 1, (uint8_t *) modbusValueArray)) { log_entry(APP_NAME, "MODBUSD: could not read coils"); printf("MODBUSD: could not read coils: %d, %s", modbusRegister, strerror(errno)); return -1; } } else { /* first read the whole unit16 value */ if (1 == modbus_read_bits(ctx, modbusRegister, 1, (uint8_t *) modbusValueArray)) { if (valueArray[0] == 0) { modbusTmpValue = 0; } else if (valueArray[0] == 1) { //setting bit to 1 modbusTmpValue = 1; } else { //toggle the bit if(0 == modbusValueArray[0]){ modbusTmpValue = 1; } else { modbusTmpValue = 0; } } if (1 != modbus_write_bit(ctx, modbusRegister, modbusTmpValue)) { return -1; } } } break; case discrete_input: if (0 == readOrWrite) { //read if (1 != modbus_read_input_bits(ctx, modbusRegister, noOfRegisters, (uint8_t *) &(modbusValueArray[0]))) { log_entry(APP_NAME, "MODBUSD: could not read input"); printf("MODBUSD: could not read input: %d, %s", modbusRegister, strerror(errno)); return -1; } } else { log_entry(APP_NAME, "MODBUSD: illegal operation -> unable to write on discrete input"); printf("MODBUSD: illegal operation -> unable to write on discrete input"); } break; case holding_register: if (0 == readOrWrite) { //read if (1 != modbus_read_registers(ctx, modbusRegister, noOfRegisters, &(modbusValueArray[0]))) { return -1; } } else { if (1 != modbus_write_registers(ctx, modbusRegister, noOfRegisters, &(valueArray[0]))) { return -1; } } break; case input_register: if (0 == readOrWrite) { //read if (1 != modbus_read_input_registers(ctx, modbusRegister, noOfRegisters, &(modbusValueArray[0]))) { log_entry(APP_NAME, "MODBUSD: could not read input registers"); printf("MODBUSD: could not read input registers: %d, %s", modbusRegister, strerror(errno)); return -1; } } else { log_entry(APP_NAME, "unable to write on input register"); printf("unable to write on input register"); } break; case holding_bit: if (0 == readOrWrite) { //read if (1 == modbus_read_registers(ctx, modbusRegister, noOfRegisters, &modbusTmpValue)) { modbusValueArray[0] = modbusTmpValue & (1 << desiredBit); } else { return -1; } } else { /* first read the whole unit16 value */ if (1 == modbus_read_registers(ctx, modbusRegister, noOfRegisters, &modbusTmpValue)) { if (valueArray[0] == 0) { //clearing a bit at postion desired bit modbusTmpValue &= ~(1 << desiredBit); } else if (valueArray[0] == 1) { //setting bit to 1 modbusTmpValue |= 1 << desiredBit; } else { //toggle the bit modbusTmpValue ^= 1 << desiredBit; } if (1 != modbus_write_registers(ctx, modbusRegister, noOfRegisters, &modbusTmpValue)) { return -1; } } else { return -1; } } break; case input_bit: if (0 == readOrWrite) { //read if (1 == modbus_read_input_registers(ctx, modbusRegister, noOfRegisters, &modbusTmpValue)) { modbusValueArray[0] = modbusTmpValue & (1 << desiredBit); } else { return -1; } } else { log_entry(APP_NAME, "MODBUSD; unable to write single bit for input register"); printf("MODBUSD; unable to write single bit for input register"); return -1; } break; default: log_entry(APP_NAME, "MODBUSD; unknown register type"); printf("MODBUSD; unknown register type %d", typeOfReg); } if (0 == readOrWrite) { //read valueArray[0] = modbusValueArray[0]; valueArray[1] = modbusValueArray[1]; } return 1; }
void TDefaultModbusContext::WriteHoldingRegisters(int addr, int nb, const uint16_t *data) { if (modbus_write_registers(InnerContext, addr, nb, data) < nb) throw TModbusException("failed to write " + std::to_string(nb) + " holding register(s) @ " + std::to_string(addr)); }
int connectToSlave(modbus_t *ctx) { uint16_t *tab_rp_registers; // for getting data from server( slave module ) int i,j; // for repeat int nb_points; // number of register int rc; // register counter char query[QUERY_SIZE]; // for getting query char sSlaveNum[3]; char sFuncCode[3]; char sRegiAdd[5]; char sRegiNum[5]; char sData[5]; char svData[MODBUS_MAX_WRITE_REGISTERS][5]; // MODBUS_MAX_WRITE_REGISTERS : set value in modbus.h char sWriteNum[3]; // str for read data in query uint16_t nSlaveNum; uint16_t nFuncCode; uint16_t nRegiAdd; uint16_t nRegiNum; uint16_t nData; uint16_t nvData[MODBUS_MAX_WRITE_REGISTERS]; uint8_t nWriteNum; // variable for read data in query /* Allocate and initialize the memory to store the registers */ nb_points = (UT_REGISTERS_NB > UT_INPUT_REGISTERS_NB) ? UT_REGISTERS_NB : UT_INPUT_REGISTERS_NB; tab_rp_registers = (uint16_t *) malloc(nb_points * sizeof(uint16_t)); memset(tab_rp_registers, 0, nb_points * sizeof(uint16_t)); while ( 1 ) { memset(sSlaveNum, 0, sizeof(sSlaveNum) ); memset(sFuncCode, 0, sizeof(sFuncCode) ); memset(sRegiAdd, 0, sizeof(sRegiAdd) ); memset(sRegiNum, 0, sizeof(sRegiNum) ); memset(sData, 0, sizeof(sData) ); for ( i=0 ; i< MODBUS_MAX_WRITE_REGISTERS ; i++ ) memset(svData[i], 0, sizeof(svData[i]) ); memset(sWriteNum, 0, sizeof(sWriteNum) ); memset(query, 0, QUERY_SIZE); // memory init printf("\tinput Query ( \"q\" exit, \"all\" show all data, \"r\" random query )\n"); printf("\tQUERY : "); scanf( "%s", query ); printf("\n"); if ( !strcmp( query, "q" ) ) // quit message break; // while break else if ( !strcmp( query, "all" ) ) { PrintAll(ctx, tab_rp_registers, UT_REGISTERS_NB); // print all data continue; } else if ( !strcmp( query, "r") ) // random code { printf("\t\"r3\" : 0x03 \"r6\" : 0x06 \"r1\" : 0x10\n\n"); continue; } else if ( !strcmp( query, "r3") ) RandomQuery( query, FUNC03 ); // make random code 0x03 else if ( !strcmp( query, "r6") ) RandomQuery( query, FUNC06 ); // make random code 0x06 else if ( !strcmp( query, "r1") ) RandomQuery( query, FUNC10 ); // make random code 0x10 else if ( !isHexCode(query) || strlen(query)<12 ) // if incorrect query inputed { printf("\tplease input correct query\n\n"); continue; } memcpy( sSlaveNum, (char *)&(query[0]), 2 ); memcpy( sFuncCode, (char *)&(query[2]), 2 ); memcpy( sRegiAdd, (char *)&(query[4]), 4 ); // get Slave ID, Function code, Register start address from query nSlaveNum = strtol( sSlaveNum, NULL, 16 ); nFuncCode = strtol( sFuncCode, NULL, 16 ); nRegiAdd = strtol( sRegiAdd, NULL, 16); // translate string to uint variable switch ( nFuncCode ) { /**/ case 0x03: // 3 read multiple data in RW register /**/ case 0x04: // 4 read multiple data in RO register { if ( strlen(query) != 12 ) // func 0x03, 0x04 must have 16 byte len // last 4 byte is CRC // 16 - 4 = 12 { printf("\tplease input correct query\n\n"); break; // switch break } memcpy( sRegiNum, (char *)&(query[8]), 4 ); nRegiNum = strtol( sRegiNum, NULL, 16); rc = modbus_read_registers(ctx, nRegiAdd, nRegiNum, tab_rp_registers); // func 0x03 in modbus library if ( rc < 1 ) { printf("read operation error\n"); // error break; // switch break } printf("\t---------------------------------------- Data ----------------------------------------\n"); printf("\t\t 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F\n"); printf("\t----------------------------------------------------------------------------------------"); for (i=0 , j=nRegiAdd%0x10; i<nRegiNum+j ; i++ ) { if ( i%16 == 0 ) printf("\n\t0x%02X\t", nRegiAdd-j+i); if ( i >= j && i < j+nRegiNum ) printf(" %04X", *(tab_rp_registers+i-j)); else printf(" "); } printf("\n\t----------------------------------------------------------------------------------------\n\n"); } break; // switch break /**/ case 0x06: // 6 write one data in RW register { if ( strlen(query) != 12 ) // func 0x06 must have 16 byte len // last 4 byte is CRC // 16 - 4 = 12 { printf("\tplease input correct query\n\n"); break; // switch break } memcpy( sData, (char *)&(query[8]), 4 ); nData = strtol( sData, NULL, 16); rc = modbus_write_register(ctx, nRegiAdd, nData); // func 0x06 in modbus library if ( rc != 1 ) { printf("write operation error\n\n"); break; // switch break } printf("\n"); } break; /**/ case 0x10: // 16 write multiple data in RW register { memcpy( sRegiNum, (char *)&(query[8]), 4 ); memcpy( sWriteNum, (char *)&(query[12]), 2 ); nRegiNum = strtol( sRegiNum, NULL, 16); nWriteNum = strtol( sWriteNum, NULL, 16); if ( strlen(query) != 14+(nRegiNum*4) || nWriteNum != nRegiNum*2 ) { // func 0x06 must have 16 byte len // last 4 byte is CRC // 16 - 4 = 12 printf("\tplease input correct query\n\n"); break; // switch break } for ( i=0 ; i< nRegiNum ; i++ ) { memcpy( svData[i], (char *)&(query[14+(i*4)]), 4 ); nvData[i] = strtol( svData[i], NULL, 16); } printf("\n"); modbus_write_registers(ctx, nRegiAdd, nRegiNum, nvData); // func 0x10 in modbus library } break; // switch break; default : printf("incorrect Function code.\n\n"); // function code is not 0x03, 0x06, 0x10 } // switch end } // while end printf("interface end.\n"); /* Free the memory */ free(tab_rp_registers); }
int main(int argc, char *argv[]) { extern int errno; modbus_t *ctx; int registers; uint8_t rtu; int addr; int nb; int rc; int ch; int verbose=0; int debug=0; int port=502; char name[255]; addr=0; nb=1; strcpy(name,"127.0.0.1"); // ctx = modbus_new_tcp("192.168.0.143", 1502); // ctx = modbus_new_tcp("127.0.0.1", 1502); // ctx = modbus_new_tcp("10.0.0.101", 502); // ctx = modbus_new_tcp("192.168.100.72", 1502); while((ch = getopt(argc,argv,"dvh?p:i:r:n:c:")) != -1) { switch(ch) { case 'c': sscanf(optarg,"%x",®isters); break; case 'd': debug=1; break; case 'v': verbose=1; break; case 'h': case '?': printf("Usage\n"); exit(1); break; case 'p': port=atoi(optarg); break; case 'i': strcpy(name,optarg); break; case 'r': addr=atoi(optarg); break; case 'n': nb=atoi(optarg); break; } } if (verbose) { printf("Name :%s\n",name); printf("Port :%d\n",port); printf("Register:%d\n",addr); printf("Count :%d\n", nb); printf("Data :%04x\n", registers); printf("==================\n"); } ctx = modbus_new_tcp(name, port); if (ctx == NULL) { fprintf(stderr, "modbus_new_tcp failed.\n"); exit(-1); } if(debug) { modbus_set_debug(ctx, TRUE); } else { modbus_set_debug(ctx, FALSE); } modbus_set_error_recovery(ctx, MODBUS_ERROR_RECOVERY_LINK | MODBUS_ERROR_RECOVERY_PROTOCOL); if (modbus_connect(ctx) == -1) { fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); modbus_free(ctx); return -1; } rc = modbus_write_registers(ctx, addr, nb,(uint16_t *) ®isters); if (rc != nb) { printf("Failed:%d\n",rc); printf("==>%s\n", modbus_strerror(errno)); } // printf("\nData = 0x%04x\n", registers & 0xffff); sleep(1); modbus_close(ctx); modbus_free(ctx); return 0; }
int ConnectionModbusPoint::writeRegisters(int address, int cnt, uint16_t *src) { return modbus_write_registers(ctx, address, cnt, src); }
int main(int argc, char *argv[]) { modbus_t *ctx; struct timeval timeout; int ret, i, rc, ii,iii; int nb_pointers; // unit16_t *tab_rp_registers; uint16_t regs[MODBUS_MAX_READ_REGISTERS] = {0}; uint16_t regs2[MODBUS_MAX_READ_REGISTERS] = {0}; char regs3[MODBUS_MAX_READ_REGISTERS] = {0}; FILE *fp = NULL; if(argc < 3){ printf("INsufficient argument"); return -1; } ctx = modbus_new_rtu(MODBUS_SERIAL_DEV, MODBUS_SERIAL_BAUDRATE, MODBUS_SERIAL_PARITY, MODBUS_SERIAL_DATABITS, MODBUS_SERIAL_STOPBITS); if (ctx == NULL) { fprintf(stderr, "Unable to create the libmodbus context\n"); exit(-1); } i = modbus_rtu_get_serial_mode(ctx); if( i == MODBUS_RTU_RS232) { printf("Serial mode = RS232\n"); ret = modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS232); if(ret < 0) fprintf(stderr, "modbus_rtu_set_serial_mode() error: %s\n", strerror(errno)); } else if(i == MODBUS_RTU_RS485) { printf("Serial mode = RS485\n"); ret = modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS485); if(ret < 0) fprintf(stderr, "modbus_rtu_set_serial_mode() error: %s\n", strerror(errno)); } else { printf("Serial mode = RS485\n"); ret = modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS485); if(ret < 0) fprintf(stderr, "modbus_rtu_set_serial_mode() error: %s\n", strerror(errno)); } /* set slave device ID */ modbus_set_slave(ctx, MODBUS_DEVICE_ID); /* Debug mode */ modbus_set_debug(ctx, MODBUS_DEBUG); if (modbus_connect(ctx) == -1) { fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); modbus_free(ctx); return -1; } /* Allocate and initialize the memory to store the registers */ /* nb_points = (UT_REGISTERS_NB > UT_INPUT_REGISTERS_NB) ? UT_REGISTERS_NB : UT_INPUT_REGISTERS_NB; tab_rp_registers = (uint16_t *) malloc(nb_points * sizeof(uint16_t)); memset(tab_rp_registers, 0, nb_points * sizeof(uint16_t)); */ /* write data in test.txt */ fp = fopen("test2.txt", "w"); if(fp == NULL) { printf("fail to open file!\n"); return -1; } for( iii=1; iii <= strtol(argv[2],NULL, 10);iii++) { regs[iii] = strtol(argv[iii+2], NULL, 10); } rc = modbus_write_registers(ctx, strtol(argv[1], NULL, 16), strtol(argv[2], NULL, 10), ®s[1]); if (rc < 0) { fprintf(stderr, "%s\n", modbus_strerror(errno)); } /* read holding registers (0x03 function code) */ rc = modbus_read_registers(ctx, strtol(argv[1], NULL, 16), strtol(argv[2], NULL, 10), regs2); if (rc < 0) { fprintf(stderr, "%s\n", modbus_strerror(errno)); } else { printf("HOLDING REGISTERS:\n"); for (ii=0; ii < rc; ii++) { sprintf(regs3, "%d", regs2[ii]); fputs(regs3, fp); fputs("\n", fp); printf("[%d]=%d\n", ii, regs2[ii]); } } fclose(fp); /* Close the connection */ modbus_close(ctx); modbus_free(ctx); return 0; }
int main(int argc, char *argv[]) { modbus_t *ctx; uint16_t *tab_reg; int rc; int use_backend; const uint16_t values[] = {5678, 9012}; if (argc > 1) { if (strcmp(argv[1], "tcp") == 0) { use_backend = TCP; } else if (strcmp(argv[1], "rtu") == 0) { use_backend = RTU; } else { printf("Usage:\n %s [tcp|rtu] - Modbus client for unit testing\n\n", argv[0]); exit(1); } } else { /* By default */ use_backend = TCP; } if (use_backend == TCP) { ctx = modbus_new_tcp("127.0.0.1", 1502); } else { ctx = modbus_new_rtu("/dev/ttyUSB1", 115200, 'N', 8, 1); } if (ctx == NULL) { fprintf(stderr, "Unable to allocate libmodbus context\n"); return -1; } modbus_set_debug(ctx, TRUE); modbus_set_error_recovery(ctx, MODBUS_ERROR_RECOVERY_LINK | MODBUS_ERROR_RECOVERY_PROTOCOL); if (use_backend == RTU) { modbus_set_slave(ctx, SERVER_ID); } if (modbus_connect(ctx) == -1) { fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); modbus_free(ctx); return -1; } /* Allocate and initialize the memory to store the registers */ tab_reg = (uint16_t *) malloc(10 * sizeof(uint16_t)); /* Single register */ printf("1/2 modbus_write_register"); rc = modbus_write_register(ctx, 0, 1234); if (rc != 1) { goto close; } printf("2/2 modbus_read_registers"); rc = modbus_read_registers(ctx, 0, 1, tab_reg); if (rc != 1) { goto close; } if (tab_reg[0] != 1234) { goto close; } /* Many registers */ printf("1/2 modbus_write_registers"); rc = modbus_write_registers(ctx, 1, 2, values); if (rc != 2) { goto close; } printf("2/2 modbus_read_registers"); rc = modbus_read_registers(ctx, 1, 2, tab_reg); if (rc != 2) { goto close; } close: /* Free the memory */ free(tab_reg); /* Close the connection */ modbus_close(ctx); modbus_free(ctx); return 0; }
int main(int argc, char **argv) { uint8_t *tab_bit; uint16_t *tab_reg; /* Allocate and initialize the memory to store the status */ tab_bit = (uint8_t *)malloc(MODBUS_MAX_READ_BITS * sizeof(uint8_t)); memset(tab_bit, 0, MODBUS_MAX_READ_BITS * sizeof(uint8_t)); /* Allocate and initialize the memory to store the registers */ tab_reg = (uint16_t *)malloc(MODBUS_MAX_READ_REGISTERS * sizeof(uint16_t)); memset(tab_reg, 0, MODBUS_MAX_READ_REGISTERS * sizeof(uint16_t)); /* Defaults */ char host[1024] = "127.0.0.1"; size_t port = 502; enum mb_operations operation = read_registers; size_t base_addr = 0; // read from address 0 by deafult size_t n_addrs = 10; // read forst 10 addressxes by default. size_t n_times = 1; // one times by default. size_t interval = 0; // no waiting by default. bool quiet = false; // Do not suppress output by default. size_t n_data = 0; // The number of data items from the command line. char **data_items; // Array of data items from the command line. int c; int rc; while (1) { c = getopt(argc, argv, "h:p:o:b:a:n:i:q"); if (c == -1) break; switch (c) { case 'h': printf("Connect to host: '%s'\n", optarg); strncpy(host, optarg, 1024); // Made host str 1024. Should define a constant. break; case 'p': printf("Connect on port: '%s'\n", optarg); port = strtoul(optarg, (void *)0, 10); break; case 'o': printf("Option o with value '%s'\n", optarg); if (!strcmp("read_bits", optarg)) operation = read_bits; if (!strcmp("read_input_bits", optarg)) operation = read_input_bits; if (!strcmp("read_registers", optarg)) operation = read_registers; if (!strcmp("read_input_registers", optarg))operation = read_input_registers; if (!strcmp("write_bit", optarg)) operation = write_bit; if (!strcmp("write_register", optarg)) operation = write_register; if (!strcmp("write_bits", optarg)) operation = write_bits; if (!strcmp("write_registers",optarg)) operation = write_registers; break; case 'b': printf("Base address set to: '%s'\n", optarg); base_addr = strtoul(optarg, (void *)0, 10);; break; case 'a': printf("Number of addresses to read: '%s'\n", optarg); n_addrs = strtoul(optarg, (void *)0, 10); if (n_addrs > MODBUS_MAX_READ_REGISTERS) { printf("Number of addresses to read adjusted to maximum: '%i'\n", MODBUS_MAX_READ_REGISTERS); n_addrs = MODBUS_MAX_READ_REGISTERS; } break; case 'n': printf("Repeat this many times: '%s'\n", optarg); n_times = strtoul(optarg, (void *)0, 10); break; case 'i': printf("Repeat at this interval: '%s'\n", optarg); interval = strtoul(optarg, (void *)0, 10); break; case 'q': printf("option q: supressing output.\n"); quiet = true; break; case '?': printf("option ?: There is not doc only source codes.\n"); break; default: printf("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { n_data = argc - optind; data_items = (char **)malloc(n_data * sizeof(char *)); printf("There are %i non-option ARGV-elements: ", (argc-optind)); size_t n = 0; while (optind < argc) { printf("%s ", argv[optind]); data_items[n] = argv[optind]; ++optind; ++n; } printf("\n"); } /* Get show on the road. */ modbus_t *ctx; ctx = modbus_new_tcp(host, port); if (modbus_connect(ctx) == -1) { fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); modbus_free(ctx); return -1; } for (size_t i = 0; i<n_times; i++) { switch (operation) { case read_bits: printf("READ BITS:\n"); rc = modbus_read_bits(ctx, base_addr, n_addrs, tab_bit); if (rc == -1) { fprintf(stderr, "%s\n", modbus_strerror(errno)); return(EXIT_FAILURE); } if (!quiet) { /* What did we read?*/ for (uint8_t *reg_ptr = tab_bit; reg_ptr < tab_bit + n_addrs; reg_ptr++) { printf("%i ", *reg_ptr); } printf("\n"); } break; case read_input_bits: printf("READ INPUT BITS:\n"); rc = modbus_read_input_bits(ctx, base_addr, n_addrs, tab_bit); if (rc == -1) { fprintf(stderr, "%s\n", modbus_strerror(errno)); return(EXIT_FAILURE); } if (!quiet) { /* What did we read?*/ for (uint8_t *reg_ptr = tab_bit; reg_ptr < tab_bit + n_addrs; reg_ptr++) { printf("%i ", *reg_ptr); } printf("\n"); } break; case read_registers: printf("READ REGISTERS:\n"); rc = modbus_read_registers(ctx, base_addr, n_addrs, tab_reg); if (rc == -1) { fprintf(stderr, "%s\n", modbus_strerror(errno)); return(EXIT_FAILURE); } if (!quiet) { /* What did we read?*/ for (uint16_t *reg_ptr = tab_reg; reg_ptr < tab_reg + n_addrs; reg_ptr++) { printf("%i ", *reg_ptr); } printf("\n"); } break; case read_input_registers: printf("READ INPUT REGISTERS\n\n"); rc = modbus_read_input_registers(ctx, base_addr, n_addrs, tab_reg); if (rc == -1) { fprintf(stderr, "%s\n", modbus_strerror(errno)); return(EXIT_FAILURE); } if (!quiet) { /* What did we read?*/ for (uint16_t *reg_ptr = tab_reg; reg_ptr < tab_reg + n_addrs; reg_ptr++) { printf("%i ", *reg_ptr); } printf("\n"); } break; case write_bit: printf("WRITE BIT\n"); n_addrs = 1; if (n_addrs > n_data) { fprintf(stderr, "Not enough data items on command line to write to requested address.\n"); return(EXIT_FAILURE); } for (uint8_t *reg_ptr = tab_bit; reg_ptr < tab_bit + n_addrs; reg_ptr++) { *reg_ptr = strtoul(*data_items++, (void *)0, 10); } rc = modbus_write_bit(ctx, base_addr, tab_bit); if (rc == -1) { fprintf(stderr, "%s\n", modbus_strerror(errno)); return(EXIT_FAILURE); } break; case write_register: printf("WRITE REGISTER\n"); // There is only one register. Almost everything else stays the same as write_registers. n_addrs = 1; if (n_addrs > n_data) { fprintf(stderr, "Not enough data items on command line to write to requested address.\n"); return(EXIT_FAILURE); } for (uint16_t *reg_ptr = tab_reg; reg_ptr < tab_reg + n_addrs; reg_ptr++) { *reg_ptr = strtoul(*data_items++, (void *)0, 10); } rc = modbus_write_register(ctx, base_addr, tab_reg); if (rc == -1) { fprintf(stderr, "%s\n", modbus_strerror(errno)); return(EXIT_FAILURE); } break; case write_bits: printf("WRITE BITS\n"); if (n_addrs > n_data) { fprintf(stderr, "Not enough data items on command line to write to requested addresses.\n"); return(EXIT_FAILURE); } for (uint8_t *reg_ptr = tab_bit; reg_ptr < tab_bit + n_addrs; reg_ptr++) { *reg_ptr = strtoul(*data_items++, (void *)0, 10); } rc = modbus_write_bits(ctx, base_addr, n_addrs, tab_bit); if (rc == -1) { fprintf(stderr, "%s\n", modbus_strerror(errno)); return(EXIT_FAILURE); } break; case write_registers: printf("WRITE REGISTERS\n"); if (n_addrs > n_data) { fprintf(stderr, "Not enough data items on command line to write to requested addresses.\n"); return(EXIT_FAILURE); } for (uint16_t *reg_ptr = tab_reg; reg_ptr < tab_reg + n_addrs; reg_ptr++) { *reg_ptr = strtoul(*data_items++, (void *)0, 10); } rc = modbus_write_registers(ctx, base_addr, n_addrs, tab_reg); if (rc == -1) { fprintf(stderr, "%s\n", modbus_strerror(errno)); return(EXIT_FAILURE); } break; default: break; } sleep(interval); } /* Free the memory */ free(tab_bit); free(tab_reg); //free(data_items); /* Close the connection */ modbus_close(ctx); modbus_free(ctx); exit(EXIT_SUCCESS); }
/* At each loop, the program works in the range ADDRESS_START to * ADDRESS_END then ADDRESS_START + 1 to ADDRESS_END and so on. */ int main(void) { modbus_t *ctx; int rc; int nb_fail; int nb_loop; int addr; int nb; uint8_t *tab_rq_bits; uint8_t *tab_rp_bits; uint16_t *tab_rq_registers; uint16_t *tab_rw_rq_registers; uint16_t *tab_rp_registers; /* RTU */ /* ctx = modbus_new_rtu("/dev/ttyUSB0", 19200, 'N', 8, 1); modbus_set_slave(ctx, SERVER_ID); */ /* TCP */ ctx = modbus_new_tcp("127.0.0.1", 1502); modbus_set_debug(ctx, TRUE); if (modbus_connect(ctx) == -1) { fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); modbus_free(ctx); return -1; } /* Allocate and initialize the different memory spaces */ nb = ADDRESS_END - ADDRESS_START; 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)); tab_rq_registers = (uint16_t *) malloc(nb * sizeof(uint16_t)); memset(tab_rq_registers, 0, nb * sizeof(uint16_t)); tab_rp_registers = (uint16_t *) malloc(nb * sizeof(uint16_t)); memset(tab_rp_registers, 0, nb * sizeof(uint16_t)); tab_rw_rq_registers = (uint16_t *) malloc(nb * sizeof(uint16_t)); memset(tab_rw_rq_registers, 0, nb * sizeof(uint16_t)); nb_loop = nb_fail = 0; while (nb_loop++ < LOOP) { for (addr = ADDRESS_START; addr <= ADDRESS_END; addr++) { int i; /* Random numbers (short) */ for (i=0; i<nb; i++) { tab_rq_registers[i] = (uint16_t) (65535.0*rand() / (RAND_MAX + 1.0)); tab_rw_rq_registers[i] = ~tab_rq_registers[i]; tab_rq_bits[i] = tab_rq_registers[i] % 2; } nb = ADDRESS_END - addr; /* 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++; } } /* MULTIPLE BITS */ rc = modbus_write_bits(ctx, addr, nb, tab_rq_bits); if (rc != nb) { printf("ERROR modbus_write_bits (%d)\n", rc); printf("Address = %d, nb = %d\n", addr, nb); nb_fail++; } else { rc = modbus_read_bits(ctx, addr, nb, tab_rp_bits); if (rc != nb) { printf("ERROR modbus_read_bits\n"); printf("Address = %d, nb = %d\n", addr, nb); nb_fail++; } else { for (i=0; i<nb; i++) { if (tab_rp_bits[i] != tab_rq_bits[i]) { printf("ERROR modbus_read_bits\n"); printf("Address = %d, value %d (0x%X) != %d (0x%X)\n", addr, tab_rq_bits[i], tab_rq_bits[i], tab_rp_bits[i], tab_rp_bits[i]); nb_fail++; } } } } /* SINGLE REGISTER */ rc = modbus_write_register(ctx, addr, tab_rq_registers[0]); if (rc != 1) { printf("ERROR modbus_write_register (%d)\n", rc); printf("Address = %d, value = %d (0x%X)\n", addr, tab_rq_registers[0], tab_rq_registers[0]); nb_fail++; } else { rc = modbus_read_registers(ctx, addr, 1, tab_rp_registers); if (rc != 1) { printf("ERROR modbus_read_registers single (%d)\n", rc); printf("Address = %d\n", addr); nb_fail++; } else { if (tab_rq_registers[0] != tab_rp_registers[0]) { printf("ERROR modbus_read_registers single\n"); printf("Address = %d, value = %d (0x%X) != %d (0x%X)\n", addr, tab_rq_registers[0], tab_rq_registers[0], tab_rp_registers[0], tab_rp_registers[0]); nb_fail++; } } } /* MULTIPLE REGISTERS */ rc = modbus_write_registers(ctx, addr, nb, tab_rq_registers); if (rc != nb) { printf("ERROR modbus_write_registers (%d)\n", rc); printf("Address = %d, nb = %d\n", addr, nb); nb_fail++; } else { rc = modbus_read_registers(ctx, addr, nb, tab_rp_registers); if (rc != nb) { printf("ERROR modbus_read_registers (%d)\n", rc); printf("Address = %d, nb = %d\n", addr, nb); nb_fail++; } else { for (i=0; i<nb; i++) { if (tab_rq_registers[i] != tab_rp_registers[i]) { printf("ERROR modbus_read_registers\n"); printf("Address = %d, value %d (0x%X) != %d (0x%X)\n", addr, tab_rq_registers[i], tab_rq_registers[i], tab_rp_registers[i], tab_rp_registers[i]); nb_fail++; } } } } /* R/W MULTIPLE REGISTERS */ rc = modbus_write_and_read_registers(ctx, addr, nb, tab_rw_rq_registers, addr, nb, tab_rp_registers); if (rc != nb) { printf("ERROR modbus_read_and_write_registers (%d)\n", rc); printf("Address = %d, nb = %d\n", addr, nb); nb_fail++; } else { for (i=0; i<nb; i++) { if (tab_rp_registers[i] != tab_rw_rq_registers[i]) { printf("ERROR modbus_read_and_write_registers READ\n"); printf("Address = %d, value %d (0x%X) != %d (0x%X)\n", addr, tab_rp_registers[i], tab_rw_rq_registers[i], tab_rp_registers[i], tab_rw_rq_registers[i]); nb_fail++; } } rc = modbus_read_registers(ctx, addr, nb, tab_rp_registers); if (rc != nb) { printf("ERROR modbus_read_registers (%d)\n", rc); printf("Address = %d, nb = %d\n", addr, nb); nb_fail++; } else { for (i=0; i<nb; i++) { if (tab_rw_rq_registers[i] != tab_rp_registers[i]) { printf("ERROR modbus_read_and_write_registers WRITE\n"); printf("Address = %d, value %d (0x%X) != %d (0x%X)\n", addr, tab_rw_rq_registers[i], tab_rw_rq_registers[i], tab_rp_registers[i], tab_rp_registers[i]); nb_fail++; } } } } } printf("Test: "); if (nb_fail) printf("%d FAILS\n", nb_fail); else printf("SUCCESS\n"); } /* Free the memory */ free(tab_rq_bits); free(tab_rp_bits); free(tab_rq_registers); free(tab_rp_registers); /* Close the connection */ modbus_close(ctx); modbus_free(ctx); return 0; }
int main(int argc, char **argv) { int c; int ok; int debug = 0; BackendParams *backend = 0; int slaveAddr = 1; int startAddr = 100; int startReferenceAt0 = 0; int readWriteNo = 1; int fType = FuncNone; int timeout_ms = 1000; int hasDevice = 0; int isWriteFunction = 0; enum WriteDataType { DataInt, Data8Array, Data16Array } wDataType = DataInt; union Data { int dataInt; uint8_t *data8; uint16_t *data16; } data; while (1) { int option_index = 0; static struct option long_options[] = { {DebugOpt, no_argument, 0, 0}, {0, 0, 0, 0} }; c = getopt_long(argc, argv, "a:b:d:c:m:r:s:t:p:o:0", long_options, &option_index); if (c == -1) { break; } switch (c) { case 0: if (0 == strcmp(long_options[option_index].name, DebugOpt)) { debug = 1; } break; case 'a': { slaveAddr = getInt(optarg, &ok); if (0 == ok) { printf("Slave address (%s) is not integer!\n\n", optarg); printUsage(argv[0]); exit(EXIT_FAILURE); } } break; case 'c': { readWriteNo = getInt(optarg, &ok); if (0 == ok) { printf("# elements to read/write (%s) is not integer!\n\n", optarg); printUsage(argv[0]); exit(EXIT_FAILURE); } } break; case 'm': if (0 == strcmp(optarg, TcpOptVal)) { backend = createTcpBackend((TcpBackend*)malloc(sizeof(TcpBackend))); } else if (0 == strcmp(optarg, RtuOptVal)) backend = createRtuBackend((RtuBackend*)malloc(sizeof(RtuBackend))); else { printf("Unrecognized connection type %s\n\n", optarg); printUsage(argv[0]); exit(EXIT_FAILURE); } break; case 'r': { startAddr = getInt(optarg, &ok); if (0 == ok) { printf("Start address (%s) is not integer!\n\n", optarg); printUsage(argv[0]); exit(EXIT_FAILURE); } } break; case 't': { fType = getInt(optarg, &ok); if (0 == ok) { printf("Function type (%s) is not integer!\n\n", optarg); printUsage(argv[0]); exit(EXIT_FAILURE); } } break; case 'o': { timeout_ms = getInt(optarg, &ok); if (0 == ok) { printf("Timeout (%s) is not integer!\n\n", optarg); printUsage(argv[0]); exit(EXIT_FAILURE); } printf("Timeout set to %d\r\n", timeout_ms); } break; case '0': startReferenceAt0 = 1; break; //tcp/rtu params case 'p': case 'b': case 'd': case 's': if (0 == backend) { printf("Connection type (-m switch) has to be set before its params are provided!\n"); printUsage(argv[0]); exit(EXIT_FAILURE); } else { if (0 == backend->setParam(backend, c, optarg)) { printUsage(argv[0]); exit(EXIT_FAILURE); } } break; case '?': break; default: printf("?? getopt returned character code 0%o ??\n", c); } } if (0 == backend) { printf("No connection type was specified!\n"); printUsage(argv[0]); exit(EXIT_FAILURE); } if (1 == startReferenceAt0) { startAddr--; } //choose write data type switch (fType) { case(ReadCoils): wDataType = Data8Array; break; case(ReadDiscreteInput): wDataType = DataInt; break; case(ReadHoldingRegisters): case(ReadInputRegisters): wDataType = Data16Array; break; case(WriteSingleCoil): case(WriteSingleRegister): wDataType = DataInt; isWriteFunction = 1; break; case(WriteMultipleCoils): wDataType = Data8Array; isWriteFunction = 1; break; case(WriteMultipleRegisters): wDataType = Data16Array; isWriteFunction = 1; break; default: printf("No correct function type chosen"); printUsage(argv[0]); exit(EXIT_FAILURE); } if (isWriteFunction) { int dataNo = argc - optind - 1; /*if (-1 != readWriteNo && dataNo != readWriteNo) { printf("Write count specified, not equal to data values count!"); printUsage(argv[0]); exit(EXIT_FAILURE); } else*/ readWriteNo = dataNo; } //allocate buffer for data switch (wDataType) { case (DataInt): //no need to alloc anything break; case (Data8Array): data.data8 = malloc(readWriteNo * sizeof(uint8_t)); break; case (Data16Array): data.data16 = malloc(readWriteNo * sizeof(uint16_t)); break; default: printf("Data alloc error!\n"); exit(EXIT_FAILURE); } int wDataIdx = 0; if (1 == debug && 1 == isWriteFunction) printf("Data to write: "); if (optind < argc) { while (optind < argc) { if (0 == hasDevice) { if (0 != backend) { if (Rtu == backend->type) { RtuBackend *rtuP = (RtuBackend*)backend; strcpy(rtuP->devName, argv[optind]); hasDevice = 1; } else if (Tcp == backend->type) { TcpBackend *tcpP = (TcpBackend*)backend; strcpy(tcpP->ip, argv[optind]); hasDevice = 1; } } } else {//setting write data buffer switch (wDataType) { case (DataInt): data.dataInt = getInt(argv[optind], 0); if (debug) printf("0x%x", data.dataInt); break; case (Data8Array): { data.data8[wDataIdx] = getInt(argv[optind], 0); if (debug) printf("0x%02x ", data.data8[wDataIdx]); } break; case (Data16Array): { data.data16[wDataIdx] = getInt(argv[optind], 0); if (debug) printf("0x%04x ", data.data16[wDataIdx]); } break; } wDataIdx++; } optind++; } } if (1 == debug && 1 == isWriteFunction) printf("\n"); //create modbus context, and preapare it modbus_t *ctx = backend->createCtxt(backend); modbus_set_debug(ctx, debug); modbus_set_slave(ctx, slaveAddr); //issue the request int ret = -1; if (modbus_connect(ctx) == -1) { fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); modbus_free(ctx); return -1; } else { switch (fType) { case(ReadCoils): ret = modbus_read_bits(ctx, startAddr, readWriteNo, data.data8); break; case(ReadDiscreteInput): printf("ReadDiscreteInput: not implemented yet!\n"); wDataType = DataInt; break; case(ReadHoldingRegisters): ret = modbus_read_registers(ctx, startAddr, readWriteNo, data.data16); break; case(ReadInputRegisters): ret = modbus_read_input_registers(ctx, startAddr, readWriteNo, data.data16); break; case(WriteSingleCoil): ret = modbus_write_bit(ctx, startAddr, data.dataInt); break; case(WriteSingleRegister): ret = modbus_write_register(ctx, startAddr, data.dataInt); break; case(WriteMultipleCoils): ret = modbus_write_bits(ctx, startAddr, readWriteNo, data.data8); break; case(WriteMultipleRegisters): ret = modbus_write_registers(ctx, startAddr, readWriteNo, data.data16); break; default: printf("No correct function type chosen"); printUsage(argv[0]); exit(EXIT_FAILURE); } } if (ret == readWriteNo) {//success if (isWriteFunction) printf("SUCCESS: written %d elements!\n", readWriteNo); else { printf("SUCCESS: read %d of elements:\n\tData: ", readWriteNo); int i = 0; if (DataInt == wDataType) { printf("0x%04x\n", data.dataInt); } else { const char Format8[] = "0x%02x "; const char Format16[] = "0x%04x "; const char *format = ((Data8Array == wDataType) ? Format8 : Format16); for (; i < readWriteNo; ++i) { printf(format, (Data8Array == wDataType) ? data.data8[i] : data.data16[i]); } printf("\n"); } } } else { printf("ERROR occured!\n"); modbus_strerror(errno); } //cleanup modbus_close(ctx); modbus_free(ctx); backend->del(backend); switch (wDataType) { case (DataInt): //nothing to be done break; case (Data8Array): free(data.data8); break; case (Data16Array): free(data.data16); break; } exit(EXIT_SUCCESS); }
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; }