Anyone know if/how to connect a Monitor One to a PLC. I am considering using these to access data on a Delta PLC, I can see the Console for accessing single data points but I need to access multiple for monitoring the system.
The Monitor One has simple built-in Modbus capabilities for use with the I/O card. If you need more features than that, you can modify the Monitor Edge software to do whatever you need from device firmware. You can do local processing of the data if desired, as well as add the data to location publishes, or other publishes, for any devices on the RS-485 bus.
I'm fine with doing it that way just hadn't seen any examples of it.
Would the modbus library be the way to do it then?
There aren't any examples of it but it should be fairly straightforward. Start with the Monitor Edge Firmware and the customization instructions.
The Modbus library isn't documented but it's easy to understand. The source is in lib/modbus and the calls in lib/modbus/src/ModbusClient.h are heavily commented.
Great I will give it a shot, thanks.
Any luck in getting this running locally and have a slab of code they're willing to share? I'm trying to run with the lib/modbus/src/ModbusClient.h. Right now, I'm having issues an immediate issue knowing where the response buffer is after a read. The readHoldingRegister function returns a status and "puts it in the response buffer", but there isn't a call in the library to access this buffer from what I could see.
Thus far, it looks like you define the baud, parity, stop bit in the serial init. The register and slave/client id gets put in the read/write call.
Code looks like the following, more or less,
ModbusClient wattnode1;
void setup()
{
Serial1.begin(19200,SERIAL_8N1);
wattnode1.begin(Serial1);
wattnode1.readHoldingRegisters()
Edge::instance().init();
}
void loop()
{
Edge::instance().loop();
uint8_t currentResult = wattnode1.readHoldingRegisters(1162, 2); // Register 1163,1164. 2 registers for current
if (currentResult == 0) { // Check if read was successful (0 means success)
//this would work in most libraries, not in this one, is there another function?
u_int16_t responseBuffer = (wattnode1.getResponseBuffer(1) << 16) | wattnode1.getResponseBuffer(0);
float Outlet1Current = responseBuffer;
Serial.println(Outlet1Current);
}
delay(5000)
}
Yeah I was able to get it working. Probably not the most efficient way or cleanest but it does the job for me.
It looks like you are missing some variables in your readHoldingRegisters. It should include a ModbusClientContext structure This is what that function is calling and the context is where the read value goes.
You can then use one of the wordsTo functions on the context and get the value as a single number
I had just stumbled upon that a short bit ago.
So creating a context object is necessary, which gets fed into the function.
ModbusClientContext context;
and after, the buffer can be parsed via the context.readBuffer portion.
Alright. That might be enough to work off of. Current issue are things timing out. Did you have to do any pre or post transmission callbacks to get things set up and receiving data properly?
Sorry this got lost in my notifications.
Yes you need to create the context because that is where the data will be stored. There was no pretransmission work but post transmission you do need to process the data to format it into the type of variable it should be as well as if there is any shifting of bits or masking or anything of the sort.