Hello Guest it is May 03, 2024, 03:48:04 PM

Author Topic: Coroutine question/problem  (Read 1292 times)

0 Members and 1 Guest are viewing this topic.

Coroutine question/problem
« on: September 15, 2021, 05:58:31 PM »
 i double posted this by accident (over in the General mach forum)

First, what I am attempting to do is create a button that raises the router to what I call "safeZ" - just to get it out of the way to work on my workpiece or whatever.

I created a coroutine so the DRO would show the progress.  Now, after the GCode move is complete, I'd liek to do some other stuff.  But, after the move is complete, nothing happens!  I've tried all sorts of commands down there and nothing happens.  One thing I was trying to add was to disable the machine after the move.  If I add that down there, it disables before the move!

What I mean by down there is after the else where it says back to work coordinates.

So, basically I am trying to complete a move and keep the DRO live, then do other things like display the error message and perhaps disable the machine.

One more thing I noticed....in the function, message boxes are executed, but not the mach functions like mc.CntlSetLastError.

Thanks for any help!

Tony





Code: [Select]
--10FE20

--This script is to test using a coroutine so that when a Gcode
--is sent, the DRO's are updated live and the completion message doesn't
--show up until the move is complete
--another post on Mach4 suggested checking to see if the machine is indeed in the
--correct location before displaying the finished message in case something happened
-- to prevent it from getting there - not sure how to do that yet.

local inst = mc.mcGetInstance()
local val
local rc
local homed

--Change to machine coords
local hsig = mc.mcSignalGetHandle(inst, mc.OSIG_MACHINE_CORD)
local sig = mc.mcSignalGetState(hsig)

if (sig == 0) then
mc.mcSignalSetState(hsig,1)
end


--check if Z is homed . if not - do nothing

homed , rc = mc.mcAxisIsHomed(inst,mc.Z_AXIS)

if homed == 1 then
SafeZ = coroutine.create(function()

mc.mcCntlGcodeExecute(inst, "G53 G1 Z-0.5 F25")
coroutine.yield()
val,rc = mc.mcAxisGetMachinePos(inst,mc.Z_AXIS)
    if val == -0.5000 then
--wx.wxMessageBox("Safe Z Finished")
mc.mcCntlSetLastError("Safe Z completed")
else
wx.wxMessageBox("Oops! - Didn't make it to -0.5'")
end
--wx.wxMessageBox("Safe Z Finished")
end)

else
wx.wxMessageBox("Move Cancelled - Z is not homed")
end

--back to work coords
mc.mcSignalSetState(hsig,0)
wx.wxMessageBox("Safe Z Finished")

Offline gorf23

*
  •  189 189
    • View Profile
Re: Coroutine question/problem
« Reply #1 on: September 15, 2021, 07:50:12 PM »
I'm not great at coroutine's but i think you need a coroutine.yield() to stop or exit the coroutine

Offline DazTheGas

*
  •  778 778
  • DazTheGas
    • View Profile
Re: Coroutine question/problem
« Reply #2 on: September 16, 2021, 03:13:53 AM »
Have you remembered to resume the coroutine within the PLC IE:

Code: [Select]
if (SafeZ ~= nil)  then
    local state = coroutine.status(SafeZ)
    if state == 'suspended' then
        coroutine.resume(SafeZ)
    end
end

perhaps this might help https://www.youtube.com/watch?v=t2xQYvAXT8o

DazTheGas
New For 2022 - Instagram: dazthegas
Re: Coroutine question/problem
« Reply #3 on: September 16, 2021, 12:02:10 PM »
Yessir.  Your the one that taught me how to get started with a coroutine!  Thanks! 

I did exactly what you did in the video.  The Gcode works, and I can get a message to display after that, but I can't seem to do anything beyond that.

I saw another post where the poster did something similar and called a function that was defined in the screen load script.  I may try that today. 

Thanks,

Tony
Re: Coroutine question/problem
« Reply #4 on: September 16, 2021, 12:07:18 PM »
I just checked my PLC code to make sure and I noticed it is a little different in that it checks machState.  Is that an issue?

Code: [Select]
--------------------------------
--SafeZ 10FE20
---------------------------------
if (SafeZ ~= nil) and (machState == 0) then --wait exist and state == idle
local state = coroutine.status(SafeZ)
    if state == "suspended" then --wait is suspended
        coroutine.resume(SafeZ)
    end
end

Offline gorf23

*
  •  189 189
    • View Profile
Re: Coroutine question/problem
« Reply #5 on: September 16, 2021, 02:18:50 PM »
i do something like this most likely not the best approach but it does run fine for me and gui doesn't lockup
but its just an example

Code: [Select]
-------------------------------------------------------
--  MyCoroutine  the part in a button script
-------------------------------------------------------

local inst = mc.mcGetInstance()

MyCoroutine = coroutine.create(function()
    mc.mcCntlGcodeExecute(inst, "G00 X2 F30")
    coroutine.yield()
    coroutine.resume(MyCoroutine)
    coroutine.yield()
    mc.mcCntlGcodeExecute(inst, "G00 Y2 F30")
    wx.wxMessageBox("Coroutine Finished "..coroutine.status(MyCoroutine))
end)
 
---------------------------------------------------
-- this go's in the Plc script
---------------------------------------------------
if (MyCoroutine ~= nil) and (machState == 0) then --MyCoroutine  exist and state == idle
local state = coroutine.status(MyCoroutine)
    if state == "suspended" then                  --MyCoroutine  is suspended
        coroutine.resume(MyCoroutine)
    end
end
Re: Coroutine question/problem
« Reply #6 on: September 16, 2021, 09:58:34 PM »
Thanks for the help.  I was getting really frustrated and about to just give up.  The routine did the positioning I needed, I just wanted to "make it pretty!"  I tried creating a function that resides in the screen load script and calling that function after the yield.  That worked.  Why?  I dunno.

I was really working on two scripts (in buttons). One to move to a safe Z position (Machine coord.  -0.5) and one that moves the router to the edge of the table where it it easy to swap bits.  After clicking, the scripts changes the display to Machine coords, checks to make sure the machine has been homed, moves the router into position, then changes back to work coords, and in the case of tool change, disables the machine.  The functions handle everything after the move. 

The button script for Safe Z...

Code: [Select]
--10FE20

--This script is to test using a coroutine so that when a Gcode
--is sent, the DRO's are updated live and the completion message doesn't
--show up until the move is complete
--another post on Mach4 suggested checking to see if the machine is indeed in the
--correct location before displaying the finished message in case something happened
-- to prevent it from getting there - not sure how to do that yet. 

local inst = mc.mcGetInstance()
local val
local rc
local homed

--Change to machine coords
local hsig = mc.mcSignalGetHandle(inst, mc.OSIG_MACHINE_CORD)
local sig = mc.mcSignalGetState(hsig)

if (sig == 0) then
mc.mcSignalSetState(hsig,1)
end


--check if Z is homed . if not - do nothing

homed , rc = mc.mcAxisIsHomed(inst,mc.Z_AXIS)

if homed == 1 then
SafeZ = coroutine.create(function()

mc.mcCntlGcodeExecute(inst, "G53 G1 Z-0.5 F25")
coroutine.yield()
val,rc = mc.mcAxisGetMachinePos(inst,mc.Z_AXIS)
    if val == -0.5000 then
--wx.wxMessageBox("Safe Z Finished")
readytogoZzero()
--mc.mcCntlSetLastError("Safe Z completed")
else
wx.wxMessageBox("Oops! - Didn't make it to -0.5'")
end
--wx.wxMessageBox("Safe Z Finished")
end)

else
wx.wxMessageBox("Move Cancelled - Z is not homed")
end


The function in the screen load script...

Code: [Select]
function readytogoZzero()
--wx.wxMessageBox("readytogo from function")
local hsigCORD = mc.mcSignalGetHandle(inst, mc.OSIG_MACHINE_CORD)
mc.mcSignalSetState(hsigCORD,0)-- go back to work coords
mc.mcCntlSetLastError(inst, "Safe Z reached...")
end


I use the message boxes for testing to let me know the script got to a certain spot.  Also, some of the notes are outdated.  I've ben using these buttons since last year, but I decided I wanted to spruce them up a bit (like disabling the machine after moving to bit swapping position).

I use the same idea for the tool change script but I check all three axes for homing and disable the machine once it gets moved. 

Thanks again for the help.  I still don't understand why this worked, but it does work well, so....

Tony

Offline jbuehn

*
  •  101 101
    • View Profile
Re: Coroutine question/problem
« Reply #7 on: September 16, 2021, 11:57:48 PM »
The mc.mcCntlSetLastError() that you commented out is missing the "inst" parameter. If the execution reached that point in your code it was probably throwing an error and not executing the rest of the script.
Re: Coroutine question/problem
« Reply #8 on: September 17, 2021, 09:49:05 AM »
Oops.  Thanks for catching that.   I had also left out an mc in front of a OSIG call but I caught that one.  I'll go back and try some more without the function to see if I cam make it work. 

Thanks for the help.

Tony
Re: Coroutine question/problem
« Reply #9 on: September 17, 2021, 11:06:17 PM »
Yes, that seems to be the whole problem.  I'd like to call it a typo, but it was really my ignorance.  I've used that call a bunch, but I just forgot and left it out.  I took everything from the function and put it back into the script after the yield and it seems to be working fine now. 

I got that all wrapped up and got back to the business of making sawdust with my machine today. 

Thanks again for the help.

Tony