Hello Guest it is April 24, 2024, 09:11:33 AM

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

501
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



502
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

503
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

504
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


505
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

506
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

507
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?

508
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.

509
Mach4 General Discussion / Re: Connecting to Mach4
« on: February 12, 2017, 02:23:53 PM »
Steve, thanks for taking time to respond and for the two non-documented functions.  Delphi can run time link to dll's.  I have been unable to find the machAPI.h file.  I have searched the Mach4Hobby directory and it is not there.  Is this another one where you have to be a licensed developer to get it?

510
Mach4 General Discussion / Re: Connecting to Mach4
« on: February 12, 2017, 02:19:23 PM »
FocusPaul,

Thanks for the socket idea, I will look some more at lua sockets.