modbuspp  1.1.40
C++ wrapper for the libmodbus library
server/clock-server-json/main.cpp
#include <ctime>
#include <csignal>
#include <thread>
#include <iostream>
#include <modbuspp.h>
#include <modbuspp/popl.h>
using namespace std;
using namespace Modbus;
const int SlaveAddress = 10;
Server srv; // instantiates new MODBUS Server
// -----------------------------------------------------------------------------
// Signal trap, triggers during a CTRL+C or if kill is called
void
sighandler (int sig) {
srv.close();
cout << "everything was closed." << endl << "Have a nice day !" << endl;
exit(EXIT_SUCCESS);
}
// -----------------------------------------------------------------------------
int main (int argc, char **argv) {
if (argc < 2) {
cerr << "Error: the JSON filename must be provided as a parameter on the command line !" << endl;
cerr << "e.g. : " << argv[0] << " clock-server-tcp.json" << endl;
exit (EXIT_FAILURE);
}
string jsonfile = argv[1];
time_t now, before;
tm * t;
// ModBus Data
bool daylight;// daylight saving time, true = summer time
Data<int32_t> gmtoff; // GMT offset, +/- minutes, Big endian order : ABCD
uint16_t mb_time[8]; // date and time
cout << "Modbus Time Server" << endl;
// CTRL+C and kill call triggers the trap sighandler()
signal (SIGINT, sighandler);
signal (SIGTERM, sighandler);
cout << "Press CTRL+C to stop... " << endl << endl;
try {
cout << "opening " << jsonfile << "..." << endl;
srv.setConfig (jsonfile, "modbuspp-server");
BufferedSlave & slv = srv.slave (SlaveAddress); // Adding a new slave to the server
cout << "Slave id: " << slv.number() << endl;
if (srv.debug()) {
cout << "Mapping of registers:" << endl
<< "--- Input Registers" << endl
<< "@ Reg. Size Description" << endl
<< "1 16-bit Seconds (0-60), unsigned" << endl
<< "2 16-bit Minutes (0-59), unsigned" << endl
<< "3 16-bit Hours (0-23), unsigned" << endl
<< "4 16-bit Day of the month (1-31), unsigned" << endl
<< "5 16-bit Month (1-12), unsigned" << endl
<< "6 16-bit Year e.g. 2019, unsigned" << endl
<< "7 16-bit Day of the week (0-6, Sunday = 0), unsigned" << endl
<< "8 16-bit Day in the year (1-366, 1 Jan = 1), unsigned" << endl
<< "--- Holding Registers" << endl
<< "@ Reg. Size Description" << endl
<< "1 32-bit number of seconds to add to UTC to get local time, signed" << endl
<< "--- Coils" << endl
<< "@ Reg. Size Description" << endl
<< "1 1-bit Daylight saving time" << endl << endl;
}
now = before = time (nullptr);
t = localtime (&now);
// init tz_offset and daylight saving time from from localtime
daylight = (t->tm_isdst > 0);
slv.writeCoil (1, daylight);
gmtoff = t->tm_gmtoff;
slv.writeRegister (1, gmtoff);
if (srv.open ()) { // open a connection
cout << "Listening server on " <<
srv.connection() << ":" << srv.settings() << "..." << endl << endl;
do {
now = time (nullptr);
if (now > before) {
before = now;
// update daylight saving time from holding register
slv.readCoil (1, daylight);
// update GMT offset from holding register
slv.readRegister (1, gmtoff);
// calculate the epoch time
now += (daylight ? 3600 : 0) + gmtoff;
t = gmtime (&now);
mb_time[0] = t->tm_sec;
mb_time[1] = t->tm_min;
mb_time[2] = t->tm_hour;
mb_time[3] = t->tm_mday;
mb_time[4] = t->tm_mon + 1;
mb_time[5] = t->tm_year + 1900;
mb_time[6] = t->tm_wday;
mb_time[7] = t->tm_yday + 1;
// update the input registers
slv.writeInputRegisters (1, mb_time, 8);
}
srv.poll (100);
}
while (srv.isOpen());
}
}
catch (std::exception & e) {
cerr << "Error: " << e.what() << endl;
}
catch (...) {
cerr << "Unattended exception !" << endl;
}
return EXIT_FAILURE;
}
/* ========================================================================== */