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