Hello Guest it is April 28, 2024, 07:24:17 PM

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - tgirard

Pages: « 1 2 3 4 »
21
Mach4 General Discussion / Re: Arduino, Mach4 and ModbusIP.
« on: December 13, 2015, 12:02:22 PM »
It wouldn't let me post the pics the first time :)

22
Mach4 General Discussion / Arduino, Mach4 and ModbusIP.
« on: December 13, 2015, 11:58:13 AM »
I have a need to be able to do certain tasks with arduino and Modbus and have tried to put together a system. I can make a connection but I continually get a Illegal Data Address error when trying to poll for data in the holding registers.

Setup:
Arduino Unu R3
Arduino Ethernet2 board
Mach4
Ethernet2 library from arduino.org
Andre Sarmentos ModbuisIP Library https://github.com/andresarmento/modbus-arduino

Pic1 shows Mach4 with two Modbus setups, modbus0 is connected to the MODBUS Simulator
modbus1 is connected to the arduino through TCP 192.168.1.120
Note, modbus1 has no functions assigned, it's just connecting

Stay with me here...
Here is the arduino code that is simply checking 5 A-D floating inputs and sending that data across the Modbus in registers 40011 through 40015:
read the comments in the code:

/*
  Modbus-Arduino Example - TempSensor (Modbus IP)
  Copyright by AndrĂ© Sarmento Barbosa
  http://github.com/andresarmento/modbus-arduino
*/
 
#include <SPI.h>
#include <Ethernet2.h>
#include <Modbus.h>
#include <ModbusIP.h>

//Modbus Registers Offsets (0-9999)
const int reg1 = 40011; //Setup the holding register numbers to use
const int reg2 = 40012;
const int reg3 = 40013;
const int reg4 = 40014;
const int reg5 = 40015;
//Used Pins
const int sensorPin1 = A0; //setup the A-d
const int sensorPin2 = A1;
const int sensorPin3 = A2;
const int sensorPin4 = A3;
const int sensorPin5 = A4;

//Instanciate the ModbusIP object
ModbusIP mb;

long ts;

void setup() {
  Serial.begin(9600);
  // The media access control (ethernet hardware) address for the shield
    byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };  
    // The IP address for the shield
    byte ip[] = { 192, 168, 1, 120 };  
    //Config Modbus IP
    mb.config(mac, ip);

    mb.addHreg(reg1);//Create the registers based on the values above
    mb.addHreg(reg2);
    mb.addHreg(reg3);
    mb.addHreg(reg4);
    mb.addHreg(reg5);    
    ts = millis();
}

void loop() {
   //Call once inside loop() - all magic here
   mb.task();
  
   //Read each two seconds
   if (millis() > ts + 1000) {  
       ts = millis();
       //Setting raw value (0-1024)
       mb.Hreg(reg1, analogRead(sensorPin1));//Send the A-D values through Modbus
       mb.Hreg(reg2, analogRead(sensorPin2));
       mb.Hreg(reg3, analogRead(sensorPin3));
       mb.Hreg(reg4, analogRead(sensorPin4));
       mb.Hreg(reg5, analogRead(sensorPin5));      
       Serial.println(mb.Hreg(reg1));
 }
}//END


This code seems to work fine and when I run it and connect to it with a Modbus Master other than Mach4 I see the data
(I couldn't upload more than 4 pics but it ran fine)

I then create the function for modbus1 in Mach4 (pic3)

It is exactly the same as the other read function in modbus0(pic4) except I start at 40011 and only use 5 registers

The result (pic5) is modbus1 throws a Illegal Data Address error. This means that The data address received in the query is not an allowable address for the slave. More specifically, the combination of reference number and transfer length is invalid.
http://www.simplymodbus.ca/exceptions.htm

I've tried changing the starting number in Mach to 0 and to 2 with no luck. Any ideas?
I think this would be a really good thing to be able to do and would allow for easy and fast connectivity to the arduino.

I really don't want to use serial but I will if I have to.

Let me know if you have any ideas or if you have any questions
Thanks
-Tim







23
Mach4 General Discussion / Re: MACH4 - Modbus
« 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


24
Mach4 General Discussion / Re: MACH4 - Modbus
« 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
 

25
Mach4 General Discussion / Re: MACH4 - Modbus
« 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?

26
Mach4 General Discussion / Re: Mach4 Serial Port Support
« on: November 18, 2015, 07:11:28 PM »
Hey MadDog,
I was not able to make a connection by dropping in the luars232.dll. Have you had any luck?

27
WOW! that is very cool Andysims. I was just posting feature requests / bugs about the screen editer and that was one of them (Easier access to the images)

28
Some more issues
Tabbing through the Screen Tree Manager and properties
More control over color on objects (Like Groups)
Reference images in a folder rather than compile them (Easier to update / manage)
Better Font management / more options

29
Mach4 General Discussion / Re: Mach 4 Feature Request
« on: October 23, 2015, 07:57:58 PM »
Ability to programmatically read and adjust the height and width of the MACH4 window so that I can maintain aspect ratio when resizing. If there's already a way to do that, PLEASE let me know

30
Hopefully DazTheGas might have a solution here. I'm a little stumped trying to get a Serial connection to an arduino. At first  I thought that Lua would be the right way to go because there is already a luars232 package and connection is real easy (I verified this with my LuaForWindows installation on my machine).

When I tried to move that package into Mach, it doesn't work.

Should I just scrap that and dive into Modbus?

I need to be able to:
Read DRO values
Send and receive data from an external box (arduino)
Control the External box via buttons on Mach

Any documentation or help would be greatly appreciated. I'm finishing up our screens and this is the next big chunk

Pages: « 1 2 3 4 »