Ederen Barnworks

Neues aus der Bastelbude

Linuxcnc Retrofit von Igor Teil 9 – Fusion 360 Post processor

Im vergleich zu den Anpassungen am Postprozessor für die alte Sinumerik muss hier nur wenig geändert werden, da wir bereits einen sicheren Werkzeugwechsel haben. Aber ich wollte auch hier die Möglichkeit haben die Tischseite vorgeben zu können. Außerdem hatte ich den Effekt das bei hohen Vorschüben LinuxCNC dazu neigte den Vorschub über die Genauigkeit zu stellen, also wollte ich die zusätzlichen Toleranzen setzten daher habe ich drei Zeilen in den // user-defined properties ergänzt:

indexTable: 3, //Side of index table under Spindle 3 if no change
useG61orG64: true,// use G64 or G61 for tolerance control
G64tolerance: 0.005, //G64 Tolenace uses G61 if 0

Dann mussten das ganze noch umgesetzt werden. Dazu habe ich dann am Ende von function onOpen() noch den dazugehörigen Code ergänzt

//custom codes for Igor
 //index Table
 if(properties.indexTable == 1)
 {
 writeBlock(mFormat.format(31));
 }
 else if(properties.indexTable == 2)
 {
 writeBlock(mFormat.format(32));
 }
 //end index table
 //begin tolecrance control 
 if(properties.useG61orG64 == true)
  {if(properties.G64tolerance == 0)
   {
      writeBlock(gFormat.format(61)); // G61
   }
   else
   {
      writeBlock(gFormat.format(64), "P" + properties.G64tolerance ); // G64 PQ
   }}
//end tolerance control

Ein zweiter Punkt sind meine Werkzeugnummern. Ich verwende vierstellige Werkzeugnummern. Die erst Stelle steht für den Typ und die drei folgenden stellen sind der Durchmesser in 1/10” mm. Also ein Bohrer mit 10,5mm Durchmesser wäre 1105 verschieden die Wahrscheinlichkeit, dass ich zwei gleiche Werkzeuge mit unterschiedlichen Längen in einem Programm brauche sind im Hobbyeinsatz eher gering. Und 10-99 wären dafür noch frei:

NrTyp1.stelle2.Stelle3.Stelle4.Stelle
0Werkzeug in Spindel0000
001temporäre werkzeuge00TypTyp
01Probes01TypTyp
02Spindle02typtyp
03T-Slot0310er1er
04Scheibenfräser04druchmesser 10erDurchmesser 1er
05Prismenfräser05Winkel 10erWinkel 1er
1Drill11010,1
2Spotdrill2TypTypTyp
3Index31010,1
4Endmill41010,1
5Roughingendmill51010,1
6Bullnose6101Radius
7Ball endmill71010,1
8Formfräser8TypTypTyp

Der Standard-Post für LinuxCNC unterstützt keine 9999 Werkzeuge, daher mussten hier zwei Zeilen angepasst werden:

if (tool.number > 9999) {
warning(localize("Tool number exceeds maximum value."));
}

und

if (lengthOffset > 9999) {
error(localize("Length offset out of range."));
return;
}

Linuxcnc Retrofit von Igor Teil 8 Notaus und Komfort

Nach all der Arbeit, läuft Igor nun. Damit konnte man sich nun den “Kleinigkeiten” widmen. Wenn der Notaus ausgelöst wurde konnte die Spindel ab 2000 U/min nicht mehr gebremst werden, da zu früh die Stromversorgung zur Steuerung getrennt wurde. Deshalb habe ich das Ladder-Programm überarbeitet.
Zum einen habe ich es in drei unabhängige Stränge geteilt.
Der erst aktiviert die Steuerung.
Kommt von dieser das OK weird der Strohm zu den Motoren eingeschaltet. Außerdem gibt es hier jetzt einen Selbsterhalt, der beim deaktivieren der Steuerung durch den Notaus die Stromversorgung aufrecht erhält bis I3 den Stillstand der Spindel meldet.
Der dritte Strang dient zum Lösen der Z-Achs-Bremse, wenn die Steuerung betriebsbereit und die Motoren aktiv sind.

Bildschirmfoto 2020-08-22 um 10.45.38

kommen wir jetzt zum Komfort. Ich habe des öfteren vergessen den Kompressor aus zu schalten, deswegen habe ich ein Shelly Funkrelais in den Kompressor gebaut, das ich an Linuxcnc gekoppelt habe. So kann ich nicht mehr nacht vom Kompressor geweckt werden, weil ich vergessen habe ihn aus zu schalten. Außerdem kann ich den 2. Kanal des Shelly als Zeitrelais zum automatischen entwässern des Kessels verwenden. Möglich wurde das durch ein Pythonscript mit dem es möglich ist Hal pins zu erzeugen und so in Linuxcnc zu integrieren.

#!/usr/bin/python

import time
import hal
import urllib3
import atexit
import time


delta_t = 1 # seconds poll interval, hold inputs at least this long

#hal
h = hal.component("compressor")
h.newpin("active",hal.HAL_BIT,hal.HAL_IN)
h.ready()

def finaloff():
    r = http.request('GET', 'http://192.168.178.89/relay/1?turn=off')
    r = http.request('GET', 'http://192.168.178.89/relay/0?turn=on')
atexit.register(finaloff)
old_start_pin_value = False
started = False
http = urllib3.PoolManager()
while True:
    time.sleep(delta_t)
    #print h["active"]
    start_pin_value = h["active"]
    if start_pin_value != old_start_pin_value:
        #print("changed")
        if started:
            started = False
            print("compressor off")
            r = http.request('GET', 'http://192.168.178.89/relay/1?turn=off')
            r = http.request('GET', 'http://192.168.178.89/relay/0?turn=on')
        else:
            started = True
            print("compressor on")
            r = http.request('GET', 'http://192.168.178.89/relay/1?turn=on')
            r = http.request('GET', 'http://192.168.178.89/relay/0?turn=on')
    old_start_pin_value = start_pin_value

Dann habe ich ein weiteres Python script geschrieben mit dem ich die Maschinenstunden erfassen und Wartungsintervalle signalisieren kann.
Dazu läuft ein Timer wenn die Maschine in Eingeschaltet und betriebsbereit ist und wird gespeichert. Außerdem gehen gelbe Hinweislampen an, wenn das 50 Stunden oder 2000 Stunden Wartungsintervall erreicht ist.

Bildschirmfoto 2020-08-22 um 11.28.59
#!/usr/bin/python

import time
import hal
import atexit

fname = "timelog.txt"
sumlog = "time.txt"

delta_t = 1 # seconds poll interval, hold inputs at least this long
f = open(fname,mode="a+") # a: append or create if file doesnt exist
h = hal.component("timelog")
h.newpin("active",hal.HAL_BIT,hal.HAL_IN)
h.newpin("alarm",hal.HAL_BIT,hal.HAL_OUT)
h.newpin("alarm50",hal.HAL_BIT,hal.HAL_OUT)
h.newpin("alarm2000",hal.HAL_BIT,hal.HAL_OUT)
h.newpin("alarmon",hal.HAL_BIT,hal.HAL_OUT)
h.newpin("alarm50on",hal.HAL_BIT,hal.HAL_OUT)
h.newpin("alarm2000on",hal.HAL_BIT,hal.HAL_OUT)
h.newpin("seconds",hal.HAL_U32,hal.HAL_OUT)
h.newpin("minutes",hal.HAL_U32,hal.HAL_OUT)
h.newpin("hours",hal.HAL_U32,hal.HAL_OUT)
h.ready()



try:
        f2= open(sumlog,mode="r+")
        runtime=float(f2.readline())
        f2.close()
except:
        f2= open(sumlog,mode="w+")
        runtime=0.0
        f2.write(str(runtime))
        #f3.flush()
        f2.truncate()
        f2.close()


m, s = divmod(runtime, 60)
hr, m = divmod(m, 60)
#print(hr,m,s)
h["seconds"]=s
h["minutes"]=m
h["hours"]=hr
old_start_pin_value = False
t_start = time.time()
t_begin = time.time()
msg = ("Begin %s\n" % time.ctime())
f.write(msg)
f.flush()

#2000 hr check
if hr%2000==0:
        h["alarm2000"]=True
        #h["alarm2000on"]=True
        h["alarmon"]=True
        msg = ("2000 hour check %s\n" % time.ctime())
        f.write(msg)
        f.flush()
         
##50h check
if hr%50==0:
        h["alarm50"]=True
        #h["alarm50on"]=True
        h["alarmon"]=True
        msg = ("50 hour check %s\n" % time.ctime())
        f.write(msg)
        f.flush()
        
started = False
def finaloff():
    if h["active"]:
            started = False
            print("timer off")
            t_now = time.time()
            msg = ("Stop:  %s Elapsed: %f\n" % (time.ctime(),t_now - t_start))
            f.write(msg)
            f.flush()
            runtime=seconds
            savetime=str(seconds)
            print savetime
            f2= open(sumlog,mode="w+")
            f2.write(savetime)
            f2.truncate()
            f2.close()
    msg = ("End %s\n" % time.ctime())
    f.write(msg)
    f.flush()
        
atexit.register(finaloff)

while True:
    time.sleep(delta_t)
    #print h["active"]
    start_pin_value = h["active"]
    if start_pin_value != old_start_pin_value:
        print("changed")
        if started:
            started = False
            print("timer off")
            t_now = time.time()
            msg = ("Stop:  %s Elapsed: %f\n" % (time.ctime(),t_now - t_start))
            f.write(msg)
            f.flush()
            runtime=seconds
            savetime=str(seconds)
            print savetime
            f2= open(sumlog,mode="w+")
            f2.write(savetime)
            #f3.flush()
            f2.truncate()
            f2.close()
        else:
            started = True
            print("timer on")
            msg = ("Start: %s\n" %time.ctime())
            f.write(msg)
            f.flush()
            t_start = time.time()
            f2= open(sumlog,"r")
            runtime=float(f2.readline())
            f2.close()
            print runtime

    if start_pin_value: 
        seconds= runtime+(time.time() - t_start)
        m, s = divmod(seconds, 60)
        hr, m = divmod(m, 60)
        h["seconds"]=s
        h["minutes"]=m
        h["hours"]=hr
    old_start_pin_value = start_pin_value

Da ich inzwischen die Standard-RT kerne verwende gingen meine Latenzen in letzter zeit hoch, doch ich wollte eigentlich nicht wieder einen custom Kernel installieren. Es gibt aber die Boot option Einzelne Kerne für die Echtzeitanwendungen zu reservieren, das hat die Latenzen massiv verbessert, ich reservier die Kerne 2 und 3. Dazu muss in der Datei  /etc/default/grub folgende Zeile angepasst werden:

GRUB_CMDLINE_LINUX_DEFAULT="quiet text isolcpus=2,3"

danach noch grub updaten:

sudo update-grub

Zum vergleich vorher:

last latency data is as follows:.
10 secs base min: -78.600 uS max: 71.900 uS sdev: 2.900 uS
10 secs servo min: -97.600 uS max: 101.800 uS sdev: 4.000 uS


Nachher:

last latency data is as follows:
724 secs base min: -34.800 uS max: 34.600 uS sdev: 0.900 uS
724 secs servo min: -22.400 uS max: 22.700 uS sdev: 1.600 uS


Linuxcnc Retrofit von Igor Teil 7 Handrad

Immer öfter kam bei mir der Wunsch auf die Maschine auch per Handrad bewegen zu könne, was der Antasten und Auch das setzten der Nullpunkte erleichtern soll, Ich habe mich für ein Kabelloses XHC-WHB04B-6 entschieden:

Danach ging es an die Installation. Zunächst mussten dazu die sourcen von Linuxcnc gezogen werden:

cd ~
git clone https://github.com/LinuxCNC/linuxcnc dev-linuxcnc
cd dev-linuxcnc/src/

danach im Makefile unter subdirs die Zeile “hal/user_comps/xhc-whb04b-6 \” hinzufügen

./autogen.sh
./configure --with-realtime=uspace
make
sudo make setuid
sudo cp ../bin/xhc-whb04b-6 /usr/bin/

Damit sind die Treiber übersetzt, jetzt müssen noch die Udev Regel erstellt werden. Dazu brauchen wir die Informationen vom USB Dongel

lsusb
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 007: ID 8087:0a2a Intel Corp. 
Bus 001 Device 006: ID 0bda:0153 Realtek Semiconductor Corp. 3-in-1 (SD/SDHC/SDXC) Card Reader
Bus 001 Device 005: ID 1c4f:0016 SiGma Micro 
Bus 001 Device 004: ID 2575:0401  
Bus 001 Device 003: ID 046d:c408 Logitech, Inc. Marble Mouse (4-button)
Bus 001 Device 002: ID 10ce:eb93 Silicon Labs 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Der SIlicon Labs Chip ist der, den wir suchen (10ce:eb93 / VendirID:ProductID) wir jetzt legen wir die Udevregel an:

mcedit /etc/udev/rules.d/99-xhc-whb04b-6.rules
und dort tragen wir folgende Zeile ein:
ATTR{idProduct}==”eb93″, ATTR{idVendor}==”10ce”, MODE=”0666″, OWNER=”root”, GROUP=”plugdev”

Dann Udev neu laden:
sudo udevadm trigger
xhc-whb04b-6

Wenn man jetzt das Handrad bewegt oder eine taste drückt sollte es fleißig Daten regnen.

jetzt muss da ganze noch mit Linuxcnc verheiratet werden. Ich habe dafür eine eigene Haldatei gewählt:

loadusr -W xhc-whb04b-6 -H

loadrt ilowpass names=ilowpass.jog.x,ilowpass.jog.y,ilowpass.jog.z,ilowpass.jog.a
addf   ilowpass.jog.x   servo-thread
addf   ilowpass.jog.y   servo-thread
addf   ilowpass.jog.z   servo-thread
addf   ilowpass.jog.a   servo-thread
setp   ilowpass.jog.x.scale 100
setp   ilowpass.jog.y.scale 100
setp   ilowpass.jog.z.scale 100
setp   ilowpass.jog.a.scale 100
setp   ilowpass.jog.x.gain  0.01
setp   ilowpass.jog.y.gain  0.01
setp   ilowpass.jog.z.gain  0.01
setp   ilowpass.jog.a.gain  0.01

loadrt scale names=scale.axis.x,scale.axis.y,scale.axis.z,scale.axis.a
addf   scale.axis.x   servo-thread
addf   scale.axis.y   servo-thread
addf   scale.axis.z   servo-thread
addf   scale.axis.a   servo-thread
setp   scale.axis.x.gain   0.01 
setp   scale.axis.y.gain   0.01 
setp   scale.axis.z.gain   0.01
setp   scale.axis.a.gain   0.01  
setp   scale.axis.x.offset  0
setp   scale.axis.y.offset  0
setp   scale.axis.z.offset  0
setp   scale.axis.a.offset  0

# Estop
net  pdnt.machine.is-on   halui.machine.is-on   whb.halui.machine.is-on
net  pdnt.machine.on   whb.halui.machine.on   halui.machine.on
net  pdnt.machine.off   whb.halui.machine.off   halui.machine.off

# program
net  pdnt.program.is-idle   whb.halui.program.is-idle   halui.program.is-idle
net  pdnt.program.is-paused   whb.halui.program.is-paused   halui.program.is-paused
net  pdnt.program.is-running   whb.halui.program.is-running   halui.program.is-running
net  pdnt.program.resume   whb.halui.program.resume   halui.program.resume
net  pdnt.program.pause   whb.halui.program.pause   halui.program.pause
net  pdnt.program.run   whb.halui.program.run   halui.program.run
net  pdnt.program.stop   whb.halui.program.stop   halui.program.stop

# axis   
net  pdnt.joint.X.select   whb.halui.joint.x.select   halui.joint.0.select
net  pdnt.joint.Y.select   whb.halui.joint.y.select   halui.joint.1.select
net  pdnt.joint.Z.select   whb.halui.joint.z.select   halui.joint.2.select

net  pdnt.axis.0.jog-scale   whb.axis.0.jog-scale   scale.axis.x.in   
net  pdnt.axis.1.jog-scale   whb.axis.1.jog-scale   scale.axis.y.in   
net  pdnt.axis.2.jog-scale   whb.axis.2.jog-scale   scale.axis.z.in  

net  scale.axis.0.jog-scale   scale.axis.x.out   axis.x.jog-scale
net  scale.axis.1.jog-scale   scale.axis.y.out   axis.y.jog-scale
net  scale.axis.2.jog-scale   scale.axis.z.out   axis.z.jog-scale

net  pdnt.axis.0.jog-counts   whb.axis.0.jog-counts   ilowpass.jog.x.in
net  pdnt.axis.1.jog-counts   whb.axis.1.jog-counts   ilowpass.jog.y.in
net  pdnt.axis.2.jog-counts   whb.axis.2.jog-counts   ilowpass.jog.z.in

net  pdnt.ilowpass.jog.0.jog-counts   ilowpass.jog.x.out   axis.x.jog-counts
net  pdnt.ilowpass.jog.1.jog-counts   ilowpass.jog.y.out   axis.y.jog-counts
net  pdnt.ilowpass.jog.2.jog-counts   ilowpass.jog.z.out   axis.z.jog-counts

net  pdnt.axis.0.jog-enable   whb.axis.0.jog-enable   axis.x.jog-enable
net  pdnt.axis.1.jog-enable   whb.axis.1.jog-enable   axis.y.jog-enable
net  pdnt.axis.2.jog-enable   whb.axis.2.jog-enable   axis.z.jog-enable

net  pdnt.axis.0.jog-vel-mode   whb.axis.0.jog-vel-mode   axis.x.jog-vel-mode
net  pdnt.axis.1.jog-vel-mode   whb.axis.1.jog-vel-mode   axis.y.jog-vel-mode
net  pdnt.axis.2.jog-vel-mode   whb.axis.2.jog-vel-mode   axis.z.jog-vel-mode

# macro buttons

net pdnt.macro.1   whb.button.macro-1   halui.mdi-command-01
net pdnt.macro.2   whb.button.macro-2   halui.mdi-command-02
net pdnt.macro.3   whb.button.macro-3   halui.mdi-command-03
net pdnt.macro.4   whb.button.macro-4   halui.mdi-command-04
net pdnt.button.m-home   whb.button.m-home   halui.mdi-command-05
net pdnt.macro.6   whb.button.macro-6   halui.mdi-command-06
net pdnt.button.w-home   whb.button.w-home   halui.mdi-command-07   
net pdnt.macro.8   whb.button.macro-8   halui.mdi-command-08
net pdnt.macro.9   whb.button.macro-9   halui.mdi-command-09
net pdnt.macro.10   whb.button.macro-10   halui.mdi-command-10
net pdnt.macro.11   whb.button.macro-11   halui.mdi-command-11
net pdnt.macro.12   whb.button.macro-12   halui.mdi-command-12
net pdnt.macro.13   whb.button.macro-13   halui.mdi-command-13
net pdnt.macro.14   whb.button.macro-14   halui.home-all
net pdnt.macro.15   whb.button.macro-15   halui.mdi-command-15
net pdnt.macro.16   whb.button.macro-16   halui.mdi-command-16
net pdnt.button.safe-z   whb.button.safe-z   halui.mdi-command-17
net pdnt.button.s-on-off   whb.button.s-on-off   halui.mdi-command-18
net  pdnt.button.probe-z   whb.button.probe-z   halui.mdi-command-19
#net pdnt.macro.20   whb.button.macro-20   halui.mdi-command-20

# already connected to halui.estop.{activate, reset} via whb.halui.estop.{activate, reset}
net  pdnt.button.reset   whb.button.reset
# already linked to halui.program.stop via whb.program.stop
net  pdnt.button.stop   whb.button.stop# already connected to halui.program.{run, pause, resume} via whb.halui.program.{run, pause, resume}
net  pdnt.button.start-pause   whb.button.start-pause   
# unused
net pdnt.button.fn   whb.button.fn
net  pdnt.button.mode-continuous   whb.button.mode-continuous
net  pdnt.button.mode-step   whb.button.mode-step

# spindle
net  spindle.is-on   whb.halui.spindle.is-on
net  spindle.stop   whb.halui.spindle.stop
net  spindle.forward   whb.halui.spindle.forward
net  spindle.reverse   whb.halui.spindle.reverse
net  spindle.spindle-override.value   whb.halui.spindle-override.value	halui.spindle.0.override.value
net  spindle.spindle-override.increase   whb.halui.spindle-override.increase	halui.spindle.0.override.increase
net  spindle.spindle-override.decrease   whb.halui.spindle-override.decrease	halui.spindle.0.override.decrease
net  spindle.velocity.abs-rpm   whb.motion.spindle-speed-abs
# mode
net  pdnt.halui.mode.auto   whb.halui.mode.auto   halui.mode.auto
net  pdnt.halui.mode.joint   whb.halui.mode.joint   halui.mode.joint
net  pdnt.halui.mode.manual   whb.halui.mode.manual   halui.mode.manual
net  pdnt.halui.mode.mdi   whb.halui.mode.mdi   halui.mode.mdi
net  pdnt.halui.mode.is-auto   halui.mode.is-auto   whb.halui.mode.is-auto
net  pdnt.halui.mode.is-joint   halui.mode.is-joint   whb.halui.mode.is-joint
net  pdnt.halui.mode.is-manual   halui.mode.is-manual   whb.halui.mode.is-manual
#net  pdnt.halui.mode.is-mdi   halui.mode.is-mdi   whb.halui.mode.is-mdi

# feed
net  pdnt.halui.feed-override.scale   whb.halui.feed-override.scale   halui.feed-override.scale halui.rapid-override.scale
net  pdnt.halui.feed-override.direct-val   whb.halui.feed-override.direct-val   halui.feed-override.direct-value halui.rapid-override.direct-value
net  pdnt.halui.feed-override.counts   whb.halui.feed-override.counts   halui.feed-override.counts halui.rapid-override.counts
net  pdnt.halui.feed-override.count-enable whb.halui.feed-override.count-enable halui.feed-override.count-enable
net  pdnt.halui.feed-override.value   halui.feed-override.value   whb.halui.feed-override.value
setp   whb.halui.feed-override.min-value   [DISPLAY]MIN_FEED_OVERRIDE
setp   whb.halui.feed-override.max-value   [DISPLAY]MAX_FEED_OVERRIDE

net  pdnt.halui.feed-override.increase   whb.halui.feed-override.increase   halui.feed-override.increase halui.rapid-override.increase
net  pdnt.halui.feed-override.decrease   whb.halui.feed-override.decrease   halui.feed-override.decrease halui.rapid-override.decrease
net  pdnt.button.feed-plus   whb.button.feed-plus
net  pdnt.button.feed-minus   whb.button.feed-minus
# axis
net  pdnt.halui.axis.0.pos-feedback   halui.axis.x.pos-feedback   whb.halui.axis.0.pos-feedback
net  pdnt.halui.axis.1.pos-feedback   halui.axis.y.pos-feedback   whb.halui.axis.1.pos-feedback
net  pdnt.halui.axis.2.pos-feedback   halui.axis.z.pos-feedback   whb.halui.axis.2.pos-feedback

net  pdnt.halui.axis.0.pos-relative   halui.axis.x.pos-relative   whb.halui.axis.0.pos-relative
net  pdnt.halui.axis.1.pos-relative   halui.axis.y.pos-relative   whb.halui.axis.1.pos-relative
net  pdnt.halui.axis.2.pos-relative   halui.axis.z.pos-relative   whb.halui.axis.2.pos-relative

Macros und Hal sind bereits passend in der INI hinterlegt:


[HAL]
HALFILE = hallib/core_igor.hal
HALFILE = hallib/xhc-whb04b-6.hal
POSTGUI_HALFILE = hallib/postgui.hal
HALUI = halui

[HALUI]

	MDI_COMMAND=(debug,00)
	MDI_COMMAND=(debug,macro1)
	MDI_COMMAND=(debug,macro2)
	MDI_COMMAND=(debug,macro3)
	MDI_COMMAND=(debug,macro4)  
	MDI_COMMAND=o<go_to_home> call
	MDI_COMMAND=(debug,macro6)
	MDI_COMMAND=o<go_to_workhome> call
	MDI_COMMAND=(debug,macro8)
	MDI_COMMAND=o<probe_z_half> call
	MDI_COMMAND=(debug,macro10)
	MDI_COMMAND=(debug,macro11)
	MDI_COMMAND=(debug,macro12)
	MDI_COMMAND=(debug,macro13)
	MDI_COMMAND=(debug,macro14)
	MDI_COMMAND=(debug,macro15)
	MDI_COMMAND=(debug,macro16)
	MDI_COMMAND=o<go_to_zhome> call
	MDI_COMMAND=(debug,macro18_Spindle_on_of)
	MDI_COMMAND=o<probe_z> call
       # MDI_COMMAND=(debug,macro20)
O<go_to_home> sub

 G53 G0 Z0
 G53 G0 X0 Y0
 
O<go_to_home> endsub

M2
O<go_to_workhome> sub

 G53 G0 Z0
 G0 X0 Y0
 
O<go_to_workhome> endsub

M2
O<probe_z_half> sub
;check for active axis
    	o100 if [#<_hal[whb.axis.0.jog-enable]> eq 1] ;If x-axis active
                G10 L20 P0 X[#<_x>/2]                          ;zero X
	o100 endif
    	o110 if [#<_hal[whb.axis.1.jog-enable]> eq 1] ;If Y-axis active
                G10 L20 P0 Y[#<_y>/2]                          ;zero Y
	o110 endif
    	o120 if [#<_hal[whb.axis.2.jog-enable]> eq 1] ;If Z-axis active
                G10 L20 P0 Z[#<_z>/2]                          ;zero Z
	o120 endif
O<probe_z_half> endsub

M2
O<go_to_zhome> sub

 G53 G0 Z0
 
O<go_to_zhome> endsub

M2
O<probe_z> sub
;check for active axis
    	o100 if [#<_hal[whb.axis.0.jog-enable]> eq 1] ;If x-axis active
                G10 L20 P0 X0                          ;zero X
	o100 endif
    	o110 if [#<_hal[whb.axis.1.jog-enable]> eq 1] ;If Y-axis active
                G10 L20 P0 Y0                          ;zero Y
	o110 endif
    	o120 if [#<_hal[whb.axis.2.jog-enable]> eq 1] ;If Z-axis active
                G10 L20 P0 Z0                          ;zero Z
	o120 endif
O<probe_z> endsub

M2

Damit ist er Retrofit mehr oder weniger abgeschlossen. Es wird nach und nach immer mal wieder Änderungen oder Erweiterungen geben.

Linuxcnc Retrofit von Igor Teil 6 Werkzeuglängen Sensor

Es waren ja noch genug IO’s frei und um einem das Einrichten der Werkzeuge zu erleichtern habe ich mir einen einfachen Werkzeuglängensensor beschafft und in Igor verbaut. Das ist die erste Maßnahme, die über den Retrofit hinaus geht. Daher mussten hier erst mal neue Leitungen gezogen werden und ich habe die 7i77 in der Steuerkonsole dafür ausgesucht um die Wege kurz zu halten:

Konsole
Kabel Portal
Sensor Montiert

Jetzt musste noch die Software vorbereitet werden und der Ort hinterlegte werden. Das macht man im Offsets Tab, hier hinterlegt man auch ie Wege und Geschwindigkeiten für das Antasten

Die Steuerung erfolgt über den Tool Tab, auch hier habe ich mir wieder ein paar Sachen angepasst. Und jetzt kommt auch der Zeitpunkt wo ich auf mein Werkzeugwechsel-Script eingehen werde. Nicht alle meine Werkzeughalter sind für den Wechsler geeignet, daher unterscheide ich in allen Skripten zwischen Werkzeugen im Wechsler und welchen die Manuell gewechselt werden müssen. Doch später dazu mehr.

Zunächst gehen wir hier das Toolchange Panel durch:

Unload Spindle - MDI Button - M61 Q0 G49 #5210 = 0
M6 G43 - subcall Button - m6_tool_call_tool_page.ngc

(author: Chris P)
(version: 0.1)
(date: 02/8/20)
(m6 tool call with g43 offset applied)
o<M6_tool_call_tool_page> sub
#<tool_number_entry_tool_page> = #1
T#<tool_number_entry_tool_page> M6
G43 H#<tool_number_entry_tool_page>
o<tool_number_entry_tool_page> endsub
M2 (end program)
M6 - MDI Command remapped to - toolchang2.ngc

o<toolchange2> sub
(M108 P#<_current_tool>  Q#<_selected_tool> )
;assign the tool numbers held in parameters to the pocket numbers
#1 = #5190
#2 = #5191
#3 = #5192
#4 = #5193
#5 = #5194
#6 = #5195
#7 = #5196
#8 = #5197
#9 = #5198
#10 = #5199
#11 = #5200
#12 = #5201
;assign the variables passed by M6 to some parameters
#100 = #<_selected_tool>
#110 = #<_current_tool>
(#120 = #<selected_pocket>)

O10 if [#100 EQ #110] ; checks if tool in the spindle is same as requested
 o<toolchange> endsub [1]
M2
O10 endif

#<next_pocket> = 0 ; assigns 0 to the next pocket for a later check if the tool is found in the basket
#<loaded_pocket> = 0 ; assigns 0 to the next pocket for a later check if the tool is found in the basket and loaded

#15 = 12 ;assign test parameter the number of pockets in the carousel

O100 do
 	O110 if [#[5189 + #15] EQ #100] ; checks all pockets to see if it contains tool number requested as the new tool
		#<next_pocket> = #15 ; if tool is found in pocket, assigns the next pocket
	O110 endif
   
	O115 if [#[5189 + #15] EQ #110] ; checks if the pocket is loaded in spindle
		#<loaded_pocket> = #15

	O115 endif
   #15= [#15 - 1]
O100 while [#15 GT 0]

;now we know which pocket the next tool is sitting in 
;and we know inwhich pocket the current tool is
;we need to know if we need to put a tool away
;or if there is no tool in the spindle


O180 IF [#110 GT 0] ; checks if there is a valid tool in the spindle
    	O190 if [#<loaded_pocket> EQ 0] ;If there is a tool in the spindle, checks if it is an pocket
                ; Go for manual Tool removal
        	G53 G0 Z0     ;raise spindle
                G53 G0 X0 Y0  ;move to door
                M125          ; remove tool
	O190 endif
    	O195 if [#<loaded_pocket> GT 0] ;If there is a tool in the spindle, checks if it is an pocket
                ; Go for atc Tool removal
                G0 G53 Z0	; raise spindle
                M110            ; draw bar loose
                M112            ; lower basket
                M116            ; raise pockets	
	O195 endif
O180 ENDIF

O200 IF [#100 GT 0]  ; selected tool is not tool0
    	O210 if [#<next_pocket> EQ 0] ;if new tool is not in a pocket
                ; Go for manual Tool load
        	M113		; Raise basket
                G53 G0 Z0       ; Raise spindle
                G53 G0 X0 Y0	; move to door
                M110            ; draw bar loose
                M126            ; manual tool load
        O210 endif
   
    	O215 if [#<next_pocket> GT 0] ;If new tool is in a pocket
                ; Go for atc Tool Load
        	G0 G53 Z0       ; raise sindle
                M110            ; draw bar loose
                M112            ; Lower basket		
                M131 P#<next_pocket>         ; load pocket
                M114            ; air blast
                S150 M3		; rotate spindle
                M113		; raise basket
                M115            ; stop air blast
                M111		; clamp tool
                M5		; stop spindle
       	O215 endif
    
O200 Else
        ;new tool is 0 raise basket and clamp drawbar  
        M113 ;raise basket
	M111 ;clamp drawbar
O200 ENDIF


M61 Q#100

o<toolchang2> endsub [1]

M2
#!/bin/bash
#Manueller Werkzeugwechel M126
set -- $(halcmd -s show pin iocontrol.0.tool-prep-number)
newnr=$4
toolline=$(grep  "T$newnr " tool.tbl )
tool=$(cut -d ";" -f2 <<< $toolline)
temp=$(cut -d "Z" -f2 <<< $toolline)
Offset=${temp:1:3}  
zenity  --info --title="Werkzeugwechsel" --text "Werkzeug: T$newnr \n\n $tool \n\n Z-Offset: $Offset mm \n\n einsetzen"

		echo "Werkzeug spannen"		
		~/linuxcnc/configs/IgorProbe/nc_files/M111
zenity --info  --title="Werkzeugwechsel" --text "Werkzeug T$newnr gespannt?"
exit 0

Jetzt zu den Funktionen auf dem Toolsetter Panel

Clean Probe - MDI Button - M134 P2

#!/bin/bash
#M134 Druckluft fuer Werkzeugmesser
P=$1
Q=$2
case=$P
if [ -z "$1" ]
  then
    case=3
fi
#
if [ $case = 0 ]; then
 halcmd sets o-probe-clean false
#
elif [ $case = 1 ]; then
 halcmd sets o-probe-clean true
else
 set -- $(halcmd -s show sig o-probe-clean)
    open=$2
    if [ "$open" == "FALSE" ] ; then
        halcmd sets o-probe-clean true
    else 
        halcmd sets o-probe-clean false
    fi

fi

exit 0
Touch off current tool - subcall Button - tool_touch_off.ngc

o<tool_touch_off> sub

#<worktable> = #<_hal[i-table-is-2]>

#<fast_probe_fr> = #1    (set from probe screen fast probe feed rate)
#<slow_probe_fr> = #2    (set from probe screen slow probe feedrate)
#<z_max_travel> = #3    (max z distance the tool travels before erroring out if not contact is made)
#<xy_max_travel> = #4    (max xy distance the tool travels before erroring out if not contact is made)
#<retract_distance> = #6    (distance the tool retracts after making contact during fast feed mode)
#<spindle_zero_height> = #5    (G53 distance from home to spindle nose triggering point on touch plate)
#<tool_diameter_probe_mode> = #8    (activates the tool diameter probe subroutine section)
#<tool_diameter_offset_mode> = #9    (activates the tool diameter offset position for probe subroutine section)
#<tool_diameter> = #10    (current tool's diameter used for offseting probe position in x axis)

o<100> if [#<worktable> EQ 0]
                (need to change table for probing)
                G53 G0 Z0     ;raise spindle
                G53 G0 X0 Y0  ;move to door
                M123
o<100> endif

G92.1    (Cancel G92 offset)

(#<workspace_z> = #[5203 + [20 * #5220]])
#<workspace_z> = #5220

#<tool_touch_x_coords> = #5181
#<tool_touch_y_coords> = #5182
#<tool_touch_z_coords> = #5183

#<tool_radius_offset> = [#<tool_diameter> / 2]
#<offset_probing_position> = [#<tool_touch_y_coords> + #<tool_radius_offset>]

G59.3

o<110> if [#<tool_diameter_offset_mode> EQ 1]
  #<tool_touch_y_coords> = #<offset_probing_position>
o<110> endif

o<115> if [2 EQ 2]
  G49  (cancel tlo)
o<115> endif

G90    (set absolute coordinates)
M134 P1 (blow of probe)
G53 G0 Z0    (move to z0 home position)
G53 G0 X#<tool_touch_x_coords> Y#<tool_touch_y_coords>
G53 G0 Z#<tool_touch_z_coords>

G91
F #<fast_probe_fr>
G38.2 Z-[#<z_max_travel>]    (fast tool probe)
#<z_fast_probe> = #5063    (save probe result of fast probe to parameters)
G0 Z[#<retract_distance>]    (retract tool retract distance amount)

(Slow Probe Rule, if Slow Probe FR is set to 0, Slow Probe is Bypassed)
o<120> if [#<slow_probe_fr> GT 0]
  (Initiate Slow Z- Probe)
  G91
  F[#<slow_probe_fr>]    (set probe slow feedrate)
  G38.2 Z-[#<retract_distance> * 1.5]    (slow tool probe)
  #<z_slow_probe> = #5063
  (debug, Probed Pos: #5063 Z Pos: #<_z>)
  G90
  G0 Z[#<z_slow_probe> + #<retract_distance>]
o<120> endif

o<130> if [#5070 EQ 1]    (verify probe event was succesful)
  #<z_slow_probe> = #5063    (save slow probe result to parameters)
o<130> else
  (MSG,Tool Length Offset Probe Failed)
o<130> endif

(Tool Diameter Probe Mode Section, User must define this section as needed)
o<140> if [#<tool_diameter_probe_mode> EQ 1]
  (MSG, Tool Diameter Probing is Not Defined in Subroutine)
o<140> endif

G49
o<150> if [3 EQ 3]
  G49
o<150> endif

G90    (set absolute coordinates)
M134 P0 (stop blow of probe)

G53 G0 Z0 (Send Spindle to home zero position)

(define new tool length offset parameters)
#<new_tool_length_offset> = [ABS[#<spindle_zero_height> + #5063]]

G10 L1 P #5400 Z [#<new_tool_length_offset>]  (5400 = tool number)

o<160> if [#<workspace_z> EQ 1]
  G54
o<160> else if [#<workspace_z> EQ 2]
  G55
o<160> else if [#<workspace_z> EQ 3]
  G56
o<160> else if [#<workspace_z> EQ 4]
  G57
o<160> else if [#<workspace_z> EQ 5]
  G58
o<160> else if [#<workspace_z> EQ 6]
  G59
o<160> else if [#<workspace_z> EQ 7]
  G59.1
o<160> else if [#<workspace_z> EQ 8]
  G59.2
o<160> endif

T #5400 G43  H #5400    (enable tool length offset)

o<170> if [#<worktable> EQ 0]
                (need to chante table after probing)
                G53 G0 Z0     ;raise spindle
                G53 G0 X0 Y0  ;move to door
                M122
o<170> endif

o<tool_touch_off> endsub

M2 (end program)
Touch off ATC - subcall Button - atctouchoff.ngc

o<atctouchoff> sub
(print, o<atctouchoff>)
(DEBUG, EVAL[vcp.getWidget{"dynatc"}.atc_message{"Touch off ATC"}])
T0 M6; empty spindle
#1 = 0
o130 while [#1 LT 12]
    #1 = [#1+1]
    #2 = #[5189+#1]
    o140  if [#2  GT 0]
    (DEBUG, EVAL[vcp.getWidget{"dynatc"}.atc_message{"Touch off Tool #2 "}])
    M6 T#2
    o<tool_touch_off> call
    o140 endif
o130 endwhile

(DEBUG, EVAL[vcp.getWidget{"dynatc"}.atc_message{"Igor"}])
o<atctouchoff> endsub [1]

M2

Linuxcnc Retrofit von Igor Teil 5 Wiederauferstehung

Damit konnte Igor das erste mal mit neuer Steuerung bewegt werden. Wie gesagt es war nicht alles so linear wir hier dargestellt. Das ganze hier dient mir mehr oder weniger als Dokumentation, Falls ich sowas nochmal machen muss, auch welchem Grund auch immer. Aber mit all den Voran gegangen Schritten ließ sich das ganze Starten und Homen:

Mit dem Schritt können wir uns nun dem Werkzeugwechsel und dem Wechseltisch widmen. Probe Basic arbeitet normalerweise mit einem Karussell-Wechsler, der sich doch etwas anders Verhält als der Korbwechsler von Igor. Daher habe ich die Seite für den Werkzeugwechsel an meine Bedürfnisse angepasst und mich dabei an den Funktionen orientiert, die auch in der Sinumerik zur Verfügung standen

ATC Page

Die einzelnen Knöpfe mit den dazugehörigen Programmen werde ich hier durch gehen. Doch zuvor kommen noch zwei kleine Programme, die helfen Fehler zu vermeiden weil bestimmte Parameter nicht erreicht wurden waitfor liegt im $USER/bin/ Ordner:

#!/bin/bash
n=0
if [ $# != 2 ]; then
    echo usage: $0 SignalName DesiredValue
    exit 1
fi
signal=$1
value=$2

while :; do
    set -- $(halcmd -s show sig $signal)
    if [ x"$2" == x"$value" ]; then
        exit 0
    fi
    sleep 0.25
    if [ $n -gt 20 ]; then
        zenity --info --text "$signal hat nach $n Zyklen den Wert $value nicht erreicht"
    fi
    let "n++"
done


Fangen wir dem dem “ATC Manual Control Panel” hier haben wir mehr oder weniger die Komplette Steuerung der einzelnen Teilschritte, die für den Tisch und Werkzeugwechsel notwendig sind Jeweils der Knopf und das dazugehörige Programm dazu:

Drawbar loose - MDI Buttom - M110

#!/bin/bash
#Werkzeug lösen
halcmd sets o-tool-open true
waitfor i-tool-is-open TRUE
exit 0
Drawbar Tight - MDI Buttom - M111

#!/bin/bash
#Werkzeug spannen
halcmd sets o-tool-open FALSE
waitfor i-tool-is-open FALSE
exit 0

ATC UP - MDI Button - M113

#!/bin/bash
#Korb anheben

halcmd sets o-tool-basket-down FALSE
halcmd sets o-tool-basket-up TRUE
#waitfor i-tool-basket-is-down FALSE
waitfor i-tool-basket-is-up TRUE
halcmd sets o-tool-open FALSE
waitfor i-tool-is-open FALSE

exit 0
ATC Down - MDI Button - M112

#!/bin/bash
#Kor Absenken
halcmd sets o-tool-open true
waitfor i-tool-is-open TRUE
halcmd sets o-tool-basket-up FALSE
halcmd sets o-tool-basket-down TRUE
waitfor i-tool-basket-is-up FALSE
waitfor i-tool-basket-is-down TRUE
#halcmd sets o-tool-basket-down FALSE

exit 0
Arm Down - MDI Button M131 P#<Armnr>

#!/bin/bash
#Arm Absenken
P=$1
Q=$2
armnr=${P%.*}
waitfor i-tool-basket-is-down 	TRUE
halcmd sets o-tool-01-down	FALSE
halcmd sets o-tool-02-down	FALSE
halcmd sets o-tool-03-down	FALSE
halcmd sets o-tool-04-down	FALSE
halcmd sets o-tool-05-down	FALSE
halcmd sets o-tool-06-down	FALSE
halcmd sets o-tool-07-down	FALSE
halcmd sets o-tool-08-down	FALSE
halcmd sets o-tool-09-down	FALSE
halcmd sets o-tool-10-down	FALSE
halcmd sets o-tool-11-down	FALSE
halcmd sets o-tool-12-down	FALSE
halcmd sets o-tool-all-up   	TRUE
#
waitfor i-tool-01-is-down	FALSE
waitfor i-tool-02-is-down	FALSE
waitfor i-tool-03-is-down	FALSE
waitfor i-tool-04-is-down	FALSE
waitfor i-tool-05-is-down	FALSE
waitfor i-tool-06-is-down	FALSE
waitfor i-tool-07-is-down	FALSE
waitfor i-tool-08-is-down	FALSE
waitfor i-tool-09-is-down	FALSE
waitfor i-tool-10-is-down	FALSE
waitfor i-tool-11-is-down	FALSE
waitfor i-tool-12-is-down	FALSE
#
waitfor i-tool-01-is-up	TRUE
waitfor i-tool-02-is-up	TRUE
waitfor i-tool-03-is-up	TRUE
waitfor i-tool-04-is-up	TRUE
waitfor i-tool-05-is-up	TRUE
waitfor i-tool-06-is-up	TRUE
waitfor i-tool-07-is-up	TRUE
waitfor i-tool-08-is-up	TRUE
waitfor i-tool-09-is-up	TRUE
waitfor i-tool-10-is-up	TRUE
waitfor i-tool-11-is-up	TRUE
waitfor i-tool-12-is-up	TRUE
#
halcmd sets o-tool-all-up   	FALSE
#
echo $armnr
if [ $armnr = 1 ]; then
	halcmd sets o-tool-01-down	TRUE
	  waitfor i-tool-01-is-up	FALSE
	  waitfor i-tool-01-is-down	TRUE
	halcmd sets o-tool-01-down	FALSE
fi
#
if [ $armnr = 2 ]; then
	halcmd sets o-tool-02-down	TRUE
	  waitfor i-tool-02-is-up	FALSE
	  waitfor i-tool-02-is-down	TRUE
	halcmd sets o-tool-02-down	FALSE
fi
#
if [ $armnr = 3 ]; then
	halcmd sets o-tool-03-down	TRUE
	  waitfor i-tool-03-is-up	FALSE
	  waitfor i-tool-03-is-down	TRUE
	halcmd sets o-tool-03-down	FALSE
fi
#
if [ $armnr = 4 ]; then
	halcmd sets o-tool-04-down	TRUE
	  waitfor i-tool-04-is-up	FALSE
	  waitfor i-tool-04-is-down	TRUE
	halcmd sets o-tool-04-down	FALSE
fi
#
if [ $armnr = 5 ]; then
	halcmd sets o-tool-05-down	TRUE
	  waitfor i-tool-05-is-up	FALSE
	  waitfor i-tool-05-is-down	TRUE
	halcmd sets o-tool-05-down	FALSE
fi
#
if [ $armnr = 6 ]; then
	halcmd sets o-tool-06-down	TRUE
	  waitfor i-tool-06-is-up	FALSE
	  waitfor i-tool-06-is-down	TRUE
	halcmd sets o-tool-06-down	FALSE
fi
#
if [ $armnr = 7 ]; then
	halcmd sets o-tool-07-down	TRUE
	  waitfor i-tool-07-is-up	FALSE
	  waitfor i-tool-07-is-down	TRUE
	halcmd sets o-tool-07-down	FALSE
fi
#
if [ $armnr = 8 ]; then
	halcmd sets o-tool-08-down	TRUE
	  waitfor i-tool-08-is-up	FALSE
	  waitfor i-tool-08-is-down	TRUE
	halcmd sets o-tool-08-down	FALSE
fi
#
if [ $armnr = 9 ]; then
	halcmd sets o-tool-09-down	TRUE
	  waitfor i-tool-09-is-up	FALSE
	  waitfor i-tool-09-is-down	TRUE
	halcmd sets o-tool-09-down	FALSE
fi
#
if [ $armnr = 10 ]; then
	halcmd sets o-tool-10-down	TRUE
	  waitfor i-tool-10-is-up	FALSE
	  waitfor i-tool-10-is-down	TRUE
	halcmd sets o-tool-10-down	FALSE
fi
#
if [ $armnr = 11 ]; then
	halcmd sets o-tool-11-down	TRUE
	  waitfor i-tool-11-is-up	FALSE
	  waitfor i-tool-11-is-down	TRUE
	halcmd sets o-tool-11-down	FALSE
fi
#
if [ $armnr = 12 ]; then
	halcmd sets o-tool-12-down	TRUE
	  waitfor i-tool-12-is-up	FALSE
	  waitfor i-tool-12-is-down	TRUE
	halcmd sets o-tool-12-down	FALSE
fi

exit 0
Airblast - MDI Button - M130 P3

#!/bin/bash
#Kegel Ausblasen beginnen
P=$1
halcmd sets o-tool-clean TRUE
sleep $P
#Kegel Ausblasen beenden
halcmd sets o-tool-clean FALSE

exit 0
ALL UP - MDI Button - M116

#!/bin/bash
#Arme Anheben
waitfor i-tool-basket-is-down TRUE
halcmd sets o-tool-clean FALSE
halcmd sets o-tool-01-down	FALSE
halcmd sets o-tool-02-down	FALSE
halcmd sets o-tool-03-down	FALSE
halcmd sets o-tool-04-down	FALSE
halcmd sets o-tool-05-down	FALSE
halcmd sets o-tool-06-down	FALSE
halcmd sets o-tool-07-down	FALSE
halcmd sets o-tool-08-down	FALSE
halcmd sets o-tool-09-down	FALSE
halcmd sets o-tool-10-down	FALSE
halcmd sets o-tool-11-down	FALSE
halcmd sets o-tool-12-down	FALSE
halcmd sets o-tool-all-up   	TRUE
#
waitfor i-tool-01-is-down	FALSE
waitfor i-tool-02-is-down	FALSE
waitfor i-tool-03-is-down	FALSE
waitfor i-tool-04-is-down	FALSE
waitfor i-tool-05-is-down	FALSE
waitfor i-tool-06-is-down	FALSE
waitfor i-tool-07-is-down	FALSE
waitfor i-tool-08-is-down	FALSE
waitfor i-tool-09-is-down	FALSE
waitfor i-tool-10-is-down	FALSE
waitfor i-tool-11-is-down	FALSE
waitfor i-tool-12-is-down	FALSE
#
waitfor i-tool-01-is-up	TRUE
waitfor i-tool-02-is-up	TRUE
waitfor i-tool-03-is-up	TRUE
waitfor i-tool-04-is-up	TRUE
waitfor i-tool-05-is-up	TRUE
waitfor i-tool-06-is-up	TRUE
waitfor i-tool-07-is-up	TRUE
waitfor i-tool-08-is-up	TRUE
waitfor i-tool-09-is-up	TRUE
waitfor i-tool-10-is-up	TRUE
waitfor i-tool-11-is-up	TRUE
waitfor i-tool-12-is-up	TRUE
#
halcmd sets o-tool-all-up   	FALSE

exit 0
Erster Test
unlock table - MDI Button - M120

#!/bin/bash
#Tisch anheben M120
halcmd sets o-table-lock FALSE
waitfor o-table-lock FALSE
sleep 1
halcmd sets o-table-up TRUE
waitfor i-table-is-up TRUE
exit 0
Lock table - MDI Button - M121

#!/bin/bash
#Tisch verriegeln M121
while :; do
	set -- $(halcmd -s show sig i-table-is-1)
	seite1=$2
	set -- $(halcmd -s show sig i-table-is-2)
	seite2=$2
        echo $seite1 
	echo $seite2
    if [ "$seite1" == "TRUE" ] || [ "$seite2" == "TRUE" ] ; then
        halcmd sets o-table-up FALSE
	halcmd sets o-table-lock TRUE
	waitfor i-table-is-up FALSE
	waitfor o-table-lock TRUE
	exit 0
    fi
    sleep 2
done

exit 0
Change Table - MDI Button - M124

#!/bin/bash
#Tisch wechseln M124
set -- $(halcmd -s show sig i-table-is-1)
seite1=$2
set -- $(halcmd -s show sig i-table-is-2)
seite2=$2
if [ "$seite1" == "TRUE" ] ; then
        ~/linuxcnc/configs/IgorProbe/nc_files/M123
fi
if [ "$seite2" == "TRUE" ] ; then
        ~/linuxcnc/configs/IgorProbe/nc_files/M122
fi

exit 0
1 - MDI Button - M122

#!/bin/bash
#Tisch Seite 1 M122
set -- $(halcmd -s show sig i-table-is-1)
seite1=$2
if [ "$seite1" == "TRUE" ] ; then
        exit 0

else
	~/linuxcnc/configs/IgorProbe/nc_files/M120
	waitfor i-table-is-up TRUE
	halcmd sets o-table-1 TRUE
	waitfor i-table-is-1 TRUE
#    sleep 3
	~/linuxcnc/configs/IgorProbe/nc_files/M121
	halcmd sets o-table-1 FALSE
fi

exit 0
2 - MDI Button - M123

#!/bin/bash
#Tisch Seite 2 M123
set -- $(halcmd -s show sig i-table-is-2)
seite2=$2
if [ "$seite2" == "TRUE" ] ; then
        exit 0

else 
	~/linuxcnc/configs/IgorProbe/nc_files/M120
	waitfor i-table-is-up TRUE
	halcmd sets o-table-2 TRUE
	waitfor i-table-is-2 TRUE	
#    sleep 3
	~/linuxcnc/configs/IgorProbe/nc_files/M121
	halcmd sets o-table-2 FALSE
fi
exit 0 
Tischlein Wechsel Dich

Dann wäre da noch die Rechte Seite, bei der geht es um das Eigentliche Laden von Werkzeugen in den Wechsler:

Begin Load Basket - subcall Button - beginloadtoolchanger.ngc

o<beginloadtoolchanger> sub
(print, o<beginloadtoolchanger>)
O10 if [#<_current_tool> gt 0] ; checks if spindle empty
(MSG, Spindle not epmty)  
 o<toolchange> endsub [1]
M2
O10 endif
M110
M112
M116

o<beginloadtoolchanger> endsub [1]

M2
Load Toolchanger - subcall Button - loadtoolchanger.ngc

(author: PL)
(version: 0.1)
(date: 7.3.2020)

(Bring ATC Arm down for loading)

o<loadtoolchanger> sub

O10 if [#<_current_tool> gt 0] ; checks if spindle empty
(MSG, Spindle not epmty)  
 o<toolchange> endsub [1]
M2
O10 endif
O20 if [#<_hal[i-tool-basket-is-down]> eq 0 ] ; checks if basket is ready
(MSG, basket not ready)  
 o<toolchange> endsub [1]
M2
O20 endif
;assign the variables from UI to some parameters
#<loadarmnr_atc_page> = #1
#<tool_number_entry_atc_page> = #12
;M108 P#<tool_number_entry_atc_page> Q#<loadarmnr_atc_page>
M131 P#<loadarmnr_atc_page>
M132 P#<tool_number_entry_atc_page>
(DEBUG, EVAL[vcp.getWidget{"dynatc"}.store_tool{#<loadarmnr_atc_page>, #<tool_number_entry_atc_page>}])
#[5189 + #<loadarmnr_atc_page>] = #<tool_number_entry_atc_page> 
;M108 P[5189 + #<loadarmnr_atc_page>] Q#[5189 + #<loadarmnr_atc_page>]
M116
;assign the tool numbers in the pockets to the parameters

o<loadtoolchanger> endsub

M2
#!/bin/bash
#M132 Arm Laden
P=$1
Q=$2
newnr=$P
echo $newnr
toolline=$(grep  "T$newnr " tool.tbl )
tool=$(cut -d ";" -f2 <<< $toolline)
temp=$(cut -d "Z" -f2 <<< $toolline)
Offset=${temp:1:3}  
zenity --info --title="Korb Laden" --text "Werkzeug: T$newnr \n\n $tool \n\n Z-Offset: $Offset mm \n\n einsetzen"

zenity --info --title="Korb Laden" --text "Werkzeug T$P Gesichert?"
exit 0
#!/bin/bash
#M133 Arn leeren
P=$1
Q=$2

zenity --info --text "Werkzeug Aus Arm $P entfernen"

zenity --info --text "Arm $P Gesichert?"
exit 0
End Load Toolchanger - subcall button - endloadtoolchanger.ngc

o<endloadtoolchanger> sub
(print, o<endloadtoolchanger>)

M116
M113
M111

o<endloadtoolchanger> endsub [1]

M2
Copland pump 1 - MDI Button - M127

#!/bin/bash
#toggle relais 1
set -- $(halcmd -s show sig o-pump-1)
status=$2
if [ "$status" == "TRUE" ] ;    then
	halcmd sets o-pump-1	FALSE
    else
    halcmd sets o-pump-1	TRUE
fi

exit 0
ATC Automatic control Panel - subcall button - fillwidget.ngc

o<fillwidget> sub
(print, o<fillwidget>)
#1 = 0
o130 while [#1 LT 12]
    #1 = [#1+1]
    #2 = #[5189+#1]
    (DEBUG, EVAL[vcp.getWidget{"dynatc"}.store_tool{#1, #2}])
o130 endwhile

(DEBUG, EVAL[vcp.getWidget{"dynatc"}.atc_message{"Igor"}])
o<fillwidget> endsub [1]

M2
Power Up Sequence
Tool Arm test

Linuxcnc Retrofit von Igor Teil 4 Konfiguration

Hier war ich Anfangs sehr überfordert und habe eine erst mal alles im pncconf Wizzard mit einer anderen Mesakarte (5i25 und der 7i77) ans laufen bringen. Vielleicht wird die 7i92 inzwischen unterstützt. Was wir brauchen sind Encoder, Beschleunigungen usw. dann hat man eine 1. Konfiguration bei der man dann alles der 5i25 durch die 7I92 ersetzt.
Das ist eigentlich nur eine Zeile:

loadrt hm2_pci config=" num_encoders=6 num_pwmgens=0 num_stepgens=0 sserial_port_0=000xxx"

durch

loadrt hm2_eth board_ip="192.168.1.121" config=" num_encoders=6 num_pwmgens=0 num_stepgens=0 sserial_port_0=000xxx sserial_port_1=000xxx"

damit sollte sich schon mal was starten lassen. Inzwischen gehe ich eher direkt auf Hal und Ini Dateien los. Hier mal meine aktuelle INI:

[EMC]
VERSION = 1.1
MACHINE = Igor
DEBUG = 0

[DISPLAY]
DISPLAY = probe_basic
CONFIRM_EXIT = False
CONFIG_FILE = custom_config.yml
POSITION = 0x0
POSITION_OFFSET = RELATIVE
POSITION_FEEDBACK = ACTUAL
MAX_FEED_OVERRIDE = 2.000000
MAX_SPINDLE_OVERRIDE = 2.000000
MIN_SPINDLE_OVERRIDE = 0.010000
DEFAULT_SPINDLE_SPEED = 1000
INTRO_GRAPHIC = linuxcnc.gif
INTRO_TIME = 1
EDITOR = gedit
LOG_FILE = igor.log
PREFERENCE_FILE = igor.pref
PROGRAM_PREFIX = ~/totempole/NC-Files
INCREMENTS = JOG, 10.000, 1.000, 0.100, 0.010, 0.001
DEFAULT_LINEAR_VELOCITY = 50.0000
MAX_LINEAR_VELOCITY = 180
MIN_LINEAR_VELOCITY = 0.02000
MAX_RAPID_OVERRIDE = 2
DEFAULT_ANGULAR_VELOCITY = 12.0000
MAX_ANGULAR_VELOCITY = 180.0000
MIN_ANGULAR_VELOCITY = 1.6667
GEOMETRY = xyz

[VTK]
# VTK_Widget Options
MACHINE_BOUNDRY = True
MACHINE_TICKS = True
MACHINE_LABELS = False
PROGRAM_BOUNDRY = True
PROGRAM_TICKS = True
PROGRAM_LABELS = False
GRID_LINES = True

[PYTHON]
TOPLEVEL = ./python/toplevel.py
PATH_APPEND = ./python/
PATH_APPEND = ./python/python-stdglue/

[FILTER]
PROGRAM_EXTENSION = .nc,.txt,.tap ; .ngc is always accepted

[RS274NGC]
PARAMETER_FILE = igor.var
RS274NGC_STARTUP_CODE = F10 S300 G21 G17 G40 G49 G54 G64 P0.001 G80 G90 G91.1 G92.1 G94 G97 G98
FEATURES = 12
SUBROUTINE_PATH = ~/linuxcnc/configs/IgorProbe/nc_files/sub_progs/
USER_M_PATH = ~/linuxcnc/configs/IgorProbe/nc_files/
REMAP= M6 modalgroup=6 ngc=toolchange2

[EMCMOT]
EMCMOT = motmod
COMM_TIMEOUT = 1.0
COMM_WAIT = 0.010
BASE_PERIOD = 100000
SERVO_PERIOD = 1000000

[TASK]
TASK = milltask
CYCLE_TIME = 0.010

[HAL]
HALFILE = hallib/core_igor.hal
HALFILE = hallib/xhc-whb04b-6.hal
POSTGUI_HALFILE = hallib/postgui.hal
HALUI = halui

[HALUI]

	MDI_COMMAND=(debug,00)
	MDI_COMMAND=(debug,macro1)
	MDI_COMMAND=(debug,macro2)
	MDI_COMMAND=(debug,macro3)
	MDI_COMMAND=(debug,macro4)  
	MDI_COMMAND=o<go_to_home> call
	MDI_COMMAND=(debug,macro6)
	MDI_COMMAND=o<go_to_workhome> call
	MDI_COMMAND=(debug,macro8)
	MDI_COMMAND=o<probe_z_half> call
	MDI_COMMAND=(debug,macro10)
	MDI_COMMAND=(debug,macro11)
	MDI_COMMAND=(debug,macro12)
	MDI_COMMAND=(debug,macro13)
	MDI_COMMAND=(debug,macro14)
	MDI_COMMAND=(debug,macro15)
	MDI_COMMAND=(debug,macro16)
	MDI_COMMAND=o<go_to_zhome> call
	MDI_COMMAND=(debug,macro18_Spindle_on_of)
	MDI_COMMAND=o<probe_z> call
       # MDI_COMMAND=(debug,macro20)


[TRAJ]
AXES = 3
COORDINATES = X Y Z
LINEAR_UNITS = mm
ANGULAR_UNITS = degree
CYCLE_TIME = 0.010
DEFAULT_LINEAR_VELOCITY = 30.0000
MAX_LINEAR_VELOCITY = 250
MAX_LINEAR_ACCELERATION = 90
SPINDLES = 1
#FORCE_NO_HOMING =       1 #spaeter auskommentiren
POSITION_FILE = position.txt

[EMCIO]
EMCIO = io
CYCLE_TIME = 0.100
TOOL_TABLE = tool.tbl

[KINS]
KINEMATICS = trivkins coordinates=XYZ
JOINTS = 3

#==================
#      X Axis
#==================

[AXIS_X]
MAX_VELOCITY =          333.333333
MAX_ACCELERATION =      130
MIN_LIMIT = -535.0
MAX_LIMIT = 9.0

[JOINT_0]
TYPE = LINEAR
MAX_VELOCITY =          333.333333
MAX_ACCELERATION =      130
BACKLASH =              0.000
FERROR =                0.5
MIN_FERROR =            0.1
ENCODER_SCALE = -1000
OUTPUT_SCALE = 333.333333
OUTPUT_OFFSET =         0.0
OUTPUT_MIN_LIMIT = -333.333333
OUTPUT_MAX_LIMIT = 333.333333
MAX_OUTPUT = 333.333333
MIN_LIMIT = -535.0
MAX_LIMIT = 9.0
HOME_OFFSET = 0.000000
HOME_SEARCH_VEL = -30.000000
HOME_LATCH_VEL = -0.500000
HOME_FINAL_VEL = -0.000000
HOME_SEQUENCE = 1
HOME_USE_INDEX = NO
HOME_IGNORE_LIMITS =    NO

# PID tuning params
DEADBAND =              0.000015
P =                     200
I =                     0
D =                     0
FF0 =                   0
FF1 =                   0.9
FF2 =                   0
BIAS =                  0

#==================
#      Y Axis
#==================

[AXIS_Y]
MAX_VELOCITY =         291.666666
MAX_ACCELERATION =      130
MIN_LIMIT = -295.0
MAX_LIMIT = 9.0

[JOINT_1]
TYPE = LINEAR
MAX_VELOCITY =          291.666666
MAX_ACCELERATION =      130
BACKLASH =              0.000
FERROR =                0.50
MIN_FERROR =            0.10
ENCODER_SCALE = -1000
OUTPUT_SCALE = 290
OUTPUT_OFFSET =         0.0
OUTPUT_MIN_LIMIT = -290
OUTPUT_MAX_LIMIT = 290
MAX_OUTPUT = 290
MIN_LIMIT = -295.0
MAX_LIMIT = 9.0
HOME_OFFSET = 0.000000
HOME_SEARCH_VEL = -30.000000
HOME_LATCH_VEL = -0.500000
HOME_FINAL_VEL = -0.000000
HOME_SEQUENCE = 1
HOME_USE_INDEX = NO
HOME_IGNORE_LIMITS =    NO

# PID tuning params
DEADBAND =              0.000015
P =                     200
I =                     0
D =                     0
FF0 =                   0
FF1 =                   0.9
FF2 =                   0
BIAS =                  0

#==================
#      Z Axis
#==================

[AXIS_Z]
MAX_VELOCITY =          333.333333
MAX_ACCELERATION =      130
MIN_LIMIT = -419.0
MAX_LIMIT = 9.0

[JOINT_2]
YPE = LINEAR
MAX_VELOCITY =          333.333333
MAX_ACCELERATION =      130
BACKLASH =              0.000
FERROR =                0.50
MIN_FERROR =            0.10
ENCODER_SCALE = -1000
OUTPUT_SCALE = 333.333333
OUTPUT_OFFSET =         0.0
OUTPUT_MIN_LIMIT = -333.333333
OUTPUT_MAX_LIMIT = 333.333333
MAX_OUTPUT = 333.333333
MIN_LIMIT = -419.0
MAX_LIMIT = 9.0
HOME_OFFSET = 0.000000
HOME_SEARCH_VEL = -30.000000
HOME_LATCH_VEL = -0.500000
HOME_FINAL_VEL = -0.000000
HOME_SEQUENCE = 1
HOME_USE_INDEX = NO
HOME_IGNORE_LIMITS =    NO

# PID tuning params
DEADBAND =              0.000015
P =                     200
I =                     0
D =                     0
FF0 =                   0
FF1 =                   0.9
FF2 =                   0
BIAS =                  0

HOME = 0.000

#==================
#     Spindle
#==================

[SPINDLE_9]
P = 1I = 0
D = 0
FF0 = 0
FF1 = 0
FF2 = 0
BIAS = 0
DEADBAND = 0
MAX_OUTPUT = 10500
ENCODER_SCALE = 4096
OUTPUT_SCALE = -10500
OUTPUT_MIN_LIMIT = -10500
OUTPUT_MAX_LIMIT = 10500

Ich habe bei mir die Logik das alle Achsen negativ Laufen von der Ursprünglichen Konfiguration der Sinumerik übernommen, daher sind bei mir die Encoder negiert.
Die Hal ist recht umfangreich und wie man hier sieht ist auch inzwischen ein Handrad verbaut. Dazu wird es noch einen eigenen Beitrag geben. Kommen wir jetzt zu den Einzelnen Hal Dateien:

# first load all the RT modules that will be needed
# kinematics
loadrt [KINS]KINEMATICS
# motion controller, get name and thread periods from ini file
loadrt [EMCMOT]EMCMOT base_period_nsec=[EMCMOT]BASE_PERIOD servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS num_spindles=[TRAJ]SPINDLES
loadrt hostmot2
loadrt hm2_eth board_ip="192.168.1.121" config=" num_encoders=6 num_pwmgens=0 num_stepgens=0 sserial_port_0=000xxx sserial_port_1=000xxx"
setp    hm2_7i92.0.watchdog.timeout_ns 5000000
loadrt pid names=pid.x,pid.y,pid.z,pid.s

# classic ladder
loadrt classicladder_rt #numBits=40 numWords=30 numArithmExpr=100
addf classicladder.0.refresh servo-thread
# Load the ladder
#loadusr classicladder powerup.clp
loadusr classicladder --nogui powerup.clp

# estop
loadrt estop_latch count=3
addf estop-latch.0            servo-thread
addf estop-latch.1            servo-thread
addf estop-latch.2            servo-thread

#Spindle ramp
loadrt limit2 names=spindle-ramp
loadrt near names=spindle-atspeed
# add the Spindele functions to a thread
addf spindle-ramp servo-thread
addf spindle-atspeed servo-thread

#and2
loadrt or2 count=1
addf or2.0 servo-thread

# set the parameter for max rate-of-change
# (max spindle accel/decel in units per second)
setp spindle-ramp.maxv 1000

# add motion controller functions to servo thread
addf hm2_7i92.0.read          servo-thread
addf motion-command-handler   servo-thread
addf motion-controller        servo-thread
addf pid.x.do-pid-calcs       servo-thread
addf pid.y.do-pid-calcs       servo-thread
addf pid.z.do-pid-calcs       servo-thread
addf pid.s.do-pid-calcs       servo-thread
addf hm2_7i92.0.write         servo-thread

# external output signals
# 7i71
net o-tool-clean	hm2_7i92.0.7i71.1.1.output-00
net o-tool-01-down	hm2_7i92.0.7i71.1.1.output-01
net o-tool-02-down	hm2_7i92.0.7i71.1.1.output-02
net o-tool-03-down	hm2_7i92.0.7i71.1.1.output-03
net o-tool-04-down	hm2_7i92.0.7i71.1.1.output-04
net o-tool-05-down	hm2_7i92.0.7i71.1.1.output-05
net o-tool-06-down	hm2_7i92.0.7i71.1.1.output-06
net o-tool-07-down	hm2_7i92.0.7i71.1.1.output-07
net o-tool-08-down	hm2_7i92.0.7i71.1.1.output-08
net o-tool-09-down	hm2_7i92.0.7i71.1.1.output-09
net o-tool-10-down	hm2_7i92.0.7i71.1.1.output-10
net o-tool-11-down	hm2_7i92.0.7i71.1.1.output-11
net o-tool-12-down	hm2_7i92.0.7i71.1.1.output-12
net o-tool-basket-down	hm2_7i92.0.7i71.1.1.output-13
net o-tool-basket-up	hm2_7i92.0.7i71.1.1.output-14
net o-tool-open   	hm2_7i92.0.7i71.1.1.output-15
net o-tool-all-up   	hm2_7i92.0.7i71.1.1.output-16
net o-steuerung-1	hm2_7i92.0.7i71.1.1.output-18
net o-impulsfreigabe	hm2_7i92.0.7i71.1.1.output-17
net o-pump-1		hm2_7i92.0.7i71.1.1.output-19
net o-airpressure-1	hm2_7i92.0.7i71.1.1.output-20
net o-chiptransport	hm2_7i92.0.7i71.1.1.output-21
net o-pump-2		hm2_7i92.0.7i71.1.1.output-22
net o-power-drives	hm2_7i92.0.7i71.1.1.output-23
net o-power-drives-delay	hm2_7i92.0.7i71.1.1.output-24
#bei Transport auskommentieren
net o-brake-z		hm2_7i92.0.7i71.1.1.output-25
#/bei Transport auskommentieren
net o-pump-3		hm2_7i92.0.7i71.1.1.output-27

# --- SPINDLE-ENABLE ---
#net spindle-enable 	hm2_7i92.0.7i71.1.1.output-26
net o-impulsfreigabe  	 hm2_7i92.0.7i71.1.1.output-26
net spindle-enable      hm2_7i92.0.7i77.0.0.output-01	

# --- Table-Out ---
net o-table-up		hm2_7i92.0.7i71.1.1.output-28
net o-table-lock	hm2_7i92.0.7i71.1.1.output-29
net o-table-2		hm2_7i92.0.7i71.1.1.output-30
net o-table-1		hm2_7i92.0.7i71.1.1.output-31

net  error1		hm2_7i92.0.7i71.1.1.output-32
net enable1		hm2_7i92.0.7i71.1.1.output-33
# --- COOLANT-FLOOD ---
net coolant-flood 	hm2_7i92.0.7i71.1.1.output-34

net o-dummy35 	hm2_7i92.0.7i71.1.1.output-35
net o-dummy36	hm2_7i92.0.7i71.1.1.output-36
#---clean-probe
net o-probe-clean	hm2_7i92.0.7i71.1.1.output-37

# --- COOLANT-MIST ---
net coolant-mist	hm2_7i92.0.7i71.1.1.output-38

#---- NOT CONNECTED ----
net o-dummy39	hm2_7i92.0.7i71.1.1.output-39
net o-dummy40	hm2_7i92.0.7i71.1.1.output-40
net o-dummy41	hm2_7i92.0.7i71.1.1.output-41
net o-dummy42	hm2_7i92.0.7i71.1.1.output-42
net o-dummy43	hm2_7i92.0.7i71.1.1.output-43
#net o-dummy44	hm2_7i92.0.7i71.1.1.output-44

#bei Transport auskommentieren
net z-enable	hm2_7i92.0.7i71.1.1.output-45
net y-enable	hm2_7i92.0.7i71.1.1.output-46
net x-enable	hm2_7i92.0.7i71.1.1.output-47
#/bei Transport auskommentieren

#7i77

# --- SPINDLE-BRAKE ---
#net spindle-brake hm2_7i92.0.7i77.0.0.output-05

net o-power-drives-delay hm2_7i92.0.7i77.0.0.output-00

#---- NOT CONNECTED ----
net o-2dummy02	hm2_7i92.0.7i77.0.0.output-02
net o-2dummy03	hm2_7i92.0.7i77.0.0.output-03
net o-2dummy04	hm2_7i92.0.7i77.0.0.output-04
net o-2dummy05	hm2_7i92.0.7i77.0.0.output-05
net o-2dummy06	hm2_7i92.0.7i77.0.0.output-06
net o-2dummy07	hm2_7i92.0.7i77.0.0.output-07
net o-2dummy08	hm2_7i92.0.7i77.0.0.output-08
net o-2dummy09	hm2_7i92.0.7i77.0.0.output-09
net o-2dummy10	hm2_7i92.0.7i77.0.0.output-10
net o-2dummy11	hm2_7i92.0.7i77.0.0.output-11
net o-2dummy12	hm2_7i92.0.7i77.0.0.output-12
net o-2dummy13	hm2_7i92.0.7i77.0.0.output-13
net o-2dummy14	hm2_7i92.0.7i77.0.0.output-14
net o-2dummy15	hm2_7i92.0.7i77.0.0.output-15

# external input signals
# 7i70
net i-tool-03-is-up	hm2_7i92.0.7i70.1.0.input-00
net i-tool-03-is-down	hm2_7i92.0.7i70.1.0.input-01
net i-tool-02-is-up	hm2_7i92.0.7i70.1.0.input-02
net i-tool-02-is-down	hm2_7i92.0.7i70.1.0.input-03
net i-tool-01-is-up	hm2_7i92.0.7i70.1.0.input-04
net i-tool-01-is-down	hm2_7i92.0.7i70.1.0.input-05
net i-tool-12-is-up	hm2_7i92.0.7i70.1.0.input-06
net i-tool-12-is-down	hm2_7i92.0.7i70.1.0.input-07
net i-tool-05-is-down	hm2_7i92.0.7i70.1.0.input-08
net i-tool-05-is-up	hm2_7i92.0.7i70.1.0.input-09
net i-tool-04-is-up	hm2_7i92.0.7i70.1.0.input-10
net i-tool-10-is-down	hm2_7i92.0.7i70.1.0.input-12
net i-tool-is-open	hm2_7i92.0.7i70.1.0.input-11
net i-tool-10-is-up	hm2_7i92.0.7i70.1.0.input-13
net i-tool-11-is-down	hm2_7i92.0.7i70.1.0.input-14
net i-tool-11-is-up	hm2_7i92.0.7i70.1.0.input-15
net i-tool-09-is-down	hm2_7i92.0.7i70.1.0.input-16
net i-tool-09-is-up	hm2_7i92.0.7i70.1.0.input-17
net i-tool-08-is-down	hm2_7i92.0.7i70.1.0.input-18
net i-tool-08-is-up	hm2_7i92.0.7i70.1.0.input-19
net i-tool-07-is-down	hm2_7i92.0.7i70.1.0.input-20
net i-tool-07-is-up	hm2_7i92.0.7i70.1.0.input-21
net i-tool-06-is-down	hm2_7i92.0.7i70.1.0.input-22
net i-tool-06-is-up	hm2_7i92.0.7i70.1.0.input-23
net i-door-1-open	hm2_7i92.0.7i70.1.0.input-24
net i-steuerung-ein	hm2_7i92.0.7i70.1.0.input-25
net i-power-io		hm2_7i92.0.7i70.1.0.input-26
net i-tool-04-is-down   hm2_7i92.0.7i70.1.0.input-27
net i-tool-basket-is-down	hm2_7i92.0.7i70.1.0.input-30
net i-tool-basket-is-up	hm2_7i92.0.7i70.1.0.input-31
net i-door-1-closed	hm2_7i92.0.7i70.1.0.input-32
net i-door-2-open	hm2_7i92.0.7i70.1.0.input-33
net i-door-2-closed	hm2_7i92.0.7i70.1.0.input-34
net i-door-3		hm2_7i92.0.7i70.1.0.input-35
net i-table-is-lock	hm2_7i92.0.7i70.1.0.input-36
net i-table-is-up	hm2_7i92.0.7i70.1.0.input-37
net i-table-is-1	hm2_7i92.0.7i70.1.0.input-38
net i-table-is-2	hm2_7i92.0.7i70.1.0.input-39

# --- HOME-Z ---
net home-x     hm2_7i92.0.7i70.1.0.input-40
net home-y     hm2_7i92.0.7i70.1.0.input-29
net home-z     hm2_7i92.0.7i70.1.0.input-28

# --- A Axis ---- NOT CONNECTED ----
net home-a      hm2_7i92.0.7i70.1.0.input-41
net i-setup-a	hm2_7i92.0.7i70.1.0.input-42

#---- NOT CONNECTED ----
net i-dummy43	hm2_7i92.0.7i70.1.0.input-43
net i-dummy44	hm2_7i92.0.7i70.1.0.input-44
net i-dummy45	hm2_7i92.0.7i70.1.0.input-45
net i-dummy46	hm2_7i92.0.7i70.1.0.input-46
net i-dummy47	hm2_7i92.0.7i70.1.0.input-47

#7i77

net i-brake-z-is-on	hm2_7i92.0.7i77.0.0.input-00
net i-machine-ready	hm2_7i92.0.7i77.0.0.input-01

# --- MAX-X ---
net max-x     <=  hm2_7i92.0.7i77.0.0.input-02
net max-x-n	<=  hm2_7i92.0.7i77.0.0.input-02-not
# --- MAX-Y ---
net max-y     <=  hm2_7i92.0.7i77.0.0.input-03
net max-y-n     <=  hm2_7i92.0.7i77.0.0.input-03-not

# --- MAX-Z ---
net max-z     <=  hm2_7i92.0.7i77.0.0.input-04
net max-z-n-1     <=  hm2_7i92.0.7i77.0.0.input-04-not
# --- E-Stop input---
net estop-button        hm2_7i92.0.7i77.0.0.input-06-not
net i-pressure-ok	hm2_7i92.0.7i77.0.0.input-05-not
net i-temp-bimetall	hm2_7i92.0.7i77.0.0.input-07-not
net i-temp		hm2_7i92.0.7i77.0.0.input-08-not

# --- E-STOP CHAIN STARTS ---
net latch-ok-in iocontrol.0.user-enable-out 
net latch-ok-in => estop-latch.0.ok-in
net latch0-out <= estop-latch.0.ok-out 
net latch0-out => estop-latch.1.ok-in
net latch1-out <= estop-latch.1.ok-out 
net latch1-out => estop-latch.2.ok-in
net reset => estop-latch.0.reset
net reset => estop-latch.1.reset
net reset => estop-latch.2.reset
net latch-out iocontrol.0.emc-enable-in <= estop-latch.2.ok-out
net estop-out estop-latch.2.fault-out
# --- EXTERNAL ESTOP SWITCH ---
net estop-button => estop-latch.0.fault-in
# --- Airpressure low E-Stop ---
net i-pressure-ok => estop-latch.1.fault-in 
# --- Overheating E-STOP ---
net i-temp-bimetall => estop-latch.2.fault-in
# --- ESTOP CHAIN ENDS ---
#Ladder
# --- MACHINE-IS-ENABLED ---
net machine-is-enabled	classicladder.0.in-00
net i-steuerung-ein	classicladder.0.in-01
# --- ladder-out
net o-impulsfreigabe 	<= classicladder.0.out-02
net o-steuerung-1	<= classicladder.0.out-01
net o-power-drives	<= classicladder.0.out-04
net o-power-drives-delay <= classicladder.0.out-05
net o-brake-z 		<= classicladder.0.out-06



net i-unknown1	hm2_7i92.0.7i77.0.0.input-09
net i-unkown2	hm2_7i92.0.7i77.0.0.input-10
net i-servo	hm2_7i92.0.7i77.0.0.input-11
net i-spindle	hm2_7i92.0.7i77.0.0.input-12
net i-2dummy13	hm2_7i92.0.7i77.0.0.input-13
net i-2dummy14	hm2_7i92.0.7i77.0.0.input-14
net i-2dummy15	hm2_7i92.0.7i77.0.0.input-15
#********************
#Iputs in Ganty START
#********************
net i-toolsensor-1  	hm2_7i92.0.7i77.0.0.input-16
net i-toolsensor-2  	hm2_7i92.0.7i77.0.0.input-17
net max-z-n-2  	hm2_7i92.0.7i77.0.0.input-17-not
net i-toolsensor      hm2_7i92.0.7i77.0.0.input-16-not
net i-toolsensor        motion.probe-input
net i-2dummy18  	hm2_7i92.0.7i77.0.0.input-18
net i-2dummy19	        hm2_7i92.0.7i77.0.0.input-19
net i-2dummy20  	hm2_7i92.0.7i77.0.0.input-20
net i-2dummy21	        hm2_7i92.0.7i77.0.0.input-21
net i-2dummy22	        hm2_7i92.0.7i77.0.0.input-22
net i-ganty-powergood	hm2_7i92.0.7i77.0.0.input-23
#********************
#Iputs in Ganty END
#********************
net i-2dummy24	hm2_7i92.0.7i77.0.0.input-24
net i-2dummy25	hm2_7i92.0.7i77.0.0.input-25
net i-2dummy26	hm2_7i92.0.7i77.0.0.input-26
net i-2dummy27	hm2_7i92.0.7i77.0.0.input-27
net i-2dummy28	hm2_7i92.0.7i77.0.0.input-28
net i-2dummy29	hm2_7i92.0.7i77.0.0.input-29
net i-2dummy30	hm2_7i92.0.7i77.0.0.input-30
net i-2dummy31	hm2_7i92.0.7i77.0.0.input-31
#********************
#Z-Limit logic
#********************
net max-y-n-1   or2.0.in0
net max-z-n-2   or2.0.in1
net max-z-n     or2.0.out
#*******************
#  JOINT X
#*******************
setp   pid.x.Pgain     [JOINT_0]P
setp   pid.x.Igain     [JOINT_0]I
setp   pid.x.Dgain     [JOINT_0]D
setp   pid.x.bias      [JOINT_0]BIAS
setp   pid.x.FF0       [JOINT_0]FF0
setp   pid.x.FF1       [JOINT_0]FF1
setp   pid.x.FF2       [JOINT_0]FF2
setp   pid.x.deadband  [JOINT_0]DEADBAND
setp   pid.x.maxoutput [JOINT_0]MAX_OUTPUT
setp   pid.x.error-previous-target true

net x-index-enable  <=> pid.x.index-enable
net x-enable        =>  pid.x.enable
net x-pos-cmd       =>  pid.x.command
#net x-vel-cmd       =>  pid.x.command-deriv
net x-pos-fb        =>  pid.x.feedback
net x-output        =>  pid.x.output

# ---PWM Generator signals/setup---

setp   hm2_7i92.0.7i77.0.1.analogout0-scalemax  [JOINT_0]OUTPUT_SCALE
setp   hm2_7i92.0.7i77.0.1.analogout0-minlim    [JOINT_0]OUTPUT_MIN_LIMIT
setp   hm2_7i92.0.7i77.0.1.analogout0-maxlim    [JOINT_0]OUTPUT_MAX_LIMIT

net x-output                             => hm2_7i92.0.7i77.0.1.analogout0
net x-pos-cmd    joint.0.motor-pos-cmd
net x-enable     joint.0.amp-enable-out
# enable _all_ sserial pwmgens
net x-enable   hm2_7i92.0.7i77.0.1.analogena

# ---Encoder feedback signals/setup---

setp    hm2_7i92.0.encoder.00.counter-mode 0
setp    hm2_7i92.0.encoder.00.filter 1
setp    hm2_7i92.0.encoder.00.index-invert 0
setp    hm2_7i92.0.encoder.00.index-mask 0
setp    hm2_7i92.0.encoder.00.index-mask-invert 0
setp    hm2_7i92.0.encoder.00.scale  [JOINT_0]ENCODER_SCALE

net x-pos-fb               <=  hm2_7i92.0.encoder.00.position
net x-vel-fb               <=  hm2_7i92.0.encoder.00.velocity
net x-pos-fb               =>  joint.0.motor-pos-fb
net x-index-enable    joint.0.index-enable  <=>  hm2_7i92.0.encoder.00.index-enable
net x-pos-rawcounts        <=  hm2_7i92.0.encoder.00.rawcounts

# ---setup home / limit switch signals---

net home-x     =>  joint.0.home-sw-in
net max-x-n     =>  joint.0.neg-lim-sw-in
net max-x-n     =>  joint.0.pos-lim-sw-in

#*******************
#  JOINT Y
#*******************

setp   pid.y.Pgain     [JOINT_1]P
setp   pid.y.Igain     [JOINT_1]I
setp   pid.y.Dgain     [JOINT_1]D
setp   pid.y.bias      [JOINT_1]BIAS
setp   pid.y.FF0       [JOINT_1]FF0
setp   pid.y.FF1       [JOINT_1]FF1
setp   pid.y.FF2       [JOINT_1]FF2
setp   pid.y.deadband  [JOINT_1]DEADBAND
setp   pid.y.maxoutput [JOINT_1]MAX_OUTPUT
setp   pid.y.error-previous-target true

net y-index-enable  <=> pid.y.index-enable
net y-enable        =>  pid.y.enable
net y-pos-cmd       =>  pid.y.command
#net y-vel-cmd       =>  pid.y.command-deriv
net y-pos-fb        =>  pid.y.feedback
net y-output        =>  pid.y.output

# ---PWM Generator signals/setup---

setp   hm2_7i92.0.7i77.0.1.analogout1-scalemax  [JOINT_1]OUTPUT_SCALE
setp   hm2_7i92.0.7i77.0.1.analogout1-minlim    [JOINT_1]OUTPUT_MIN_LIMIT
setp   hm2_7i92.0.7i77.0.1.analogout1-maxlim    [JOINT_1]OUTPUT_MAX_LIMIT

net y-output                             => hm2_7i92.0.7i77.0.1.analogout1
net y-pos-cmd    joint.1.motor-pos-cmd
net y-enable     joint.1.amp-enable-out

# ---Encoder feedback signals/setup---

setp    hm2_7i92.0.encoder.01.counter-mode 0
setp    hm2_7i92.0.encoder.01.filter 1
setp    hm2_7i92.0.encoder.01.index-invert 0
setp    hm2_7i92.0.encoder.01.index-mask 0
setp    hm2_7i92.0.encoder.01.index-mask-invert 0
setp    hm2_7i92.0.encoder.01.scale  [JOINT_1]ENCODER_SCALE

net y-pos-fb               <=  hm2_7i92.0.encoder.01.position
net y-vel-fb               <=  hm2_7i92.0.encoder.01.velocity
net y-pos-fb               =>  joint.1.motor-pos-fb
net y-index-enable    joint.1.index-enable  <=>  hm2_7i92.0.encoder.01.index-enable
net y-pos-rawcounts        <=  hm2_7i92.0.encoder.01.rawcounts

# ---setup home / limit switch signals---

net home-y     =>  joint.1.home-sw-in
net max-y-n     =>  joint.1.neg-lim-sw-in
net max-y-n     =>  joint.1.pos-lim-sw-in

#*******************
#  JOINT Z
#*******************

setp   pid.z.Pgain     [JOINT_2]P
setp   pid.z.Igain     [JOINT_2]I
setp   pid.z.Dgain     [JOINT_2]D
setp   pid.z.bias      [JOINT_2]BIAS
setp   pid.z.FF0       [JOINT_2]FF0
setp   pid.z.FF1       [JOINT_2]FF1
setp   pid.z.FF2       [JOINT_2]FF2
setp   pid.z.deadband  [JOINT_2]DEADBAND
setp   pid.z.maxoutput [JOINT_2]MAX_OUTPUT
setp   pid.z.error-previous-target true

net z-index-enable  <=> pid.z.index-enable
net z-enable        =>  pid.z.enable
net z-pos-cmd       =>  pid.z.command
#net z-vel-cmd       =>  pid.z.command-deriv
net z-pos-fb        =>  pid.z.feedback
net z-output        =>  pid.z.output  

# ---PWM Generator signals/setup---

setp   hm2_7i92.0.7i77.0.1.analogout2-scalemax  [JOINT_2]OUTPUT_SCALE
setp   hm2_7i92.0.7i77.0.1.analogout2-minlim    [JOINT_2]OUTPUT_MIN_LIMIT
setp   hm2_7i92.0.7i77.0.1.analogout2-maxlim    [JOINT_2]OUTPUT_MAX_LIMIT

net z-output     => hm2_7i92.0.7i77.0.1.analogout2
net z-pos-cmd    joint.2.motor-pos-cmd
net z-enable     joint.2.amp-enable-out

# ---Encoder feedback signals/setup---

setp    hm2_7i92.0.encoder.02.counter-mode 0
setp    hm2_7i92.0.encoder.02.filter 1
setp    hm2_7i92.0.encoder.02.index-invert 0
setp    hm2_7i92.0.encoder.02.index-mask 0
setp    hm2_7i92.0.encoder.02.index-mask-invert 0
setp    hm2_7i92.0.encoder.02.scale  [JOINT_2]ENCODER_SCALE

net z-pos-fb               <=  hm2_7i92.0.encoder.02.position
net z-vel-fb               <=  hm2_7i92.0.encoder.02.velocity
net z-pos-fb               =>  joint.2.motor-pos-fb
net z-index-enable    joint.2.index-enable  <=>  hm2_7i92.0.encoder.02.index-enable
net z-pos-rawcounts        <=  hm2_7i92.0.encoder.02.rawcounts

# ---setup home / limit switch signals---

net home-z     =>  joint.2.home-sw-in
net max-z-n     =>  joint.2.neg-lim-sw-in
net max-z-n     =>  joint.2.pos-lim-sw-in

#*******************
#  SPINDLE S
#*******************

setp   pid.s.Pgain     [SPINDLE_9]P
setp   pid.s.Igain     [SPINDLE_9]I
setp   pid.s.Dgain     [SPINDLE_9]D
setp   pid.s.bias      [SPINDLE_9]BIAS
setp   pid.s.FF0       [SPINDLE_9]FF0
setp   pid.s.FF1       [SPINDLE_9]FF1
setp   pid.s.FF2       [SPINDLE_9]FF2
setp   pid.s.deadband  [SPINDLE_9]DEADBAND
setp   pid.s.maxoutput [SPINDLE_9]MAX_OUTPUT
setp   pid.s.error-previous-target true

net spindle-index-enable  <=> pid.s.index-enable
net spindle-enable        =>  pid.s.enable
#net spindle-vel-cmd-rpm     => pid.s.command
# the output of spindle ramp is sent to the scale in
net spindle-ramped <= spindle-ramp.out => => pid.s.command
net spindle-vel-fb-rpm      => pid.s.feedback
net spindle-output        <=  pid.s.output

# ---PWM Generator signals/setup---

setp   hm2_7i92.0.7i77.0.1.analogout4-scalemax  [SPINDLE_9]OUTPUT_SCALE
setp   hm2_7i92.0.7i77.0.1.analogout4-minlim    [SPINDLE_9]OUTPUT_MIN_LIMIT
setp   hm2_7i92.0.7i77.0.1.analogout4-maxlim    [SPINDLE_9]OUTPUT_MAX_LIMIT

net spindle-output      => hm2_7i92.0.7i77.0.1.analogout4

# ---Encoder feedback signals/setup---

setp    hm2_7i92.0.encoder.05.counter-mode 0
setp    hm2_7i92.0.encoder.05.filter 1
setp    hm2_7i92.0.encoder.05.index-invert 0
setp    hm2_7i92.0.encoder.05.index-mask 0
setp    hm2_7i92.0.encoder.05.index-mask-invert 0
setp    hm2_7i92.0.encoder.05.scale  [SPINDLE_9]ENCODER_SCALE

net spindle-revs             <=   hm2_7i92.0.encoder.05.position
net spindle-vel-fb-rps       <=   hm2_7i92.0.encoder.05.velocity
net spindle-index-enable     <=>  hm2_7i92.0.encoder.05.index-enable

# ---setup spindle control signals---

net spindle-vel-cmd-rps        <=  spindle.0.speed-out-rps
net spindle-vel-cmd-rps-abs    <=  spindle.0.speed-out-rps-abs
net spindle-vel-cmd-rpm        <=  spindle.0.speed-out
net spindle-vel-cmd-rpm-abs    <=  spindle.0.speed-out-abs
net spindle-enable             <=  spindle.0.on
net spindle-cw                 <=  spindle.0.forward
net spindle-ccw                <=  spindle.0.reverse
net spindle-brake              <=  spindle.0.brake
net spindle-revs               =>  spindle.0.revs
#net spindle-at-speed           =>  spindle.0.at-speed
net spindle-vel-fb-rps         =>  spindle.0.speed-in
net spindle-index-enable      <=>  spindle.0.index-enable

# hijack the spindle speed out and send it to spindle ramp in
net spindle-vel-cmd-rpm => spindle-ramp.in
# to know when to start the motion we send the near component
# (named spindle-at-speed) to the spindle commanded speed from
# the signal spindle-cmd and the actual spindle speed
# provided your spindle can accelerate at the maxv setting.
net spindle-vel-cmd-rpm => spindle-atspeed.in1
net spindle-ramped => spindle-atspeed.in2
#net spindle-vel-fb-rpm => spindle-atspeed.in2
# ---Setup spindle at speed signals---
# the output from spindle-at-speed is sent to motion.spindle-at-speed
# and when this is true motion will start
net spindle-at-speed <= spindle-atspeed.out => spindle.0.at-speed
#sets spindle-at-speed true


#******************************
# connect miscellaneous signals
#******************************

#  ---HALUI signals---

net axis-select-x  halui.axis.x.select
net jog-x-pos      halui.axis.x.plus
net jog-x-neg      halui.axis.x.minus
net jog-x-analog   halui.axis.x.analog
net x-is-homed     halui.joint.0.is-homed
net axis-select-y  halui.axis.y.select
net jog-y-pos      halui.axis.y.plus
net jog-y-neg      halui.axis.y.minus
net jog-y-analog   halui.axis.y.analog
net y-is-homed     halui.joint.1.is-homed
net axis-select-z  halui.axis.z.select
net jog-z-pos      halui.axis.z.plus
net jog-z-neg      halui.axis.z.minus
net jog-z-analog   halui.axis.z.analog
net z-is-homed     halui.joint.2.is-homed
net jog-selected-pos      halui.axis.selected.plus
net jog-selected-neg      halui.axis.selected.minus
#aenderungen
net spindle-manual-cw     halui.spindle.0.forward
net spindle-manual-ccw    halui.spindle.0.reverse
net spindle-manual-stop   halui.spindle.0.stop
#net machine-is-on         halui.machine.is-on
#Probe
#net spindle-fwd spindle.0.forward
#net spindle-rev spindle.0.reverse
#net spindle-speed spindle.0.speed-out

net jog-speed             halui.axis.jog-speed
net MDI-mode              halui.mode.is-mdi

#  ---coolant signals---

net coolant-mist      <=  iocontrol.0.coolant-mist
net coolant-flood     <=  iocontrol.0.coolant-flood
#probe
#net lube iocontrol.0.lube
#net flood iocontrol.0.coolant-flood
#net mist iocontrol.0.coolant-mist

#  ---motion control signals---
net in-position               <=  motion.in-position
net machine-is-enabled        <=  motion.motion-enabled
#  ---tool change signals---
net tool-change-confirmed   iocontrol.0.tool-changed      <=  iocontrol.0.tool-change
net tool-prepare-loopback   iocontrol.0.tool-prepare      =>  iocontrol.0.tool-prepared

Postgui Hal:

#E-stop
net reset <= qtpyvcp.hb1.out
net reset => qtpyvcp.led4.on
net estop-button     	=> qtpyvcp.led1.on
net i-pressure-ok	=> qtpyvcp.led2.on
net i-temp-bimetall	=> qtpyvcp.led3.on
net latch-out           => qtpyvcp.led5.on

Was noch Fehlt ist die Startsequenz der Servotreiber und der Spindel das habe ich über eine Ladder gelöst:


Ladder für das Starten der Spindel und Servotreiber

Damit ist alles umgesetzt, das benötigt wird die Maschine in Bewegung zu setzten. Es Fehlen noch diverse Programme zum Steuern der einzelnen Komponenten. Doch dazu kommen wir später.

Linuxcnc Retrofit von Igor Teil 3 Installation und Firmware

Es gab hier diverse Ansätze und auch immer wieder Sackgassen oder Projekte, die ich angefangen und über Bord geworfen habe. Angefangen habe ich mit gmocappy als VCP bin inzwischen aber bei qtpyvcp bzw. Probe Basic angekommen, das auf qtpyvcp basiert.

Fangen wir an mit der Installation von linuxcnc. Hier die Version, die am schnellsten funktioniert hat:

http://www.linuxcnc.org/testing-stretch-rtpreempt/

Passende Iso aus suchen, runter laden und auf einen USB Stick flashen. Nach der Installation geht es dann weiter. Ich habe linuxcnc auf version 2.8 gehoben:

sudo apt-get update
sudo apt-get dist-upgrade
sudo apt-get install dirmngr
sudo apt-get install software-properties-common
sudo apt-key adv --keyserver hkp://keys.gnupg.net --recv-key E0EE663E
sudo add-apt-repository "deb http://buildbot.linuxcnc.org/ stretch 2.8-rtpreempt"
sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
sudo apt install python-pyqt5 python-pyqt5.qtquick python-dbus.mainloop.pyqt5 python-pyqt5.qtopengl python-pyqt5.qsci python-pyqt5.qtmultimedia qml-module-qtquick-controls gstreamer1.0-plugins-bad libqt5multimedia5-plugins pyqt5-dev-tools python-dev python-setuptools python-pip git apt install qttools5.dev qttools5-dev-tools python-pip locate mc build-essential autoconf glib* pkg-config libmodbus-dev libusb-1.0-0-dev glib glib-dev libc libc-dev libgtk2.0 libgtk2.0-dev yapps2 intltool-extract intltool tcl-dev tk-dev libreadline-gplv2-dev libboost-python-dev Xmu Xmu-dev libxmu libxmu-headers libxmu* autoconf

Damit müsste eigentlich alles installiert sein, was benötigt wird um Linuxcnc mit Probe Basic ans laufen zu bekommen und noch etwas mehr. Was folgt ist die Installation von qtpyvcp und ein Neustart

git clone https://github.com/kcjengr/qtpyvcp qtpyvcp
cd qtpyvcp
pip install --editable .
cd ~/qtpyvcp/pyqt5designer/Qt5.7.1-64bit/
sudo ./install.sh
cp ~/qtpyvcp/scripts/.xsessionrc ~/
sudo reboot

Nach dem Neustart geht es an Probe Basic:

git clone https://github.com/kcjengr/probe_basic.git
cd probe_basic/
pip install -e .
cp -r ~/probe_basic/probe_basic/fonts/ ~/.local/share/
cp -r ~/probe_basic/config/probe_basic/ ~/linuxcnc/configs/

Damit sind die ersten Installationen abgeschlossen. Wir haben ein Linux mit Echtzeit-Kernel und Linuxcnc. Den ganzen Latenzkram hatte ich schon lit nem live system getestet und das ist eigentlich recht gut beschreiben, daher machen wir mit den Mesa Karten weiter. Meine Mesakarte wird per Ethernet angesprochen also musste zunächst eine Netzwerk Karte dafür reserviert werden. Ich verwende die Standard-IP der 7i92 (192.168.1.121) die Netzwerkschnittstelle wurde manuell konfiguriert und auf RT umbenannt, IPv4 manual, 192.168.1.100 mit netmask 255.255.255.2 und gateway 192.168.1.100 eingestellt. IPv6 wird auf ignore gestellt. Wenn alle Kabel und Jumper überprüft sind, kann man die Stromversorgung einschalten. Danach sollte sich Lunux schon mal melden, dass RT verbunden wurde.

ping 192.168.1.121 
PING 192.168.1.121 (192.168.1.121) 56(84) bytes of data.
64 bytes from 192.168.1.121: icmp_seq=1 ttl=64 time=0.577 ms
64 bytes from 192.168.1.121: icmp_seq=2 ttl=64 time=0.338 ms
64 bytes from 192.168.1.121: icmp_seq=3 ttl=64 time=0.313 ms
64 bytes from 192.168.1.121: icmp_seq=4 ttl=64 time=0.361 ms


Damit ist die erste Kontaktaufnahme geglückt. Jetzt muss die Mesa 7I92 noch geflashed werden. Die passenden Software gibt es von Mesa:

http://www.mesanet.com/software/parallel/7i92.zip

Das ganze auspacken und dann die passende Firmware raus suchen in meinem Fall mit der Default IP und 7i77 und 7i72 Bords die Firmware 7i92_7i77_7i74D.bit

cd ~/Downloads/7i92/utils/linux/ 
chmod +x mesaflash 
sudo ./mesaflash --device 7i92 --write ../../configs/7i92_7i77_7i74D.bit 
sudo ./mesaflash --device 7i92 --verify ../../configs/7i92_7i77_7i74D.bit

Damit sind alle Grundvoraussetzungen erfüllt, das wir mit der Konfiguration starten können.

Linuxcnc Retrofit von Igor Teil 2 die Hardware

Nachdem das grundlegende Konzept fest steht geht es an die Umsetzung. Dazu werden zunächst die I/O’s und Encoder um zu legen. Dazu wurden zunächst Schnittstellen und neue Zuordnungen lokalisiert und in Tabellen eingetragen.

Damit waren die Vorbereitungen der Hardware außerhalb der Maschine abgeschlossen. Die nächsten Schritte waren das ziehen von Netzwerkkabeln um die Seriellen Schnittstellen im Schaltschrank mit der Konsole zu verbinden und um ggf. einen Netzwerkanschluss für den Steuerrechner bereit stellen zu können. Außerdem bekam die Konsole eine eigne 220V Stromkreis für den Steuerrechner, Monitor, 5V Netzteil und Servicesteckdose.

Danach war es an der Zeit die vorläufige Frontplatte zu machen und den Steuerrechner ein zu bauen. Außerdem wurden ein Notaus-Knopf und ein Schalter für die 5V Stromversorgung der FPGA Karten eingebaut.

Damit waren die Vorbereitungen der Hardware abgeschlossen. Als nächstes kommt dann die Software.

Ok ganz so linear war es nicht zwischen beginn des Umbaus und dem Abschluss des Umbaus lag immerhin ein Umzug und auch zwischendurch wurde an der Software gearbeitet aber so lässt es sich besser aufteilen. Aber Überraschenderweise lieft der Umbau der Hardware deutlich glatter als gedacht, die akribische Vorarbeit und Dokumentation haben dazu geführt, dass bis auf Kleinigkeiten, die den undokumentierten umbauten der Maschine Geschuldet waren alles rech schnell lief. Auch die Videos der Relais während des Einschaltprozesses haben sich später bei der Umsetzung der Software bewährt. Doch dazu mehr in Teil 3

Linuxcnc Retrofit von Igor Teil 1

Es war ja sehr lange still hier im Blog. Der Grund dafür liegt in der Tatsache, das ich umgezogen bin und damit viel Zeit für die Renovierung der Neuen Heimat drauf geht. Der 2. während der Zeit habe ich auch meiner Chiron FZ12W eine neue Steuerung verpasst habe. Die alte Sinumerik 810M durfte gehen und als “neues Hirn” für Igor kamen Mesa Karten und ein kleiner PC mit Linuxcnc als Betriebssystem.

Das ganze vorhaben ist dem Wunsch nach mehr Speicher geschuldet. Anfangs war das Projekt so geplant es möglichst minimal zu machen um, falls es nicht klappt schnell wieder zurück bauen zu können. Das habe ich aber dann Teilweise über Bord geworfen. Doch kommen wir zunächst zur Planung.
Ich hatte zum Glück die Schaltpläne der Chiron, leider gab es ein paar undokumentierte Umbauten. Aber das ließ sich alles “durchklingeln”.
Die Ein- und Ausgänge lagen entweder aus Wannensteckern oder auf D-Sub Steckern. Was den Umbau erleichtert, wenn man auf Adapterplatinen setzt. Das ist zwar hinten im Schaltschrank redundant, da hier die Kabel über einen Adapter auf ein Flachbandkabel gelegt werden und dann von dem Flachbandkabel wieder auf einen Adapter, dann auf Kabel und dann in die Klemmleisten der Mesa Karten. Aber so ließe sich dann alles schnell wieder zurück bauen. Und man muss nicht alle Kabel mühsam umlegen.
Aber bevor es los ging heiß es erst mal alle Ein- und Ausgänge, Dokumentieren. Um eine passende Auswahl an Karten zu machen. Meine Wahl fiel dann auf folgendes Setup:
Zunächst die Karten, die in die alte Steuerkonsole eingebaut werden:
1. Mesa 7I92H Anything I/O Ethernet card. Dadurch wurde ich in der Wahl des Mainbords flexibler und es lässt sich leichter auf einen anderen Rechner wechseln. Diese FPGA Karte übernimmt nur die Kommunikation zwischen Rechner und den IO’s.
2. Mesa 7I77 Analog servo interface plus I/O daughtercard. Diese Karte verarbeitet die Encoder und übernimmt die Analoge Steuerung der Servotreiber und Spineln. Außerdem hat sie Digitale I/O’s mit der sich die I/O’s schalten lassen, die schon in der Konsole liegen.
3. Mesa 7I74 Eight Channel RS-422/485 interface/ RJ45 Breakout. Mit der Karte kann ich weitere Serielle Karten ansteuern, die hinten in den Schaltschrank kommen.
Damit kommen wir zu den Karten im Schaltschrank:
4. Mesa 7I71 Isolated remote power driver card. Mit der Karte werden alle digitalen Ausgänge geschaltet.
5. Mesa 7I70 Isolated remote digital input card. Mit der Karte werden die Eingänge überwacht.
so weit so gut. Zu dem Rechner habe ich noch einen touchfähigen Monitor spendiert, dadurch stört es auch nicht weiter, dass ich mit der Sinumerik auch alle Bedienelemente ausgebaut habe.
Damit sind die Eckdaten schon mal fest gelegt. Im Nächten Teil beginnt dann die Umsetzung.

Linuxcnc Retrofit von Igor Teil 2 die Hardware

Ein Kardiertier….

Ich hatte Claudia schon vor längerer Zeit versprochen, ihr eine Karde zu bauen. Irgendwann war es dann so weit…

Wie so häufig habe ich angefangen, ohne Bilder zu machen.
Also machen wir das wie in einer Kochshow: Ich habe da mal was vorbereitet… die kleine Walze:

Aber ihr Werdegang war recht analog zur großen Walze.

Weiterlesen

« Ältere Beiträge

© 2024 Ederen Barnworks

Theme von Anders NorénHoch ↑