Third party software and hardware support forums. > Modbus

My experiments with Mach3 ModBus and Arduino, Part I

(1/5) > >>

KMtronic:
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


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:




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.



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] );
 
   }   
}

--- End quote ---



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.





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.



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:



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.




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:



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





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!


Chaoticone:
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

Tweakie.CNC:
Hi KM,

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

Tweakie.

laotou:
Thanks KMtronic, It's useful for me.

Laotou.

KMtronic:
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.



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;
   }
}
/// ---------------------------------------------------------
--- End quote ---


Here is brain:



And settings:





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



Navigation

[0] Message Index

[#] Next page

Go to full version