Machsupport Forum

Third party software and hardware support forums. => Modbus => Topic started by: KMtronic on February 18, 2013, 11:05:58 AM

Title: My experiments with Mach3 ModBus and Arduino, Part I
Post by: KMtronic on February 18, 2013, 11:05:58 AM
Hi,

My project is add some external Inputs and Outputs to Mach3 using Arduino. For that last several days I read many posts about this.
I test Arduino ModBus library. Is very well documented, work but is too complicated for me in a moment. Zafarsalam too have good tutorial who I read carefully.
So I try share here step by step all my experiments when learn Mach3 ModBus and because don't know well Mach3 will thankful all who join and test.

PLEASE DON'T TEST USING MACH3 CONNECTED TO WORKING MACHINE!

Equipment:
1. Arduino board (I using Arduino Duemilanove but you can use any other Arduino board)
2. PC with Windows XP and Mach3 because software who I using for monitoring ModBus communication no support new versions Windows.
3. Software's
  - Arduino IDE
  - Mach3
  - Free Serial Port Monitor from http://www.serial-port-monitor.com (http://www.serial-port-monitor.com)


Part I: "Hello Word" or "Running Cycle Start button from Arduino Input pin".

(1) Mach3 ModBus settings


1. Connect Arduino to PC and upload any blank sketch or Blink Led example. My Arduino using COM5 so recommend change your to using the same COM Port.

2. Run Serial Port Monitor, go to New Session >> Serial Port Monitor >> Choose COM port(COM5), mark Request View and click "OK"
    Don't close Serial Port Monitor. Here you will see ModBus communication!

3. Run Mach3, go to Config, Ports&Pins and mark "ModBus InputOutput support".
   - Click OK and restart Mach3.
   - Go to Setup Serial ModBus control and set parameters exactly thereby:

(http://www.kmtronic.com/mach3/arduino_mach3_modbus_10.jpg)


Click Apply.

Now time for first checking break you to sure that all until now is correct.
 - Mach3 in ModBus status show 'Receive timeout'. In a moment this is normal. Arduino no programmed to receive command and reply.
 - Minimize Mach3 and go to Serial Port Monitor. Because default timeout settings is 500ms you will see that any half second Mach3 send to Arduino this request "01 04 00 00 00 01 31 CA". Don't try now understand what this mean in a moment. Will expand in next parts.
 - RX LED Arduino must blink too any half second.

(http://www.kmtronic.com/mach3/arduino_mach3_modbus_11.jpg)

If you don't see exactly this go back and try to find problem.
And don't continue until this step no work correctly! Any error bring no working project.

Now close Mach3 and Serial Port Monitor.


(2) Arduino programming

1. Upload this simple code who emulate ModBus slave to Arduino.
    Please use this code only for test because no have any safeguard!

Quote

int pin = 2;  //Cycle Start button
int in_buffer[8]; // receiving buffer
int reply_1[] ={0x01, 0x04, 0x02, 0x00, 0x01, 0x78, 0xF0};
int reply_0[] ={0x01, 0x04, 0x02, 0x00, 0x00, 0xB9, 0x30};

void setup()
{
  Serial.begin(9600);            // Init serial communication
  pinMode(pin, INPUT);           // Set pin to input
  digitalWrite(pin, HIGH);       // Turn on pullup resistor
}

void loop()
{
   if ( Serial.available() == 8 ) {
     
     // read ModBus command from Mach3
     // in this example we only read, don't check anything
     for (int i=0; i < 8; i++) in_buffer[ i ] = Serial.read();
     
     // Read Input PIN and reply with 0 or 1
     // Reply is inverted because PIN default state is HIGH and we connect to GND
     if ( digitalRead(2) == 0 )
         for (int i=0; i < 7; i++) Serial.write(reply_1[ i ]);
        else
         for (int i=0; i < 7; i++) Serial.write(reply_0[ i] );
 
   }   
}



Don't hurry to run Mach3. First try to understand what Arduino reply to Mach3 request.

Please download this ModBus test software:
http://www.kmtronic.com/software/ModBus/KMtronic_ModBus_Tester.zip

Run, set COM5, 9600, click Open, put this "01 04 00 00 00 01" command in text box and send to Arduino.
Next connect PIN2 Arduino to GND and click send again.

(http://www.kmtronic.com/mach3/arduino_mach3_modbus_12.jpg)

(http://www.kmtronic.com/mach3/arduino_mach3_modbus_14.jpg)

Now time to expand...
Please ignore last two bytes commands and replies. This is Check Sum and software calculate before send command for easy usage.

Command "01 04 00 00 00 01" is ModBus command who send Mach3 (check previous part).
You see in log that first reply when PIN2 is unconnected is:
1 - Rx: 01 04 02 00 00 
and
3 - Rx: 01 04 02 00 01
when PIN2 is connected to GND.

So Arduino now will reply 0 or 1 when Mach3 ask for status Input.

Again time for break if all is not the same.
Mach3 and Arduino must 'talk' together so if one of this two no work correctly no sense you to continue...


(3) Mach3 & Arduino

1. Close all programs
2. First run Serial Port Monitor >> Request View
3. Next run Mach3
If all is OK:
- Mach3 in "ModBus InputOutput support" will show 'No error'
- Arduino TX and RX LEDs will blink very fast.
- In Serial Port Monitor you will see a lot of Mach3 requests and Arduino replies.

(http://www.kmtronic.com/mach3/arduino_mach3_modbus_22.jpg)

Again break if all is not the same!


Time for last step - using brain tell Mach3 what command to execute when button is push down (PIN2 connected to GND).
 
(4) Create a brain who read ModBus and control Cycle Start button

1. Close again all programs.
2. Run Mach3 only and open Brain editor. Click on '+', go to ModBus and mark this:

(http://www.kmtronic.com/mach3/arduino_mach3_modbus_15.jpg)

Save file to Mach3\Brains in example 'Arduino_Test_01.brn'.
Now go to Brian control, click 'ReloadAll', enable it and next 'ViewBrain'.

Test that all until now work.
When you leave free PIN2 you will see Input blue. When connect to GND - green.

(http://www.kmtronic.com/mach3/arduino_mach3_modbus_19.jpg)
(http://www.kmtronic.com/mach3/arduino_mach3_modbus_20.jpg)

Brain now read Input!!!

This Input you can connect now to any function in Mach3. This example is how connect to Cycle Start button.

Go back to Brain editor, mark Input and using '+' add to Input:

(http://www.kmtronic.com/mach3/arduino_mach3_modbus_16.jpg)

Next mark again and go to Mach3 function '1000- CycleStart'

(http://www.kmtronic.com/mach3/arduino_mach3_modbus_17.jpg)

(http://www.kmtronic.com/mach3/arduino_mach3_modbus_21.jpg)

Save brain, re-load from Brian control, open any G-Code and try!

Hope this will be usefully Mach3 users understand how ModBus works .

Happy fun!


Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: Chaoticone on February 18, 2013, 11:28:36 AM
Thanks KM, I'm sure this will help many.  It's so nice of you to put this together and share it with us.  I'll be trying this soon.

Brett
Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: Tweakie.CNC on February 19, 2013, 02:47:11 AM
Hi KM,

An excellent, informative and well prepared article - thanks for posting.

Tweakie.
Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: laotou on February 20, 2013, 12:04:55 PM
Thanks KMtronic, It's useful for me.

Laotou.
Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: KMtronic on February 22, 2013, 05:51:32 AM
Hi again and thanks all for replies!

Yesterday I have free time and continue learning ModBus.

Here is next revision where I add some more Inputs and functions.
- 7 more Digital Inputs
- Calculating check sum function
- Error reply (but no sure that it work as much because Mach3 no show).

If I understand correctly Mach3 have 16 bytes registers from 0 to ...
I this code is used half of first register - MOD:0 but just support first 5 registers ( MOD:0 - MOD:4) and if need can add more Inputs.

(http://www.kmtronic.com/mach3/arduino_mach3_modbus_32.jpg)

Code no have comments and can be optimized, but work well:

Quote
unsigned int CRC16, SEED, GP; //for CRC16
#define SEED 0xFFFF  //initialization for CRC16
#define GP   0xA001  //generating polynomial
int in_buffer[8]; // receiving buffer

#define CycleStart 2;  //MOD:0-D0
#define FeedHold 3;  //MOD:0-D1
#define StopFile 4;  //MOD:0-D2
#define SingleStep 5;  //MOD:0-D3
#define ResumeFile 6;  //MOD:0-D4
#define ZeroX 7;  //MOD:0-D5
#define ZeroY 8;  //MOD:0-D6
#define ZeroZ 9;  //MOD:0-D7


void setup()
{
  Serial.begin(9600);            // Init serial communication
  pinMode(2, INPUT);           // Set pin to input
  pinMode(3, INPUT);           // Set pin to input
  pinMode(4, INPUT);           // Set pin to input
  pinMode(5, INPUT);           // Set pin to input
  pinMode(6, INPUT);           // Set pin to input
  pinMode(7, INPUT);           // Set pin to input
  pinMode(8, INPUT);           // Set pin to input
  pinMode(9, INPUT);           // Set pin to input
  digitalWrite(2, HIGH);       // Turn on pullup resistor
  digitalWrite(3, HIGH);       // Turn on pullup resistor
  digitalWrite(4, HIGH);       // Turn on pullup resistor
  digitalWrite(5, HIGH);       // Turn on pullup resistor
  digitalWrite(6, HIGH);       // Turn on pullup resistor
  digitalWrite(7, HIGH);       // Turn on pullup resistor
  digitalWrite(8, HIGH);       // Turn on pullup resistor
  digitalWrite(9, HIGH);       // Turn on pullup resistor
}

void loop()
{
   if ( Serial.available() == 8 ) {
     
     // read ModBus command from Mach3
     for (int i=0; i < 8; i++) in_buffer[ i ] = Serial.read();
     
     if ((in_buffer[0]== 0x01)&(in_buffer[1]== 0x04))
         Reply_Inputs();
         else
         Reply_Error();
         
     Serial.flush();
 
   }   
}

/// ----------------------- Functions -----------------------
void Reply_Inputs()
{
   CRC16 = SEED;
   int Inputs[] ={0x01, 0x04, 0x0A, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x00, 0x00};

   Inputs[4] = (
               ((!digitalRead( 9 ))<<7) |
               ((!digitalRead( 8 ))<<6) |
               ((!digitalRead( 7 ))<<5) |
               ((!digitalRead( 6 ))<<4) |
               ((!digitalRead( 5 ))<<3) |
               ((!digitalRead( 4 ))<<2) |
               ((!digitalRead( 3 ))<<1) |
               ((!digitalRead( 2 ))   ) );

   for (int i = 0; i < 13; i++)
        {   
        Calc_CRC(Inputs[ i ], &CRC16);
        }     
       
        Inputs[13]=CRC16 ;
        CRC16=CRC16>>8 ;
        Inputs[14]=CRC16 ;
   
   for (int i=0; i < 15; i++) Serial.write(Inputs[ i ]);
}
/// ---------------------------------------------------------
void Reply_Error()
{
   int Error[] ={0x01, 0x84, 0x00, 0x43, 0x00};
   for (int i=0; i < 5; i++) Serial.write(Error[ i ]);
}
/// ---------------------------------------------------------
void Calc_CRC(unsigned char b, unsigned int* CRC)
{
   int carry, i ;

   CRC[0] ^= b & 0xFF;
   for (i=0; i<8; i++)
   {
      carry = CRC[0] & 0x0001;
      CRC[0]>>=1;
      if (carry) CRC[0] ^= GP;
   }
}
/// ---------------------------------------------------------


Here is brain:

(http://www.kmtronic.com/mach3/arduino_mach3_modbus_30.jpg)

And settings:

(http://www.kmtronic.com/mach3/arduino_mach3_modbus_31.jpg)



I use first some buttons for test connected between PINs and GND.
 
Attachment contain Arduino code & ready brain.
You can modify buttons using "Terminate Lobe" function Brain Editor.

TODO: test ad add Analog Inputs using Zafarsalam tutorial.

Can someone know way how to configure ModBus Inputs to change screens? When button pressed in example Mach3 go to MDI?
I don't find such commands in Brain Editor.


Regards



Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: Chaoticone on February 22, 2013, 08:29:10 AM
The screens are Buttons 1-100.  The mdi page is button 2 or 3 I think.

Brett
Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: M2rt on January 08, 2014, 01:53:30 PM
Hi!
Thank you of this info. I'm building wireless remote controller for my router and this helped me to get started.

This remote controller what I'm building have, around 20 function buttons (under every button can save 2 functions), one analog joystick for X/Y jog, one potentiometer for feed override, small encoder for precise axis movement and 2x16 LCD screen for pos. info (bit to small).

First I tried to modify arduino code from this thread, but I wasn't able to increase the amount of modbus registers. Seemed to be some issue with arduino Serial.write.

Then I searched Arduino modbus library. I founded this library: SimpleModbusSlave http://code.google.com/p/simple-modbus/downloads/detail?name=SimpleModbusSlaveV8.zip&can=2&q=label%3AFeatured (http://code.google.com/p/simple-modbus/downloads/detail?name=SimpleModbusSlaveV8.zip&can=2&q=label%3AFeatured)

It works me very well so I like to share it!  :)

It only suports modbus holding registres, but its ok atleast for me. If you want to use it with Arduino Leonardo or Micro ( as I did) then you need to modify this library. Otherwise serial over USB does not work.

Here one sample how to use this:

Arduino code:
Code: [Select]
// Modbus:
#include <SimpleModbusSlave.h> //http://code.google.com/p/simple-modbus/
const int HOLDING_REGS_SIZE = 22; // I use 22 registers, first 11 for sendidng info to Mach3
//and next 11 registers for receiving info from Mach3
unsigned int holdingRegs[HOLDING_REGS_SIZE]; // function 3 and 16 register array

int rcd[11]; //holds sending info
int mcd[11]; //holds received info

void setup(){

  pinMode(13, OUTPUT); //indicator LED

  //modbus_configure(&Serial, 115200, SERIAL_8N2, 2, 13, HOLDING_REGS_SIZE, holdingRegs);
//2 is slave address, 13 is indicator led pin (useless)

  // with Arduino Micro I used modified library files and this line:
  //modbus_configure(115200, SERIAL_8N2, 2, 13, HOLDING_REGS_SIZE, holdingRegs);
}

void loop(){

  //Reads buttons:
  if(digitalRead(4) == 1) bitSet(rcd[0],0);
  else bitClear(rcd[0],0);

  if(digitalRead(5) == 1) bitSet(rcd[0],1);
  else bitClear(rcd[0],1);

  if(digitalRead(6) == 1) bitSet(rcd[0],2);   //can be up to 15
  else bitClear(rcd[0],2);

  //Potens´iometers:
  rcd[3] = analogRead(A0);
  rcd[4] = analogRead(A1);

  //Other variables:
  rcd[1] = 0x1111;
  rcd[2] = 0x2222;
  rcd[5] = 0x3333;
  rcd[6] = 32767;
  rcd[7] = 12345;
  rcd[8] = 54321;
  rcd[9] = 0;
  rcd[10] = 1;


  //Sending and receiving info:
  for (int i=0; i < 11; i++)
    holdingRegs[i] = rcd[i];

  modbus_update();

  for (int i=0; i < 11; i++)
    mcd[i] = holdingRegs[i+11];

  /* Writes cordinates to LCD:
   float Xpos = mcd[0]+(mcd[1]/100.00);
   float Ypos = mcd[2]+(mcd[3]/100.00);
   float Zpos = mcd[4]+(mcd[5]/100.00);
   
   lcd.setCursor(0, 0);
   lcd.print("                ");
   lcd.setCursor(0, 0);
   lcd.print("X");
   lcd.setCursor(0, 1);
   lcd.print(Xpos);
   lcd.setCursor(0, 8);
   lcd.print("Y");
   lcd.setCursor(0, 9);
   lcd.print(Ypos);
   lcd.setCursor(1, 0);
   lcd.print("        ");
   lcd.setCursor(1, 0);
   lcd.print("Z");
   lcd.setCursor(1, 1);
   lcd.print(Zpos);
   */
}

Mach3 settings and test images :
Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: M2rt on January 08, 2014, 02:26:14 PM
In case you want to use this library with Arduino Leonardo or Micro, you can use this library files.

Sorry abut my english.
Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: M2rt on January 08, 2014, 03:22:57 PM
Is there simple way to control machine axis with analog joystick in brain?  ???
Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: dreamon on March 26, 2014, 06:36:07 PM
Hi,

what is brain solution for jogs ? 
Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: ahmed01280 on March 07, 2015, 10:48:22 AM
i need to know how i can use arduino as interface  with mach3, i need complete code
Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: ahmed01280 on March 07, 2015, 10:50:32 AM
 i need to know else how can i use brain editor wih arduino
Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: M2rt on March 08, 2015, 10:34:10 AM
Hi
Here arduino code. I had two arduinos, on in remote and other connected to computer with mach3 and radio link between.
Some of the comments ar in estonian.
CNCpult_rc2.ino is remote control unit code, can be connected directly to computer usb.
Used two arduino micro's.

good luck!
Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: aluplastvz on April 10, 2015, 01:28:01 PM
how to increase the number of inputs
greeting
Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: TPS on April 12, 2015, 05:39:24 AM
how to increase the number of inputs

just use an other Arduino for example Mega2560 has 54 digital input/output pins .
Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: aluplastvz on April 12, 2015, 05:03:45 PM
if you have some code for arduino mega who might share
greeting
Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: TPS on April 13, 2015, 02:29:25 AM
Hi, aluplastvz

quote from the first post:
Equipment:
1. Arduino board (I using Arduino Duemilanove but you can use any other Arduino board)
2. PC with Windows XP and Mach3 because software who I using for monitoring ModBus communication no support new versions Windows.
3. Software's
  - Arduino IDE

i do not have any code, and i am not a Arduino guy.

Thomas
Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: TPS on July 31, 2015, 03:07:39 AM
Hi KMtronic,

used your example with a nano, worked fine, thank you.

but i had some issues with temporary coming up inputs.
i use no external pullup resistors, because of the internal ones.

your code:

 pinMode(2, INPUT);           // Set pin to input
 digitalWrite(2, HIGH);       // Turn on pullup resistor

should be:
 pinMode(2, INPUT_PULLUP);           // Set pin to input and turn on pullup resistor

for my understanding.
since i changed this all the problems are gone.

Thomas

 
Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: giantpt on October 26, 2015, 04:16:34 PM
Hi guys,

In the modbus configuration window, there is a limited number of Cfg# lines, something like 60 or so, is this the absolute maximum or is there a way to increase this number?

Thank you

Kind regards
Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: khalid on November 25, 2016, 02:09:53 AM
Alas all the images are not visible ...seems these are offline from the server..anyone having a pdf?
Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: Alexander Belov on January 08, 2018, 09:12:10 AM
(https://s8.hostingkartinok.com/uploads/images/2018/01/4841161c22dbd63885552ca85012d452.jpg) (https://hostingkartinok.com/show-image.php?id=4841161c22dbd63885552ca85012d452)

Hello, friends!
3 days I smoked the Internet. I ran Arduino uno + GRBL1.1 sketch + GRBL controller. Everything works, but I'm not satisfied with the level of control over the board.
I want to assemble the configuration via MODBUS. I tried to put different versions of the Modbus libraries. Configured Math3. Does not work.
I'm looking for a working Modbus library for receiving XYZ step / dir and sending button clicks in Math3.
I'm looking for a working configuration of Brain for pinout CNC Shield v3.0
Sorry for English, this is Google translator.

Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: florin2901 on March 10, 2019, 03:52:04 PM
Hi there,

Same here. But I make Mach3 to send Spindle Start/Stop through Arduino and CNC shield on pin 12.
I can't convince MACH3 to send pulses for step / dir for x, y and z, and receive info about Resume, Hold and Abort buttons from Arduino.
I don't know how to make / configure brains for these actions.
Can anyone help us with this?

Thank's in advance.
Title: Re: My experiments with Mach3 ModBus and Arduino, Part I
Post by: joeaverage on March 10, 2019, 04:21:17 PM
Hi,
Modbus is a serial communication protocol, there is no way it can send accurately timed Step/Direction pulses
they are way to fast.

Craig