Hello Guest it is April 25, 2024, 07:58:36 AM

Author Topic: MACH4 - Modbus  (Read 80910 times)

0 Members and 1 Guest are viewing this topic.

Re: MACH4 - Modbus
« Reply #130 on: November 25, 2015, 02:43:39 PM »
How do you perform two way communication with the Holding Registers?
I have both the LUA Read and Write Functions that are specified in this thread (THANK YOU)

I start out with everyone at 0 (picture1)

When a value is placed in MACH  (I setup a Modbus write Function(0x6)) and send it (I use a button that calls the LUA Send Script defined in this thread) It goes over to the simulator (MODBUS_RSSIM) and I can see it in the Holding registers (Picture2)

I can also set a new value in the simulator and send it back to MACH which displays it just fine (I use the Modbus Read Function(0x3) and a DRO) (Picture3)

My problem is that I can no longer send the value back to the holding register because the writeRegisters (0x6) has the same value that I sent previously and will not resend.

What is the normal process for two way communication through Modbus?


Of course, trying to send through the read function(0x3) doesn't work.

What am I doing wrong here? Do I need to do some sort of Comparison script in LUA that updates the write Function to MATCH the Read Function?
Re: MACH4 - Modbus
« Reply #131 on: November 29, 2015, 02:27:25 PM »
So here's my hacky solution to my problem above...
function setModbusValue(aModbusInstance,aModbusID,aModbusValue)--This sets modbus data by passing the modbus instance (modbus0) and the register ID
    local rMbHndl = mc.mcRegGetHandle(inst, aModbusInstance .."/".. aModbusID); --Get the current Read Register Handle
    local wMbHndl = mc.mcRegGetHandle(inst, aModbusInstance .."/".. "w" .. aModbusID);  --Get the current Write Register Handle
    local rRegVal = mc.mcRegGetValue(rMbHndl); --Get the read Value
    local wRegVal = mc.mcRegGetValue(wMbHndl); --Get the write Value
    if rRegVal ~= wRegVal then --Sync the Write Register to the read register
    mc.mcRegSetValue(wMbHndl, tonumber(rRegVal));-- Sync the current value which DOES NOT trigger a send
    end

                   mc.mcRegSetValue(wMbHndl, tonumber(aModbusValue));--Send your new value which can also be the old value
end

You use the read register name as the input to the function and capture the write register in the function (see the comments)

The Catch here is that you have to preface all of your MACH write registers with a "w". This is cumbersome at best and leads to problems down the line.
What I should probably do is use the Write function as the input to the function and then remove the "w" from the front of the name and check for a read register element. I just got lazy from all the frustration
 
Re: MACH4 - Modbus
« Reply #132 on: November 29, 2015, 05:28:49 PM »
I changed the code so that it uses the Write Multiple Register Elements so that you don't have to have a corresponding read element
To use the LUA function below, place it in the Global Script. then, you need to place a single char (I use a "w") on the front of each element name for the MACH write function elements. So you create a series of Write Multiple Register 16bit (0x10) elements in Mach4 and each name is prefaced with a single letter (wWrite1, wWrite2 etc).

Then you simply call the function like so: setModbusValue("modbus0","wWrite1","<DATA>");

This will call the function which checks to see if you have a corresponding read element (Without the "w" at the beginning). If it finds a read element it simply changes the write element value to the current read element value -prior- to writing the actual value that you want

Let me know if you have any questions or, if you know of a way to do this without all this silliness...


function setModbusValue(aModbusInstance,aModbusID,aModbusValue)--This sets modbus data by passing the modbus instance (modbus0) and the register ID
    local rMbHndl = mc.mcRegGetHandle(inst, aModbusInstance .."/".. string.sub(aModbusID, 2)); --Get the current Read Register Handle (Removes the first Character from the name)
    local wMbHndl = mc.mcRegGetHandle(inst, aModbusInstance .."/".. aModbusID);  --Get the current Write Register Handle
    local rRegVal = mc.mcRegGetValue(rMbHndl); --Get the read Value
    local wRegVal = mc.mcRegGetValue(wMbHndl); --Get the write Value
    if rRegVal ~= wRegVal then --Sync the Write Register to the read register
        mc.mcRegSetValue(wMbHndl, tonumber(rRegVal));-- Sync the current value which DOES NOT trigger a Modbus send
    end

        mc.mcRegSetValue(wMbHndl, tonumber(aModbusValue));--Send your new value which can also be the old value
end

Re: MACH4 - Modbus
« Reply #133 on: October 28, 2018, 06:51:53 PM »
Hi Guys,

ive made a very easy setup tutorial for the MACH4 MODBUS and Spindle Control
watch the full post and tutorial here:
http://www.machsupport.com/forum/index.php/topic,38560.new.html#new

regards cncprint.blogspot  ;D