1.linux安装libmodbus库
git clone git://github.com/stephane/libmodbus
cd libmodbus
./autogen.sh
如果报错,安装
sudo apt-get install libtool
接着配置,在libmodbus文件夹里新建一个install文件夹用来存放编译生成的相关文件
mkdir install
cd install
./configure --prefix=/home/orangepi/lou/libmodbus/install //home/orangepi/lou/libmodbus/install为安装路径
make
make install
sudo cp -r lib/libmodbus.so* /usr/lib
2.部分示例代码
class PLCModbusTCP {
public:
PLCModbusTCP(const std::string& server_ip, int port);
~PLCModbusTCP();
bool connect();
void disconnect();
void start();
void stop();
void readRegisters();
bool writeRegisters(const std::vector<uint16_t>& values);
void floatToRegisters(float value,uint16_t* low, uint16_t* high);
//回调函数
....
private:
void readLoop();
void writeLoop();
ros::Subscriber heartbeat_Sub;
ros::Publisher heartbeat_Pub;
modbus_t *ctx_;
std::string server_ip_;
int port_;
bool running_;
std::thread read_thread_;
std::thread write_thread_;
std::mutex mtx_;
std::vector<uint16_t> write_values_;
int starting_address_;
int quantity_;
};
源文件部分代码示意:
void PLCModbusTCP::readRegisters() {
uint16_t tab_reg[10]; // Adjust the size according to your needs
int rc = modbus_read_registers(ctx_, 0, 10, tab_reg);
if (rc == -1) {
std::cerr << "Read failed: " << modbus_strerror(errno) << std::endl;
} else {
std::cout << "Registers read successfully:" << std::endl;
for (int i = 0; i < rc; ++i) {
std::cout << "Register " << i << ": " << tab_reg[i] << std::endl;
}
}
}
// Write values to the PLC
bool PLCModbusTCP::writeRegisters(const std::vector<uint16_t>& values) {
write_values_ = values;
if (!write_values_.empty())
{
return 1;
}
else
{
return 0;
}
}
主函数:
int main(int argc, char **argv) {
ros::init(argc, argv, "plc_modbus_node");
PLCModbusTCP plc_driver("192.168.1.5", 502); //
if (!plc_driver.connect()) {
return 1;
}
std::vector<uint16_t> values (20,0); //初始化写入数据数组
if (!plc_driver.writeRegisters(values)) {
ROS_ERROR("Failed to write registers to PLC.");
}
plc_driver.start(); //开始线程读取
// Example write operation
plc_driver.writeRegisters(values);
ros::Rate loop_rate(50);
while (ros::ok())
{
ros::spinOnce();
loop_rate.sleep();
}
std::cout<<"1"<<std::endl;
plc_driver.stop();
plc_driver.disconnect();
std::cout<<"2"<<std::endl;
return 0;
}
ROS运行结果: