Hello Guest it is April 28, 2024, 06:27:34 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 - mcardoso

Pages: « 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 »
131
Mach4 General Discussion / ISIG/OSIG Master List
« on: October 14, 2019, 02:37:47 PM »
Is there a good reference for all of the ISIG and OSIG variables available within Mach? It is easy to find the I/O ones but a little less obvious for the system state variables.

133
I see what you're trying to do, but there is a better way.

Mach 4 offers the ability to respond to a change of state of a signal. This happens in the background and doesn't require a user script to be looping to check for it. It acts something like this: "If I see a change in state of a button, run this function".

So rather than looping, looking for your "OK to run" input, you can check the signal state before you start (perhaps as part of the cycle start button) and then just respond to a change in state.

Let's look at what this might look like in code. First off, we need to place the function call. I have done this in the Screen Load Script, but it can also be done in the Signals Script.
Code: [Select]
SigLib = {
    [mc.ISIG_INPUT5] = function (state)   --Change the input number
        SystemOKChange()                  --This is called if there is a change with the input state
    end
}

This code will call a function SystemOKChange() whenever INPUT5 (change this to what you need) changes state.

Next we need to create this function (put it at the end of your screen load script). The is called when the script changes state, but we don't yet know what the new state is. To get this, we need the handle (pointer to memory address of that input signal) and then query Mach 4 for the signal state

Code: [Select]
function SystemOKChange()
    local hSysOK
    local SysOK
   
    hSysOK, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT5)     --Change Input #
    SysOK, rc = mc.mcSignalGetState(hSysOK)
       
    if (SysOK == 0) then       --Invert this logic if needed here
        mc.mcCntlEStop(inst)  --Activate the EStop signal in Mach
        mc.mcCntlSetLastError(inst, "System OK Input Lost: ESTOP Active")   --Show a message in the Screen Set
    else
        mc.mcCntlSetLastError(inst, "System OK!")  --Show a message in the Screen Set
    end 
end

Now with this code, Mach isn't spending time in a loop looking for a change in your input. Because of this, all of your on-screen controls should continue to work fine. You can expand on that SigLib{} list to add additional inputs.

Finally, we don't want your Cycle Start Button to work if the input is OFF. To do this, we remove the property binding from the cycle start button to CycleStart() and add our own button pressed script.

Code: [Select]
local inst = mc.mcGetInstance()

    local hSysOK
    local SysOK
   
    hSysOK, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT5)     --Change Input #
    SysOK, rc = mc.mcSignalGetState(hSysOK)

    if (SysOK == 1) then       --Invert this logic if needed here
            mc.mcCntlCycleStart(inst)
    else
            mc.mcCntlSetLastError(inst, "Cannot Start, System OK Input is OFF")   --Show a message in the Screen Set
    end

134
Mach4 General Discussion / Re: Mach 4 Compatible Motion Controllers
« on: October 14, 2019, 09:42:41 AM »
+1 for the Warp9TD Ethernet SmoothStepper. Great product and great service from Andy!

Out of the box, Mach 4 runs beautifully, worth the price for sure.

For custom features, If you have done VBA scripting in Mach 3 you may find LUA a bit of a learning curve. After getting through it, it is apparent that Mach 4 is just built very intelligently and there really aren't any limitations on what you can do.

135
Mach4 General Discussion / Re: How to mark an axis as "Homed"
« on: October 09, 2019, 10:27:25 AM »
RT,

Thanks for the complement! I keep that as a log for my own enjoyment as much as sharing it with others. Just something fun to play with after work. Keeps me from going crazy working at a computer all day  ;D

Happy to share when I get stuff working!

Mike

136
Mach4 General Discussion / Re: How to mark an axis as "Homed"
« on: October 09, 2019, 09:37:52 AM »
Good news! I got it working! Thanks again to all who helped me out.

I ended up having to do a ton of test scripts to get an understanding of what exactly Mach 4 was doing with the code I was running.

Here are the key snippets I figured out to make this work (and I am sure they were discussed above already):
  • Mach 4 does not apply the changes made by calling mc.mcAxisSetHomeInPlace() until I later call mc.mcProfileSave()
  • There is some short period of time in which Mach 4 does not respond to the changes to the "Home in Place" command
  • This period of time is something greater than 10ms but less than or equal to 50ms

I figured this out by added 3 test buttons to the screen. One turned ON home in place, one ran the homing code, and one turned OFF home in place. If I clicked through these in sequence, the code worked great. If I put them together in a script, it didn't work at all. I was going to build a state machine, but figured I would try a raw delay first and that worked great (wx.wxMilliSleep()). This has yet to fail at 50ms, but if I set it to 10ms, some axes will home in place while others won't. I decided to play it safe and choose 100ms. There may be a cleaner way to do this, but execution time isn't important to me since it only runs one time at startup.

The code is executed while the axes are enabled. I can have the axes anywhere and they don't need to be moved. I get the current position of the motors from the drives which is tracked mechanically in the encoders while the machine is powered off. I throw this value into the homing offset then home in place. Finally the home offset and home in place values are returned to normal and the code ends. This still allows me to home to my switches like normal if I want. It is cool to see a tenth or two of movement when I disable and later re-enable. It is the closest thing to position feedback into Mach that I have.

Here is the code contained in the Ref All Home button:

Code: [Select]
--RefAllHome()
local e1 = 0

local HomeBox = wx.wxMessageBox("Do you wish to restore absolute position data from Servo Drives? \n \nChoose YES to restore homing data. \nChoose NO to Home to Limit Switches. \nChoose CANCEL to skip homing.", "Homing Type",18)
if HomeBox == 2 then
e1 = mcServo.AbsolutePositionRecovery()
if e1 ~= 0  then
wx.wxMessageBox("Home Position Recovery Failed! \n \n Axes must be referenced to switch before operation.", "Homing Failed",4)
else
wx.wxMessageBox("Home Position successfully read from Servo Drives", "Step 3/5 - Homing",4)
end
elseif HomeBox == 8 then
wait = coroutine.create (RefAllHome) --This is the code from the ref all home button
end


And the code for absolute homing using Allen Bradley Ultra 3000 servo drives, consuming data over RS485 Serial Host commands:

Code: [Select]
function mcServo.AbsolutePositionRecovery()

local rError = 0
local sError = 0
local xPosition = 0
local yPosition = 0
local zPosition = 0
local sPosition = 0

mc.mcAxisSetHomeInPlace(inst, 0, 1)
mc.mcAxisSetHomeInPlace(inst, 1, 1)
mc.mcAxisSetHomeInPlace(inst, 2, 1)
mc.mcAxisSetHomeInPlace(inst, 6, 1)
mc.mcProfileSave(inst)

wx.wxMilliSleep(100) --Sleep 100 milliseconds

local XctsInch = mc.mcMotorGetCountsPerUnit(inst, 0)
local YctsInch = mc.mcMotorGetCountsPerUnit(inst, 1)
local ZctsInch = mc.mcMotorGetCountsPerUnit(inst, 2)
local SctsInch = mc.mcMotorGetCountsPerUnit(inst, 6)
sError, xPosition = mcServo.GetPosition("00", XctsInch)
if sError ~= 0 then; rError = 1; return rError end
sError, yPosition = mcServo.GetPosition("01", YctsInch)
if sError ~= 0 then; rError = 1; return rError end
sError, zPosition = mcServo.GetPosition("02", ZctsInch)
if sError ~= 0 then; rError = 1; return rError end
sError, sPosition = mcServo.GetPosition("05", SctsInch)
if sError ~= 0 then; rError = 1; return rError end

mc.mcAxisSetHomeOffset(inst, 0, (xPosition*-1))
mc.mcAxisSetHomeOffset(inst, 1, (yPosition*-1))
mc.mcAxisSetHomeOffset(inst, 2, (zPosition*-1))
mc.mcAxisSetHomeOffset(inst, 6, (sPosition*-1))

mc.mcAxisHomeAll(inst)

wx.wxMilliSleep(100) --Sleep 100 milliseconds

mc.mcAxisSetHomeOffset(inst, 0, 0)
mc.mcAxisSetHomeOffset(inst, 1, 0)
mc.mcAxisSetHomeOffset(inst, 2, 0)
mc.mcAxisSetHomeOffset(inst, 6, 0)

mc.mcAxisSetHomeInPlace(inst, 0, 0)
mc.mcAxisSetHomeInPlace(inst, 1, 0)
mc.mcAxisSetHomeInPlace(inst, 2, 0)
mc.mcAxisSetHomeInPlace(inst, 6, 1) --Leave Spindle as Home in Place
mc.mcProfileSave(inst)

wx.wxMilliSleep(100) --Sleep 100 milliseconds

return rError

end

Thanks again to all!

137
Mach4 General Discussion / Re: How to mark an axis as "Homed"
« on: October 08, 2019, 03:06:27 PM »
Quote
Why use all of the profile stuff when you are doing nothing with the profile at all?

Probably because I don't yet know what I am doing  ;D

Quote
mc.mcCntlConfigStart(inst) puts the machine in the configuration state.  The idea is that you would then write things to the profile with mcProfile* functions.  Then call mc.mcCntlConfigStop(inst).  This is EXACTLY what we do with the control configuration dialog.

1. Enter the config state.
2. Read the profile's existing settings and display them in the dialog.
3. Allow the user to make changes.
4. If Ok or Apply is pressed, write the changes to the profile.  Then mc.mcProfileFlush(), which makes the changes stick.
5. Exit the config state.  This causes the control to re-read the profile and bring in the new settings.

Do you think this is the same process I would follow for changing the homing mode to "home in place"? Is the API call mc.mcAxisSetHomeInPlace() the correct one to do this or do I need to use a mcProfile command?

Quote
This is a very controlled process and can only be done with the control in the Idle state.  Not good for on-the-fly changes at run time.

This is ONLY going to be used when the machine is idle, either during a start-up script that prompts me to enable the control then home, or when the user presses the REF ALL HOME button.  Is there an easy way to check for idle? I've used the mc.mcCntlGetState() command but have never found a reference for what each state corresponds to the number returned from this call. I will add this as a condition for the homing to be allowed.

Based on the advice above, I'm thinking it might look something like this:

Code: [Select]
--change Mach 4 config for all axes to home in place, save & reload the profile
mc.mcCntlConfigStart(inst)
mc.mcAxisSetHomeInPlace(inst, 0, 1)
mc.mcAxisSetHomeInPlace(inst, 1, 1)
mc.mcAxisSetHomeInPlace(inst, 2, 1)
mc.mcAxisSetHomeInPlace(inst, 5, 1)
        mc.mcProfileFlush(inst)
mc.mcCntlConfigStop(inst)
(inst)

Would this immediately make the changes, or would I need to wait a full scan of the code for the changes to take effect?

Thanks again to everyone for the time and help. It is very appreciated.

138
Mach4 General Discussion / Re: How to mark an axis as "Homed"
« on: October 08, 2019, 12:52:31 PM »
I spent some time last night trying to get this to work and unfortunately didn't see any change in behavior from what I described before.

Here is my function. The goal is to home in place after having set a home offset equivalent to the drive current position. After homing, the DRO's should display the correct position, all the G54 offsets should be zero, and the LEDs should be illuminated showing the axes as homed. All without moving any axes.

The line "serialError, position = mcServo.GetPosition(address, ctsPerInch)" is a function I made as part of a custom library to communicate to my servos over serial. I'm 99.9% it is working correctly as it always returns the correct value for position (in unit of inches).

Code: [Select]
function mcServo.AbsolutePositionRecovery()
       
        --define local variables
local rError = 0
local sError = 0
local xPosition
local yPosition
local zPosition
local sPosition

        --change Mach 4 config for all axes to home in place, save & reload the profile
mc.mcCntlConfigStart(inst)
mc.mcAxisSetHomeInPlace(inst, 0, 1)
mc.mcAxisSetHomeInPlace(inst, 1, 1)
mc.mcAxisSetHomeInPlace(inst, 2, 1)
mc.mcAxisSetHomeInPlace(inst, 5, 1)
mc.mcCntlConfigStop(inst)
mc.mcProfileSave(inst)
mc.mcProfileReload(inst)

        --Gets the motor counts per inch for each axis
        --Then queries the servo drives for their position
        --Exits the function with an error code if any drive transmission failed
local XctsInch = mc.mcMotorGetCountsPerUnit(inst, 0)
local YctsInch = mc.mcMotorGetCountsPerUnit(inst, 1)
local ZctsInch = mc.mcMotorGetCountsPerUnit(inst, 2)
local SctsInch = mc.mcMotorGetCountsPerUnit(inst, 5)
sError, xPosition = mcServo.GetPosition("00", XctsInch)
if sError ~= 0 then; rError = 1; return rError end
sError, yPosition = mcServo.GetPosition("01", YctsInch)
if sError ~= 0 then; rError = 1; return rError end
sError, zPosition = mcServo.GetPosition("02", ZctsInch)
if sError ~= 0 then; rError = 1; return rError end
sError, sPosition = mcServo.GetPosition("05", SctsInch)
if sError ~= 0 then; rError = 1; return rError end

        --Sets the home offset equal to the position received from the drives
        --Need to multiply by -1 to invert the counts
        --Because the drive polarity on all these servos is inverted
mc.mcAxisSetHomeOffset(inst, 0, (xPosition*-1))
mc.mcAxisSetHomeOffset(inst, 1, (yPosition*-1))
mc.mcAxisSetHomeOffset(inst, 2, (zPosition*-1))
mc.mcAxisSetHomeOffset(inst, 5, (sPosition*-1))

        --Mach 4 API call to home axes (in-place)
mc.mcAxisHome(inst, 0)
mc.mcAxisHome(inst, 1)
mc.mcAxisHome(inst, 2)
mc.mcAxisHome(inst, 5)

--change Mach 4 config for all axes to home normally, save & reload the profile
        mc.mcCntlConfigStart(inst)
mc.mcAxisSetHomeInPlace(inst, 0, 0)
mc.mcAxisSetHomeInPlace(inst, 1, 0)
mc.mcAxisSetHomeInPlace(inst, 2, 0)
mc.mcAxisSetHomeInPlace(inst, 5, 0)
mc.mcCntlConfigStop(inst)
mc.mcProfileSave(inst)
mc.mcProfileReload(inst)

return rError
end

When I run this, the code still wants to bump all of the axes into their home switches. The home offset does seem to get set correctly.

After posting this to Warp 9, I was given a few ideas to try:

Quote
Hi Mike,

My guess is that your problem is that you are doing everything inside a single lua function, which has all of it calls made all in a single sequence.

However, I doubt that Mach4 is actually changing the profile and reloading it immediately when you call those functions, but rather queuing up the changes to be made after the screen scripts (or macros) finish running (the screen script is executed 40 or 50 times each second).

My guess is that if you broke your function into several separate function blocks that you called and waited for a moment before you called the next one, it would work like you wanted. If it did, then we would know that you would need to set up a state machine approach, for this operation. Assuming you have this in your screen script, the first pass through would make the changes to the conifg, and increment the state counter. The next time the screen script runs (1/40th or 1/50th of a second later, it would do the next chunk and increment the state counter. It would repeat this as many times as necessary, but it looks like your code would only need 3 times, or maybe 5 times if you had a do nothing pause step in between the real steps.


Let me know how it goes, but first try making 3 smaller functions that you call from the MDI and see if it works like you would expect it to.

I'm going to try that recommendation and see if it makes any difference.

I'm very much open to ideas or suggestions. Really would love to get this working. Understanding how Mach scans code and executes changes is a huge learning curve for me, but I think it is worth it.

139
Mach4 General Discussion / Re: How to mark an axis as "Homed"
« on: October 07, 2019, 12:28:50 PM »
From Andy at Warp9!

Quote
Hi,

The short answer is that the the SmoothStepper plugin never looks at the mcAxisSetHomeInPlace parameter. Mach4 looks at that parameter and then decides if it should do a home in place operation on that axis (motors) or tell the SmoothStepper to home that axis (motors) .

In order to set that parameter in Mach4 correctly, you need to do a couple other operations
rc = mc.mcCntlConfigStart(inst);
and
rc = mc.mcCntlConfigStop(inst); -- takes the machine out of the config state.
You may also need to do (but I don't think you will need to since you are only modifying a Mach parameter):
local hICU_Command = mc.mcRegGetHandle(inst, string.format("ESS/Force_Config_Update"))
mc.mcRegSetValueLong(hICU_Command, 1)

The second video walks you through the details...

Please understand that you are messing with your config file... you can destroy it if you are not careful! I would recommend backing up your entire c:\mach4Hobby folder before you do any of this.

Will try tonight and see if I can get it working.

140
Mach4 General Discussion / Re: How to mark an axis as "Homed"
« on: October 07, 2019, 09:49:54 AM »
Quote
I rather suspect that Mach4 is continuing in the existing homing mode, that you have changed mode has not yet taken effect.

If memory serves there is an API that causes Mach to re-read the .ini file, and then and only then does the change take effect.

Went digging through the API reference and couldn't find anything like you are describing (only a save to INI command). That's probably due to me not understanding how the INI works just yet!

Thanks for all the time and help you've given me. Really made a ton of progress yesterday with all of this.

Mike

Pages: « 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 »