Machsupport Forum

Mach Discussion => Mach4 General Discussion => Topic started by: tgirard on December 13, 2015, 11:58:13 AM

Title: Arduino, Mach4 and ModbusIP.
Post by: tgirard 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






Title: Re: Arduino, Mach4 and ModbusIP.
Post by: tgirard on December 13, 2015, 12:02:22 PM
It wouldn't let me post the pics the first time :)
Title: Re: Arduino, Mach4 and ModbusIP.
Post by: tgirard on December 13, 2015, 01:24:56 PM
I got it figured out for anyone whos interested.
When Setting up the registers on the arduino, You only specifiy the register position number like this:

//Modbus Registers Offsets (0-9999)
const int reg1 = 0;
const int reg2 = 1;
const int reg3 = 2;
const int reg4 = 3;
const int reg5 = 4;

That's because Andre adds 40001 in the Modbus Arduino library to this number to give your final number. The software is Base0 where Mach is Base1. So in Mach you use 1 through 5. I'm watching the arduino update some DROs on my screens without any problems. This is really cool as it allows me to do all kinds of really cool things and push the values to Mach. Feel free to ask if I didn't explain this well or if you want to see more :)
Title: Re: Arduino, Mach4 and ModbusIP.
Post by: tgirard on December 14, 2015, 10:22:10 AM
I made a video if anyone is interested
https://www.youtube.com/watch?v=B0w1lwUv5_o
Title: Re: Arduino, Mach4 and ModbusIP.
Post by: ksilovich on February 08, 2016, 09:52:52 PM
Tim,
I watched your video and have read in detail on how to set this all up.  I am trying to duplicate what you have done as a starting point for a project I am working on.  I have the same hardware and same settings but when I view the Modbus Diagnostics I am getting an "Illegal State error"  Any chance you know why this would be happening.   And did you have to config your Ethernet port on the PC at all?

Also did you have to modify the ModbusIP.h file to include Ethernet2.h instead of Ethernet.h
Title: Re: Arduino, Mach4 and ModbusIP.
Post by: tgirard on February 11, 2016, 10:00:41 AM
Hey Sorry for the delay in responding.
Yes, I did have to modify the Modbus.h to use ethernet2 instead of Ethernet.
Dang it, I can't remember what the Illegal  state error is but I bet you dollars to donuts it's  the setup count is incorrect between Mach and modbus (Base 1 for Mach and Base 0 for Modbus)
Title: Re: Arduino, Mach4 and ModbusIP.
Post by: sparky3 on April 08, 2016, 12:15:24 AM
I have been playing with this. Did you have to uncomment the #define TCP_KEEP_ALIVE in ModbusIP.h folder to keep it running?
Polling it did not work for me.

Thank you
R. Clark
Title: Re: Arduino, Mach4 and ModbusIP.
Post by: tgirard on April 09, 2016, 02:53:37 PM
Hi Sparkey3
Yes, I did have to uncomment the #define TCP_KEEP_ALIVE in ModbusIP.h

Thanks for posting that :)
Title: Re: Arduino, Mach4 and ModbusIP.
Post by: TadyTheFish on December 05, 2016, 12:38:04 AM
Hi
Nice work. I want to use your example for my own project. Can this code work with W5100 ethernet shield and libraty Ethernet(one) and mach3?
Thank you!
Title: Re: Arduino, Mach4 and ModbusIP.
Post by: arcadi1988 on March 31, 2017, 07:02:40 AM
Hi,

How do you know that the register "X_Axis_DRO" is really the position of the X axis?

Is there a Mach's registers manual?

Tnks
Title: Re: Arduino, Mach4 and ModbusIP.
Post by: iamarobot on May 13, 2018, 03:13:27 AM
Cool concept. Seems like something is either wrong with the arduino library or I don't know what I'm doing or something else. I'm not able to use 0, 8 or 16 as a reg value. I didn't go any further to check 24 but maybe...They just don't work. The Modbus plugin doesn't recognize the 8th "coil" input either. Neither does wireshark.

Code: [Select]
#include <ModbusIP_ENC28J60.h>

ModbusIP mb;
long ts;

int i = 0;
int regs[] = {1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17}; // values 0, 8 and 16 don't work for registers????
int pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 14, 15, 16, 17, 18, 19};

void setup() {
  for(i = 0; i < sizeof(pins)/sizeof(pins[0]); i++)
    pinMode(pins[i], INPUT);
   
  byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 
  byte ip[] = { 192, 168, 1, 210 }; 
  mb.config(mac, ip);

  for(i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
    mb.addCoil(regs[i]);  //create reg
   
  ts = millis();
}

void loop() {
  mb.task(); // MB comms
 
  if (millis() > ts + 200) { 
    ts = millis();
   
    for(i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
      mb.Coil(regs[i], digitalRead(pins[i]));  //update reg val
  }
}

(https://image.ibb.co/gTcgLd/Capture1.png)
(https://image.ibb.co/jLzHty/Capture2.png)
Title: Re: Arduino, Mach4 and ModbusIP.
Post by: Sergio007 on July 17, 2019, 12:14:19 AM
Hi Tim,

Thank you for sharing your progress on Arduino, Modbus, and Mach4. I am building a relatively gantry-type robot, for robotic welding. To achieve this, I need to define M codes (or any equivalent), to control multiple parameters of the welding machine from within the lines of G code. For instance, to increase arc voltage or wire feed speed, or accessing a memory slot in the welding machine, between lines of G code.

I wonder if you could help me understand how to define M codes to perform Modbus TCP communication. The relevant information from the welding machine manufacturer is here https://resources.userdoc.kemppi.com/manuals/a7-mig-welder-integration-om-en.pdf

At the moment, I understand that it is possible to configure the Modbus TCP protocol on Mach4. I just haven't figured out how to relate this to M codes.

Thank you in advance for any insights you may be able to share with me. Or publicly on the forum, that would be even better I guess.

Cheers

Sergio

Title: Re: Arduino, Mach4 and ModbusIP.
Post by: tgirard on July 17, 2019, 01:41:40 PM
To Everyone who has read this thread, I no longer work in the CNC field and now only Dabble a little bit with my machine at home. I haven't played with the Modbus stuff for years and so really have not kept up with how Mach4 works with Modbus. I hope that someone else who works in CNC more often can take the thread and help people or link another thread that would be more helpful.

I hope you find what you need somewhere here :)

-Tim
Title: Re: Arduino, Mach4 and ModbusIP.
Post by: compewter_numerical on July 29, 2019, 06:28:57 PM
Hi Tim,

Thank you for sharing your progress on Arduino, Modbus, and Mach4. I am building a relatively gantry-type robot, for robotic welding. To achieve this, I need to define M codes (or any equivalent), to control multiple parameters of the welding machine from within the lines of G code. For instance, to increase arc voltage or wire feed speed, or accessing a memory slot in the welding machine, between lines of G code.

I wonder if you could help me understand how to define M codes to perform Modbus TCP communication. The relevant information from the welding machine manufacturer is here https://resources.userdoc.kemppi.com/manuals/a7-mig-welder-integration-om-en.pdf

At the moment, I understand that it is possible to configure the Modbus TCP protocol on Mach4. I just haven't figured out how to relate this to M codes.

Thank you in advance for any insights you may be able to share with me. Or publicly on the forum, that would be even better I guess.

Cheers

Sergio

Once you map the Modbus IO in the Mach4 inputs/outputs mapping then you can just use the LUA scripting API to monitor or set the state of the IO. The third post down by ChaoticOne here: https://www.machsupport.com/forum/index.php?topic=27158.0 shows images on how to map the IO.

You can find documentation on the Mach4 LUA scripting located in the installation directory of Mach4 (Docs Folder Mach4CoreAPI.chm).