Page 1 of 2

My M3, M4 and M5 macros for Modbus control

PostPosted: Sun Sep 25, 2016 6:06 pm
by A_Camera
I have a Bosch Rexroth EFC5610 VFD and I control this via Modbus. For anyone interested, I share my M3, M4 and M5 macros.

Each macro is sending appropriate commands via UCCNC Modbus interface to the inverter. UCCNC sends these commands to the VFD and reads back the status. The G-code execution is stopped until the appropriate action is finished, i.e. M3 command will result in waiting until the VFD reports back that the spindle speed is reached, likewise the M4. M5 command will result in waiting until the spindle is reported stopped by the VFD. This way there is no need to have a special delay in UCCNC, code execution can begin as soon as the speed is reached.

Code: Select all
//
// M3 macro
//
// This macro is to be used with Modbus control.
// Usable only with Bosch Rexroth EFC5610 or compatible VFD.
//
// Read screen object for spindle speed and convert the RPM to freqency.
// Set Modbus register 1 to the frequency value.
// Set Modbus register 0 to RUN CW command.
// Wait for the spindle to spin up before excit
//
string SpindleSpeedValue;   // SetSpindleSpeed screen object string
double SSpeedValue;       // SetSpindleSpeed screen object converted
ushort SFrequency;      // Spindle speed frequency to VFD

ushort RunSpindleCW = 129;    // Rexroth EFC5610 RUN CW command
ushort SpindleSpeedReached = 0; // Set to 1 when spindle speed is reached

SpindleSpeedValue = AS3.Getfield(869);         // Get the S-word from the display
SSpeedValue = Convert.ToDouble(SpindleSpeedValue);   // Concert string to double
SFrequency = (ushort) (SSpeedValue / 0.6);      // Frequency = Spindle S-word / 0.6
exec.SetModbusregister(1, SFrequency);         // This frequency will be sent to VFD

exec.SetModbusregister(3, 0);   // This register contains the "Speed arrival" flag
SpindleSpeedReached = 0;
exec.SetModbusregister(0, RunSpindleCW);
exec.DospinCW();
//
// Now wait for the spindle speed to reach the set RPM
//
while (SpindleSpeedReached == 0)
{
   exec.GetModbusregister(3, out SpindleSpeedReached);
}


Code: Select all
//
// M4 macro
//
// This macro is to be used with Modbus control.
// Usable only with Bosch Rexroth EFC5610 or compatible VFD.
//
// Read screen object for spindle speed and convert the RPM to freqency.
// Set Modbus register 1 to the frequency value.
// Set Modbus register 0 to RUN CW command.
// Wait for the spindle to spin up before exit
//
string SpindleSpeedValue;   // SetSpindleSpeed screen object string
double SSpeedValue;       // SetSpindleSpeed screen object converted
ushort SFrequency;      // Spindle speed frequency to VFD

ushort RunSpindleCCW = 133;    // Rexroth EFC5610 RUN CCW command
ushort SpindleSpeedReached = 0; // Set to 1 when spindle speed is reached

SpindleSpeedValue = AS3.Getfield(869);         // Get the S-word from the display
SSpeedValue = Convert.ToDouble(SpindleSpeedValue);   // Concert string to double
SFrequency = (ushort) (SSpeedValue / 0.6);      // Frequency = Spindle S-word / 0.6
exec.SetModbusregister(1, SFrequency);         // This frequency will be sent to VFD

exec.SetModbusregister(3, 0);   // This register contains the "Speed arrival" flag
SpindleSpeedReached = 0;
exec.SetModbusregister(0, RunSpindleCCW);
exec.DospinCCW();
//
// Now wait for the spindle speed to reach the set RPM
//
while (SpindleSpeedReached == 0)
{
   exec.GetModbusregister(3, out SpindleSpeedReached);
}


Code: Select all
//
// M5 macro
//
// This macro is to be used with Modbus control.
// Usable only with Bosch Rexroth EFC5610 or compatible VFD.
//
// This macro stops the spindle and waits for VFD to report back.
// Exit when the spindle is reported stopped by the VFD.
//
ushort StopSpindleRun = 136;   // Rexroth EFC5610 STOP command
ushort CommStateReg;      // Value of Communication State Register
ushort SpindleSpeedReached = 1; // Set to 0 when spindle speed is not reached or lost

exec.SetModbusregister(0, StopSpindleRun); // Send Rexroth EFC5610 STOP command to VFD

//
// First wait for the spindle speed to drop
//
while (SpindleSpeedReached == 1)   // Zero indicates spindle speed lost
{
   exec.GetModbusregister(3, out SpindleSpeedReached);
}
//
// Wait for the spindle speed to stop
//
exec.GetModbusregister(2, out CommStateReg);
while ((CommStateReg & 0x0002) == 1)   // Test bit 1 in Communication State Register
{
   exec.GetModbusregister(2, out CommStateReg);
}
exec.Stopspin();   // Execute UCCNC macro call


The above macros are tested with this G-code, which does nothing useful except some movement and spindle spinning. Please note, don't run this G-code with the spindle risking of touching any work. The rotation is reversed in the code and nasty things might happen. This code is just for testing the spindle rotation changes and the stop, not for milling.

Code: Select all
M3 S6123
G1 X120 F880
M5
M4 S12345
G1 X90 F880
M5
M3
G1 X80 F280
M5
M30
(end)


I don't know if anyone is interested in this, but will continue update this thread after changes. I think my macros can be used even for other VFD with some modification, but I can not test with anything else than my Bosch Rexroth EFC5610.

Re: My M3, M4 and M5 macros for Modbus control

PostPosted: Fri Sep 30, 2016 11:05 am
by Battwell
i saw your macros on uccnc forum. they make nice pointers.
i think monitoring the spindle running led in a macro loop may be a better way of starting the spindle (as its set by both m3 and a button press)- along with spindle relay output in an and configuration.
if neither forward or reverse is set to run- then send stop signal. (or monitoring spindle relay again.
sending speed command from a macro loop is probably better too- followed from on screen dro. as it will follow my spindle overide etc too.
i have the gt series inverter on my machine. and the spare to test this lot with at my development pc.
just need to sort out a 485 converter to start tests etc.
now ive played with uccnc modbus- it doesnt look as baffling!

Re: My M3, M4 and M5 macros for Modbus control

PostPosted: Fri Sep 30, 2016 11:53 am
by A_Camera
OK, so I copied my answer from CNCZONE... It would be good not to keep cross talking because it is a bit annoying to have to keep repeating things... :( It would be a good idea to keep UCCNC Modbus discussions here but this forum is pretty slow and some times you want to discus things outside a manufacturer's forum, so I think it is not possible to avoid discussing UCCNC even elsewhere. Never the less, If I am going to continue this subject it will be here, but I will only continue if I see interest from other users, otherwise this is my last post.

From CNCZONE: wrote:I think that there is a bug in UCCNC because according to me those buttons should call M3, M4 and M5. But yes, until that is fixed (if it is regarded as a bug by CNC Drive), the button states plus spindle override are necessary to monitor in a macro loop, which in turn should call M3, M4 and M5 to write in Modbus registers. It is not a good idea to have a macro loop as well as the M macros to write to those registers individually.

Yes, the way Modbus is handled in UCCNC is pretty simple for the users. I still need to test what happens if two connections are addressing the same device, because I want a separate, slow loop speed connection to get some monitoring parameters out of the VFD, like output voltage, current, power and so on. These are low priority information and should not be sent as often as the control parameters, so I hope that is possible. With Mach3 that was not a problem, hope that UCCNC can do that as well.

BTW, I have a USB stick I bought from eBay and got it delivered two days later from Germany when I started with Modbus, but I am waiting currently for an Ethernet version. Now with the UC300ETH it is better to leave USB all together because it gives me the possibility to not only control the CNC from two (or more) places in my home, but also the spindle.

Re: My M3, M4 and M5 macros for Modbus control

PostPosted: Fri Sep 30, 2016 2:00 pm
by ger21
What happens if you change the spindle speed between operations? I think you need the macroloop to monitor changes outside the M3-M4-M5 macros.

Re: My M3, M4 and M5 macros for Modbus control

PostPosted: Fri Sep 30, 2016 3:15 pm
by CNC22369
I am implementing a UCCNC modbus control interface for a Hitachi WJ200 VFD. At this point, the basic interface is working OK although I am still working on the M3, etc. macros and fine tuning things.

Thanks for the discussion on the manual spindle buttons not invoking the M3, etc. macros. I was going to write a macro to monitor the buttons and then invoke the M3 type macros, but I'm going to hold off to see when CNCDrive plans to fix the issue.

On setting the speed (frequency) of the VFD, I'm using a looping macro approach. The macro reads the max rpm field, the speed set field, and the speed override value and then performs a calculation to determine the frequency for the VFD. I check the result against the min & max values and cap it if needed (since the override can change speed up to 300%). When looping, this macro will change the VFD frequency if the running g-code changes the speed, when MDI is used to change the speed, or if the override is adjusted.

I like the idea of waiting for the spindle to reach speed before exiting the macro, but I haven't added this code yet. The macro does wait until the VFD has received a frequency change then it outputs the frequency & rpm to the status box and exits. I do not update the modbus register unless a speed change has occurred.

I encountered system exceptions when starting UCCNC with the macro in the autorun mode. The macro worked fine when it was manually started (looping). The exceptions seemed to be unexpected data types when reading the fields. Since the macro runs asynchronously to the UCCNC main code (per the manual), I'm guessing the exceptions were caused by the macro reading the fields before UCCNC had completed initialization. After some experimentation, I added an exec.Wait(100) to the beginning of the macro and the startup exceptions went away. I'm now using a Thread.Sleep(200) instead. Is there a way to monitor UCCNC to determine when it had completed startup/initialization and is ready for business?

Using windows task manager, I monitored UCCNC cpu usage with and without the macro running. To me, there was very little difference. One note though, as an experiment, I added a while loop at the beginning of the macro to monitor the UCCNC Reset button (if tripped, the speed code did not run). My implementation caused a big spike in cpu usage, so I immediately removed the while loop.

Frank

Re: My M3, M4 and M5 macros for Modbus control

PostPosted: Fri Sep 30, 2016 4:00 pm
by ger21
I encountered system exceptions when starting UCCNC with the macro in the autorun mode. The macro worked fine when it was manually started (looping). The exceptions seemed to be unexpected data types when reading the fields. Since the macro runs asynchronously to the UCCNC main code (per the manual), I'm guessing the exceptions were caused by the macro reading the fields before UCCNC had completed initialization. After some experimentation, I added an exec.Wait(100) to the beginning of the macro and the startup exceptions went away. I'm now using a Thread.Sleep(200) instead. Is there a way to monitor UCCNC to determine when it had completed startup/initialization and is ready for business?


Monitor the Reset LED, and don't do anything until the machine is out of Reset?

Re: My M3, M4 and M5 macros for Modbus control

PostPosted: Fri Sep 30, 2016 4:04 pm
by Battwell
maybe checking if charge pump is running at start of program would be better than a wait or sleep.?

in my machine i use the charge pump to a relay - which it holds on no problem - it brings servos out of emg mode. always on while uccnc is running

Re: My M3, M4 and M5 macros for Modbus control

PostPosted: Fri Sep 30, 2016 5:10 pm
by Robertspark
I did wonder about modbus spindle control, if the pc went off line crashed etc, how would the spindle stop?

Does the modbus loop sending spindle speed act as a sort of watchdog (chargepump)?

Re: My M3, M4 and M5 macros for Modbus control

PostPosted: Fri Sep 30, 2016 5:55 pm
by CNC22369
Thank you for the suggestions.

On using Reset, I did try something similar, but ultimately it didn't help so I removed it. I used an if statement at the beginning of the macro to check the state of Reset. If it was tripped, I skipped the rest of the macro code. But, I had a similar problem on UCCNC startup with the macro set for autorun. It seems like for a split second during startup, the macro received the wrong state (and the macro code ran at least once). After startup, testing Reset worked as it should -- no problems whatsoever. At this point, I changed the exec.Wait(100) to Thread.Sleep(200) and the macro (with the Reset check) worked perfectly on startup and otherwise.

On using charge pump good to determine if everything is ready, that gave me some ideas on using a signal coming from my custom BOB. But if my startup issue is due to the asynchronous nature of an autorun macro vs the UCCNC main code then there is always the possibility of misreading something on startup until things completely load and initialize. If this is the case, then I'm assuming there are many variables involved like CPU speed, system loading, etc. So, with these assumptions, I think a sure fire way to solve this is for UCCNC to hold off starting autorun macros until UCCNC is completely ready to go.

On stopping a spindle (VFD) controlled by modbus when a program crashes or hangs, I address this by using independent hardware on my custom BOB to trip (estop) the VFD and axis drivers. If the charge pump watchdog trips, a driver alarms, or if estop is pushed, the hardware with trip out everything. I think my VFD can be configured to auto stop the spindle if comm is lost, but I haven't investigated this option.

Frank

Re: My M3, M4 and M5 macros for Modbus control

PostPosted: Fri Sep 30, 2016 11:44 pm
by CNC22369
Since I have mentioned on this forum that I was implementing VFD modbus control including run/stop, I wanted to say that I have reconsidered this approach. I've read through some threads debating using modbus run/stop from a safety standpoint and have decided not use modbus for these operations. I'm going back to using a VFD run control signal that is controlled by UCCNC's spindle relay output. This is actually a simple thing to do and saves the effort to modify M3, etc. macros. I am continuing to use modbus to set speed and to monitor the VFD operational status.

Frank