Hello Guest it is October 03, 2023, 05:02:59 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 - rhtuttle

491
Mach4 General Discussion / Lua Macro Parameters
« on: February 24, 2017, 12:10:04 PM »
The following code compiles and executes in the script editor.  After it executes the editor I get a message saying the editor has failed and is closed yet it is open.  hParam is always 'error' when run in the editor.  When I try to run in Mach4 mdi 'm6690 D.9' the last error line says 'Do MDI 1' and nothing happens.  What am I doing wrong and how do you track down/test this?

Code: [Select]
--Reel Seat Insert
--Turn from current Z down to 0 from current X down to parameter D or .850

function m6690(hParam)
  local xNow,zNow,maxVal
  local TS,TR,TT --timer values Mach3 niy
  local plungeFeed=6
  local roughDOC=0.015
  local roughFeed=15
  local roughSpeed=900
  local finishDOC=0.004
  local finishFeed=8
  local finishSpeed=1400
  local inst=mc.mcGetInstance()
  local endX=.850 --param1()
 
  local inst=mc.mcGetInstance()

  mc.mcCntlSetLastError(inst,'')

  if (hParam ~= nil) then
    local DFlag = mc.mcCntlGetLocalVarFlag(inst, hParam, mc.SV_D)
    if(DFlag == 1) then
      endX = mc.mcCntlGetLocalVar(inst, hParam, mc.SV_D)
    end
  end

  xNow = mc.mcAxisGetPos(inst,0)
  zNow = mc.mcAxisGetPos(inst,2)
  if xNow<=endX then
    wx.wxMessageBox("start X is less than end Diameter of "..tostring(endX))
    return
  end
  if zNow<=0 then
    wx.wxMessageBox("start Z is less than or = to 0")
    return
  end
  --ts=Timer
 
--rough cuts 
  mc.mcCntlGcodeExecuteWait(inst,"M3 S"..tostring(roughSpeed))
  while (mc.mcAxisGetPos(inst,0)>(endX+finishDOC*2)) do
    currPos=mc.mcAxisGetPos(inst,0)
    maxVal=math.max(endX+2*finishDOC,currPos)
    mc.mcCntlGcodeExecuteWait(inst,"G01 F"..tostring(plungeFeed).." X"..tostring(maxVal-roughDOC))
    if mc.mcSpindleGetSensorRPM(inst)==0 then
      wx.wxMessageBox("Spindle Stopped")
      return
    end
    mc.mcCntlGcodeExecuteWait(inst,"G01 F"..tostring(roughFeed).." Z0")
    if mc.mcSpindleGetSensorRPM(inst)==0 then
      wx.wxMessageBox("Spindle Stopped")
      return
    end
    currPos=mc.mcAxisGetPos(inst,0)
    maxVal=math.max(endX+2*finishDOC,currPos)
    if currPos==endX+2*finishDOC then
      break
    end
    mc.mcCntlGcodeExecuteWait(inst,"G01 F"..tostring(plungeFeed).." X"..tostring(math.max(endX+2*finishDOC,currPos-roughDOC)))
    if mc.mcSpindleGetSensorRPM(inst)==0 then
      wx.wxMessageBox("Spindle Stopped")
      return
    end
    mc.mcCntlGcodeExecuteWait(inst,"G01 F"..tostring(roughFeed).." Z"..tostring(zNow))
    if mc.mcSpindleGetSensorRPM(inst)==0 then
      wx.wxMessageBox("Spindle Stopped")
      return
    end 
    if currPos==endX+2*finishDOC then
      break
    end 
  end
  -- tr=Timer-ts
  --wx.wxMessageBox("Roughing Time: "..tostring(tr))

  --finish cuts
  mc.mcCntlGcodeExecuteWait(inst,"M3 S"..tostring(finishSpeed))

  while (mc.mcAxisGetPos(inst,0)>=(endX+finishDOC)) do
    currPos=mc.mcAxisGetPos(inst,0)
    mc.mcCntlGcodeExecuteWait(inst,"G01 F"..tostring(plungeFeed).." X"..tostring(currPos-finishDOC))
    if mc.mcSpindleGetSensorRPM(inst)==0 then
      wx.wxMessageBox("Spindle Stopped")
      return
    end
    mc.mcCntlGcodeExecuteWait(inst,"G01 F"..tostring(finishFeed).." Z0")
    if mc.mcSpindleGetSensorRPM(inst)==0 then
      wx.wxMessageBox("Spindle Stopped")
        return
    end
    currPos=mc.mcAxisGetPos(inst,0)
    if currPos==endX then
      break
    end 
    mc.mcCntlGcodeExecuteWait(inst,"G01 F"..tostring(plungeFeed).." X"..tostring(currPos-finishDOC))
    if mc.mcSpindleGetSensorRPM(inst)==0 then
      wx.wxMessageBox("Spindle Stopped")
      return
    end
    mc.mcCntlGcodeExecuteWait(inst,"G01 F"..tostring(finishFeed).." Z"..tostring(zNow))
    if mc.mcSpindleGetSensorRPM(inst)==0 then
      wx.wxMessageBox("Spindle Stopped")
      return
    end
    currPos=mc.mcAxisGetPos(inst,0)
    if currPos==endX then
      break
    end 
  end
  mc.mcCntlGcodeExecuteWait(inst,"M5\nM9")
--te=Timer-ts
--wx.wxMessageBox("Roughing Time: "..tostring(tr).." - Total Time: "..tostring(te))
end
 
if (mc.mcInEditor() == 1) then
    m6690()
end   

Thanks for any help,

RT

492
Mach4 General Discussion / Re: Simulate Probe Strike
« on: February 21, 2017, 10:50:23 AM »
Thanks Daz, I would have looked at that for 2 days before seeing that. 

493
Mach4 General Discussion / Simulate Probe Strike
« on: February 20, 2017, 03:48:47 PM »
I am converting my Mach3 lathe probe script to Mach4.  I want to simulate a probe strike as I rewrite this.

I have tried adding a button to the screen and writing scripts for the down and up key presses to change the state to on and off.  My code is:

local inst=mc.mcGetInstance()
local hSig=mc.mcSignalGetHandle(inst,ISIG_PROBE)
       mc.mcSignalSetState(hSig,1)


and

local inst=mc.mcGetInstance()
local hSig=mc.mcSignalGetHandle(inst,ISIG_PROBE)
       mc.mcSignalSetState(hSig,0)

What should I be doing since this doesn't work? 

TIA

RT

RT



494
Mach4 General Discussion / Re: Getting started with Mach 4
« on: February 17, 2017, 01:24:23 PM »
Also, at the top of the page for 'Mach4 General Discussion' there is a Videos button that contains only Mach4 related videos.  Daz does a great job of dumbing it down for novices, specialy with his quick tips videos

495
Mach4 General Discussion / Re: Getting started with Mach 4
« on: February 17, 2017, 01:20:23 PM »
I know that this can be daunting since I knew absolutly knothing about CNC, Bobs, drivers, etc. when I jumped in a few years ago.

With Mach4 each vendor is responsible for communicating with Mach4 and most have setup programs and profiles to make that easy.  I'm sure you've read the install manual for the 411 which has an installer as well.  Since they follow the old parallel port scheme you can plug into and wire the G540 using the same connections as you would using Mach3. The only major difference is referring to motors as Motor 0, Motor 1, Motor 2 rather than X,Y and Z.

I assume you have an appropriate power supply for the G540.  Wire it per the diagram on the gecko website.  The motor wiring will already be taken care of and you can do the limits and other wring after you get the motors turning.

Follow the instruction for installing the 411 and then fire up Mach4 and configure your motor steps per unit and acceleration.

I think that would be a good beginning. 

HTH

RT

496
Thought I would throw out an example of how to connect and utilize Mach4's Mach4IPC.dll  This dll contains all of the listed APIs.  This example only has a few of those listed.  Enough to demonstrate

This code would be used by any application:

Code: [Select]
unit Mach4DllWrapper;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes;

  //define each function that you might call
  type TmcIpcInit = function(ipAddr: pChar):integer;{$IFDEF WIN32} stdcall; {$ENDIF}
  type TmcGetInstance = function:integer;{$IFDEF WIN32} stdcall; {$ENDIF}
  type TmcIpcCleanup = function:integer;{$IFDEF WIN32} stdcall; {$ENDIF}
  type TmcRegGetValue =  function( hReg:integer;value:pdouble):integer ;{$IFDEF WIN32} stdcall; {$ENDIF}
  type TmcCntlLoadGcodeFile = function(mInst:integer;FileToLoad:pChar):integer;{$IFDEF WIN32} stdcall; {$ENDIF}
  Type TmcCntlCloseGCodeFile = function(mInst:integer):integer;{$IFDEF WIN32} stdcall; {$ENDIF}
  Type TmcCntlRewindFile = function(mInst:integer):integer;{$IFDEF WIN32} stdcall; {$ENDIF}
  type TmcCntlEStop = function( mInst:integer):integer;{$IFDEF WIN32} stdcall; {$ENDIF}
  Type TmcCntlEnable =function( mInst:integer;State:Boolean):integer;{$IFDEF WIN32} stdcall; {$ENDIF}
  type TmcCntlReset = function( mInst:integer):integer;{$IFDEF WIN32} stdcall; {$ENDIF}
  Type TmcAxisGetPos = function( mInst:integer; axisId:integer; val:pdouble):integer;{$IFDEF WIN32} stdcall; {$ENDIF}
  Type TmcAxisSetPos = function( mInst:integer; axisId:integer; val:pdouble):integer;{$IFDEF WIN32} stdcall; {$ENDIF}
  Type TmcCntlCycleStart = function(mInst:integer):integer;{$IFDEF WIN32} stdcall; {$ENDIF}
  Type TmcCntlCycleStop = function(mInst:integer):integer;{$IFDEF WIN32} stdcall; {$ENDIF}
  Type TmcCntlGcodeExecuteWait = function(mInst:integer;commands:pChar):integer;{$IFDEF WIN32} stdcall; {$ENDIF}
  Type TmcAxisHome = function( mInst:integer; axisId:integer):integer;{$IFDEF WIN32} stdcall; {$ENDIF}
  Type TmcAxisIsHomed = function( mInst:integer;axisId:integer;homed:pBoolean):integer;{$IFDEF WIN32} stdcall; {$ENDIF}

type TMach4Control=class(TObject)
  private
    fLoaded    : Boolean;
    fConnected : Boolean;
  public
    mcIpcInit          :TmcIpcInit;
    mcGetInstance      :TmcGetInstance;
    mcIpcCleanup       :TmcIpcCleanup;
    mcCntlEStop        :TmcCntlEStop;
    mcCntlEnable       :TmcCntlEnable;
    mcCntlReset        :TmcCntlReset;
    mcRegGetValue      :TmcRegGetValue;
    mcCntlLoadGcodeFile:TmcCntlLoadGcodeFile;
    mcCntlCloseGcodeFile:TmcCntlCloseGcodeFile;
    mcCntlRewindFile   :TmcCntlRewindFile;
    mcAxisGetPos       :TmcAxisGetPos;
    mcAxisSetPos       :TmcAxisSetPos;
    mcCntlCycleStart   :TmcCntlCycleStart;
    mcCntlCycleStop    :TmcCntlCycleStop;
    mcCntlGcodeExecuteWait:TmcCntlGcodeExecuteWait;
    mcAxisHome        :TmcAxisHome;
    mcAxisIsHomed     :TmcAxisIsHomed;

    Handle             :Thandle;
    mInst              :Integer;
    property Loaded    :Boolean read fLoaded write fLoaded;
    property Connected :Boolean read fConnected write fConnected;

    function init(dllLoc:pChar):Boolean;
    procedure doConnect(myIP:pChar);
    procedure cleanUp;
    constructor create;
end;

function ErrGetProcAddress(h:THandle;procName:pAnsiChar):FARPROC;

type handle = Integer;


implementation

function ErrGetProcAddress(h:THandle;procName:pAnsiChar):FARPROC;
begin
  result:=getProcAddress(h,procName);
  if not assigned(result) then
    raise exception.Create('DLL does not contain function: '+ProcName);
    // usually a typo in the function name if failed
end;

constructor TMach4Control.create;
begin
  inherited;
end;

function TMach4Control.init(dllLoc:pChar):Boolean;
begin
  //get the address of each function in the dll
  Handle := LoadLibrary(dllLoc);//'c:\Mach4Hobby\mach4IPC.dll');
  Loaded:= Handle <> 0 ;
  mcIpcInit:=ErrGetProcAddress(handle,'mcIpcInit');
  mcIpcCleanup:=ErrGetProcAddress(handle,'mcIpcCleanup');
  mcCntlEStop:=ErrGetProcAddress(handle,'mcCntlEStop');
  mcCntlEnable:=ErrGetProcAddress(handle,'mcCntlEnable');
  mcCntlReset:=ErrGetProcAddress(handle,'mcCntlReset');
  mcCntlLoadGcodeFile:=ErrGetProcAddress(handle,'mcCntlLoadGcodeFile');
  mcCntlCloseGcodeFile:=ErrGetProcAddress(handle,'mcCntlCloseGCodeFile');
  mcCntlRewindFile:=ErrGetProcAddress(handle,'mcCntlRewindFile');
  mcAxisGetPos:=ErrGetProcAddress(handle,'mcAxisGetPos');
  mcAxisSetPos:=ErrGetProcAddress(handle,'mcAxisSetPos');
  mcCntlCycleStart:=ErrGetProcAddress(handle,'mcCntlCycleStart');
  mcCntlCycleStop:=ErrGetProcAddress(handle,'mcCntlCycleStop');
  mcCntlGcodeExecuteWait:=ErrGetProcAddress(handle,'mcCntlGcodeExecuteWait');
  mcAxisHome:=ErrGetProcAddress(handle,'mcAxisHome');
  mcAxisIsHomed:=ErrGetProcAddress(handle,'mcAxisIsHomed');
end;

procedure TMach4Control.doConnect(myIP:pChar);
begin
  // connect to a running of Mach4
  if @mcIpcInit <> nil then
  begin
    mInst:=mcIpcInit(myIP);
    Connected:=(mInst=0);
  end;
end;

procedure TMach4Control.cleanUp;
begin
   if @mcIpcCleanup <> nil then
        mcIpcCleanup;
end;

end.


This code is for the application shown in the jpg

Code: [Select]
unit frmMach4AccessMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, JvExStdCtrls, JvEdit, JvValidateEdit, Mask,
  JvExMask, JvToolEdit, JvExControls, JvSpeedButton, TILed,
  MachLed, ExtCtrls,  Mach4DllWrapper;


type
  TForm1 = class(TForm)
    btnLoadFile: TButton;
    stat1: TStatusBar;
    btnEnable: TButton;
    btnCycleStart: TButton;
    btnCycleStop: TButton;
    btnRewind: TButton;
    btnCloseFile: TButton;
    btnMDIexecute: TButton;
    mmo1: TMemo;
    eGCodeFile: TJvFilenameEdit;
    pnl1: TPanel;
    lbl1: TLabel;
    eXdro: TJvValidateEdit;
    btnZeroXdro: TJvSpeedButton;
    btnXhome: TJvSpeedButton;
    MachLedxDro: tMachLed;
    MachLed2: tMachLed;
    pnl2: TPanel;
    lbl3: TLabel;
    btnZeroZdro: TJvSpeedButton;
    btnZhome: TJvSpeedButton;
    MachLedZdro: tMachLed;
    MachLed5: tMachLed;
    eZdro: TJvValidateEdit;
    procedure btnLoadFileClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure btnEnableClick(Sender: TObject);
    procedure btnCycleStartClick(Sender: TObject);
    procedure btnCycleStopClick(Sender: TObject);
    procedure btnCloseFileClick(Sender: TObject);
    procedure btnRewindClick(Sender: TObject);
    procedure btnMDIexecuteClick(Sender: TObject);
    procedure btnZeroXdroClick(Sender: TObject);
    procedure btnXhomeClick(Sender: TObject);
    procedure btnZhomeClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;


var
  Form1: TForm1;
  myIP: string = '127.0.0.1';
  dllLocation: string = 'c:\Mach4Hobby\mach4IPC.dll';
  mc:TMach4Control;

implementation

{$R *.dfm}


procedure TForm1.FormCreate(Sender: TObject);
var
  d:Double;
  homed:boolean;
begin
   mc:=TMach4Control.create;
   mc.init(pChar(DllLocation));      //load the dll and find the function locations
   if mc.Loaded then
   begin
     stat1.Panels[0].Text:='Loaded';  //Status: successfully Loaded
     btnLoadFile.Enabled:=mc.Loaded;  //determine whoter to enable or not
     btnEnable.Enabled:=mc.Loaded;    //determine whoter to enable or not
   end else
   begin
     stat1.Panels[0].Text:='Load Failure';
     exit;
   end;
   stat1.Panels[1].Text:='Connecting...';
   application.ProcessMessages;
  if mc=nil then
    exit;
  if mc.Connected then
    exit;
  mc.doConnect(pChar(myIP));    //connect to a running Mach4 instance
  if mc.Connected then
    stat1.Panels[1].Text:='Connected to Mach4'
  else
    stat1.Panels[1].Text:='Failed to Connect';
  application.ProcessMessages;
  mc.mcAxisGetPos(mc.mInst,0,@d);  //get the Xdro position-need to write a thread to update
  eXdro.Value:=d;
  mc.mcAxisGetPos(mc.mInst,2,@d);  //get the Zdro position-need to write a thread to update
  eZdro.Value:=d;
  mc.mcAxisIsHomed(mc.mInst,0,@homed);
  if homed then
    MachLedxDro.Color:=clGreen
  else
    MachLedxDro.Color:=clMaroon;
  mc.mcAxisIsHomed(mc.mInst,2,@homed);
  if homed then
    MachLedzDro.Color:=clGreen
  else
    MachLedzDro.Color:=clMaroon;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
//clean up before exiting
  if mc<>nil then
    mc.mcIpcCleanup;
  freeLibrary(mc.Handle);
end;

procedure TForm1.btnLoadFileClick(Sender: TObject);
var
  i:integer;
  s:string;
begin
  //load GCodeFile listed in edit control
    stat1.Panels[2].Text:='Loading GCode file';
    application.ProcessMessages;
    s:=eGcodeFile.FileName;
    i:=mc.mcCntlLoadGcodeFile(mc.mInst,pChar(eGcodeFile.filename));
    stat1.Panels[2].Text:='Return Code: '+intToStr(i);
end;

procedure TForm1.btnEnableClick(Sender: TObject);
begin
  //code to enable and disable Mach and update button state
  if  btnEnable.Caption='&Enable' then
  begin
    mc.mcCntlEnable(mc.mInst,True);
    btnEnable.Caption:='&Disable';
  end else
  begin
    mc.mcCntlEStop(mc.mInst);
    btnEnable.Caption:='&Enable';
  end;
  btnCycleStart.Enabled:=btnEnable.Caption<>'&Enable';
  btnCycleStop.Enabled:=btnEnable.Caption<>'&Enable';
end;

procedure TForm1.btnCycleStartClick(Sender: TObject);
begin
  mc.mcCntlCycleStart(mc.mInst);
  btnCycleStop.SetFocus;
end;

procedure TForm1.btnCycleStopClick(Sender: TObject);
begin
  mc.mcCntlCycleStop(mc.mInst);
end;

procedure TForm1.btnCloseFileClick(Sender: TObject);
begin
  mc.mcCntlCloseGcodeFile(mc.mInst);
  mc.mcCntlRewindFile(mc.mInst);//close file doesnt clear gcode window
end;

procedure TForm1.btnRewindClick(Sender: TObject);
begin
  mc.mcCntlRewindFile(mc.mInst);
end;

procedure TForm1.btnMDIexecuteClick(Sender: TObject);
begin
  //execute gcode in the momo component
  mc.mcCntlGcodeExecuteWait(mc.mInst,pChar(mmo1.Text));
end;

procedure TForm1.btnZeroXdroClick(Sender: TObject);
var
  d:double;
begin
  d:=0;
  mc.mcAxisSetPos(mc.mInst,0,@d);
end;

procedure TForm1.btnXhomeClick(Sender: TObject);
begin
  if mc.mcAxisHome(mc.mInst,0)=0 then
    MachLedxDro.color:=clGreen;
end;

procedure TForm1.btnZhomeClick(Sender: TObject);
begin
  if mc.mcAxisHome(mc.mInst,2)=0 then
    MachLedxDro.color:=clGreen;
end;

end.


Hope this saves someone some time.


RT


497
Mach4 General Discussion / Re: Change in Value Event
« on: February 16, 2017, 11:56:37 AM »
Thanks Daz,

That's a lot more elegant than what I came up with.  I haven't messed around with the PLC Script yet so it is good to see a simple example.

I use a pendant with no screen for jogging and have a button to change the increment.  I'm never looking at the screen when I do this so I
wanted to play a wav file to tell me what the new selection is.  I ended up creating wav files for each entry and added functions to the screen script as you did in your youtube sound example.  I then swapped out the Jog increment text box for a DRO since a DRO has a onChange event and put this code in:

if scr.GetProperty('JogIncrDro','Value') == "1.000000" then
  OneInch:Play()
elseif scr.GetProperty('JogIncrDro','Value')=="0.100000" then
  OneTenth:Play()
elseif scr.GetProperty('JogIncrDro','Value')=="0.010000" then
  OneHundredth:Play()
elseif scr.GetProperty('JogIncrDro','Value')=="0.001000" then
  OneThousandth:Play()
elseif scr.GetProperty('JogIncrDro','Value')=="0.000100" then
  OneTenThousandth:Play()
end

Putting it in the PLC would be quicker and cleaner. 

BTW, You need to come up with a website where we can donate some beer money for all your help  ;D

498
Mach4 General Discussion / Change in Value Event
« on: February 15, 2017, 11:55:46 AM »
How would you go about capturing a change in the current jog increment?

TIA

RT

499
Mach4 General Discussion / Re: Connecting to Mach4
« on: February 12, 2017, 08:15:48 PM »
steve,

What should mcIpcInit return for success and failure? Non zero and zero?

500
Mach4 General Discussion / Re: Connecting to Mach4
« on: February 12, 2017, 02:29:17 PM »
Spent a little time to see if I could create a DLL in Delphi that Mach4 could communicate with.

From the Delphi side:

Code: [Select]
library MyLuaTest;

uses
  SysUtils,lua,Classes;

{$R *.res}

  function Func1(L:pointer):integer; cdecl;
  begin
     lua_pushstring(L,pchar('test My open'));
     result:=1;
  end;

  function luaopen_MyLuaTest(L:pointer):integer; cdecl;
  begin
//    showMessage('open call');
    lua_register(L,'Func1',@func1);
    Result := 1;
  end;

Exports
 luaopen_MyLuaTest;

end.

from Mach4, Button left up script:

Code: [Select]
local inst = mc.mcGetInstance() -- Get the instance of Mach4

--wx.wxMessageBox("before require");

require("MyLuaTest","luaopen_MyLuaTest")
wx.wxMessageBox("before func1");

i=Func1(inst)

wx.wxMessageBox(i);

Can be done.