Posts by Andreas

    Hi jar,


    das Auto hat neben einem Kennzeichen auch eine Straßenzulassung, aktuellen Aufkleber eines zugelassenen technischen Überwachungsvereins. Es gehört aber nicht mir...


    Das Auto fährt an ausgewählten Tagen ohne weitere Zugmaschinen vor... und zieht auf die gleiche Weise auch wieder von dannen.



    Beste Grüße


    Andreas

    Hallo zusammen,


    nee, soll kein Wiederbeleben von Forentreffs der Jahre 2016 & 2017 werden.


    Es hat sich sehr viel in Schmidhofen getan. Ja, man kann sagen, städtische Komponenten haben Einzug gehalten.


    Wir haben jetzt zwar immer noch keine Feuerwehr im Ort. Aber es gibt ein Feuerwehrauto.



    Ist alles dran: Die alphanumerischen Zeichen deuten auf Feuerwehr hin. Die Farbe rot wie bei den großen Löschtrupps. Ne Sirene auf'm Dach. Das Auto fährt auch, denn es ist nämlich nur werktags an ausgewählten Tagen in Schmidhofen anzutreffen. Aber dann immer an der gleichen Stelle.

    Ach, es ist noch eine Anhängerkupplung vorhanden, um den Anhänger mit 'nem Küppel Löschwasser um die Ecke zu karren. Klein, fein, funktional. So oft brennt's ja nun auch nicht in Schmidhofen.


    Schmidhofen ist klein und ausgewachsen. Das Feuerwehrauto ist klein und wächst bestimmt noch.


    Beste Grüße


    Andreas

    Hallo Wend,


    gehe mal davon aus, dass Dein Sensor untauglich sein wird.


    Partikel von 10 Mikrometer sinken in unen ohne nennenswerte Belüftung in kurzer Zeit auf den Boden und entziehen sich dadurch der Messung. Was aber als 10 Mikrometer angezeigt wird, ist die Summe aller Partikel im Bereich 2.5 < x < 10 Mikrometer.


    Die potentiell infektiösen Mikrotröpfchen liegen bei < 1 Mikrometer und steigen nach oben und bleiben dort.


    Und bedenke noch, dass ein Partikelsensor auch auf feuchte Materialien anschlägt, z.B. nasse Textilien, also keine Relevanz für Deine Messung.


    Beste Grüße


    Andreas

    Hallo wend,


    ich nutze dafür das Kernstück eines handelsüblichen Partikelsensors, der von 0.3 bis 10 Mikrometer Partikel zählt. Das Teil verfügt über eine Saugvorrichtung und einen Laser zur Partikelanregung etc.


    Das Problem einer Bastellösung besteht darin, einen definierten Volumenstrom zu erzeugen, um den Messwert auf ein Volumen hochzurechnen.


    Wenn Dein Sensor keine Partikel unter 2.5 Mikrometer auflösen kann, dann nutzt er Dir bei der Messaufgabe nicht.


    Beste Grüße


    Andreas

    Hallo zusammen,


    ich biete mal an:




    Ausgabe:

    Code
    125.0
    85.0
    25.0625
    10.125
    0.5
    0.0
    -0.5
    -10.125
    -25.0625
    -55.0

    (sind die Beispiele aus dem Datenblatt).


    Beste Grüße


    Andreas

    Hallo Düsentrieb,


    Hallo,

    ich versuche verzweifelt auch im Minusbereich zu messen.

    Hat jemand dafür eine Lösung?

    ja, ich habe eine Lösung.


    Für ein Projekt musste ich bis -80 °C Temperaturen recht genau messen können. Ich habe nach einiger Recherche Tieftemperatursensoren erworben, die bis -200 °C linear arbeiten. Vertrauend darauf, dass der Temperaturkoeffizient von -200 bis + 150 °C konstant sein soll (lt. Datenblatt), habe ich diesen im Temperaturbereich 100 bis 30 °C mittels Blockkalibrator bestimmt und bei tiefen Temperaturen mit CaCl2 * 6 H20 - Eis (-50 °C) und Trockeneis-Ethanol (-72 °C) verifiziert. Demnach kann ich in diesen Bereichen mit weniger als 0,15 °C Abweichung messen.

    Leider komme ich an Flüssigstickstoff nicht heran, um bei -196 °C verifizieren zu können.


    Reicht Dir das?


    Beste Grüße


    Andreas

    Hallo zusammen,


    bei der Suche nach was ganz anderem bin ich auf folgende Pipe gestoßen:


    Code
    dmesg | tail | awk '$3 == "sd" {print}'

    Diese Pipe liefert die Zeilen von dmesg, die entstehen, wenn eine SD-Karte als externes Medium eingelegt wird.


    Und


    Code
    dmesg | tail | awk '$3 == "sd" {print$4}'

    verrät dann den Device-Namen z.B. [sdc]



    Beste Grüße


    Andreas

    Hallo zusammen,


    in letzter Zeit habe ich einiges programmiert, bei dem die typischen Stapelverarbeitungen First in - First out und First in - Last out / Last in - First out zum Einsatz kamen.


    Das geht in Icon natürlich auch beliebig einfach:


    Hierfür gibt es 5 Funktionen:

    • put(L, x) fügt der Liste L ein weiteres Element x mit neuem höchsten Index zu. Alle in der Liste enthaltenen Elemente behalten Ihren Index.
    • push(L, x) fügt der Liste L ein weiteres Element mit dem neuen Index 1 zu. Alle vorher vorhandenen Elemente x erhalten einen um 1 höheren Index.
    • x := pull(L) entfernt das Element x mit dem höchsten Index.
    • x := get(L) bzw. x := pop(L) entfernen das Element x mit dem Index 1.


    Somit ermöglichen dann folgende Funktionspaare die entsprechenden Stapelverabeitungen:


    StapelverarbeitungHinzufügenHerausnehmen
    FIFOput()get(), pop()
    push()pull()
    LIFOput()pull()
    push()get(), pop()


    Beste Grüße


    Andreas

    Hallo zusammen,

    Icon bietet wohl auch eine Möglichkeit dynamisch eine C-Funktion aus einer Bibliothek zu laden, aber da müssen die C-Funktionen bestimmten Anforderungen genügen, so dass man nicht einfach irgendwelche C-Funktionen aufrufen kann. Da müsste man sich also eine kleine C-Bibliothek mit der Funktionalität schreiben, die man dann einbinden kann.


    Mit bash ist da leider Essig :no_sad: Aber Icon kann das wohl ...


    Ja, ist in Icon relativ einfach. In den Tutorial-Teilen 30 wird die Verwendung von in C geschriebenen Libraries vorgestellt. In Teil 31 analog um in C++ geschriebene Libraries. Und im Teil 32 geht es um die Kommunikation von Icon (& Unicon) mit Code, der in D, Lazarus/FreePascal, Cobol, Prolog und ARM-Assembler.


    Allen gemeinsam ist, dass eine "fremdsprachige" Funktion seitens Icon dynamisch oder statisch geladen wird, Argumente ganz normal in die "fremdsprachige" Funktion übertragen werden. Da Icon keine richtigen Datentypen hat, muss dann in der "fremdsprachigen" Funktion angegeben werden, welchem Datentyp das in der "Fremdsprache" entspricht. Ńach Ablauf erfolgt dann eine Rückwandlung des Ergebnisses nach Icon, um das Ergebnis in Icon nutzen zu können.

    Werden keine Argumente übergeben, dann kann man sich da entsprechend Code sparen. Das Gleiche gilt dann auch für die Rückgabe von Ergebnissen.


    Beste Grüße


    Andreas

    Hallo framp,


    es gibt in Icon eine Datei "regexp.icn" (in ipl/gprocs) zum Einbinden in eigene Projekte, die laut Beschreibung


    Quote

    Procedure for regular-expression pattern matching

    enthält.

    Mit 831 Zeilen scheint das Ding auch recht mächtig zu sein.

    Ein Demo-Code befindet sich in /ipl/progs/igrep.icn.


    Das, was ich vorhin in Beitrag #75 gebracht habe, hat mit Regex so gar nichts zu tun. Das ist das "normale" String-Scanning von Icon.



    Beste Grüße


    Andreas

    Hallo zusammen,


    viele meiner Funktionen haben folgenden generellen Aufbau:



    Bei der Benennung der Argumente orientiere ich mich an den üblichen Icon-Vorgaben des Datentyps bzw. der Bedeutung als Argument der entsprechenden Funktion.


    Die obige Struktur hat den Vorteil, dass man sich auf das Wesentliche - das Programmieren der eigentlichen Aktion konzentrieren kann. Der Rest macht man irgendwie wie im Tran.

    Der Nachteil ist, dass man sich einen Wolf sucht, wenn man mal vergessen hat, z.B. den Zeichensatz für einen Alarm oder eine Systemmeldung zurückzusetzen, und alle weiteren Ausgaben auf der GUI in einem unpassenden Stil erfolgen.


    Viel einfacher geht das bei Verwendung eines Stapelspeichers STACK, der mit STACK := [] oder STACK := list() angelegt wurde.


    Eine Funktion sieht dann z.B. so aus:



    Code-Deutung:


    Die Zeile put(STACK, Font(), Fg(), Bg()) speichert den vorher verwendeten Zeichensatz, Vordergrundfarbe, Hintergrundfarbe auf diesen Stapelspeicher STACK.

    STACK[1] enthält den Zeichensatz, STACK[2] die Vordergrundfarbe etc.



    Die Zeile every i := 1 to *STACK do i(Bg, Fg, Font)(pull(STACK)) macht das dann wieder rückgängig. Hier habe ich die Funktion pull() verwendet, die - beginnend mit dem zuletzt mit put()auf den Stapel gebrachten Eintrag - den Stapel abräumt. Prinzipiell wären auch die anderen beiden Funktionen get() und pop() möglich gewesen. Dann müsste aber entweder in put() oder in der unteren Funktion die Reihenfolge der Parameter geändert werden, um FIFO, FILO / LIFO abzubilden.


    Was hier mit i(...)(...) sehr strange aussieht, nennt sich in Icon "mutual evaluation". Damit ist eine extreme Einsparung an Code verbunden.

    Ganz allgemein besteht dies aus einem Ausdruck, der ein ganzzahliges Ergebnis liefert, einer in Klammern stehenden Auflistung an "Angeboten", was getan werden könnte (also weitere Ausdrücke, Funktionen oder Variablen) und - sollten leere Funktionsnamen aufgeführt sein - dann folgen deren Parameter in einem weiteren Klammerpaar.

    Bei dem i ist das leicht durchschaubar, da dies die Schleifenvariable ist, die von 1 bis 3 laufen soll.

    Dieses ganzzahlige Ergebnis bildet nicht den Funktionsnamen sondern den Index, unter dem aus der nachfolgenden Aufzählung etwas ausgewählt werden soll. Bei i = 1 wird also der erste Eintrag herangezogen, also Bg. Hier könnte ein weiterer auswertbarer Ausdruck stehen, eine Variable, eine Funktion oder was auch immer. Hier steht also Bg, was eigentlich die Funktion für das Setzen der Hintergrundfarbe für kommende Zeichenfunktionen darstellt. Wenn es sich um eine Funktion handeln sollte, müssen danach auch Parameter in Klammern () angeboten werden. OK - Klammern folgen da auch noch. Die Argumente werden vom zuvor beschriebenen Stack geholt. Es handelt sich also tatsächlich um die Abwicklung der Icon-Funktion Bg().


    Bei i = 2 wird Analoges für den zweiten Index, also Fg und bei i = 3 für den drittem Index Font() durchgeführt.


    Am Ende ist der Stapel leer, egal, ob man ausreichend Funktionen bereitgestellt hat oder nicht und die betrachteten Einstellungen sind wieder so wie vorher.


    Ich mag "mutual evaluation", weil hier in einer Zeile stehen kann, was sonst in einer Fallunterscheidung geklärt werden muss.



    Beste Grüße


    Andreas

    Hallo __blackjack__,


    Icon's String-Scanning wäre in der Tat der nächste Ansatz gewesen - man braucht aber gar nicht so tief einzusteigen, da ein simples


    Code
    s := piper("ip -4 a s wlan0 | grep inet")
    suchvon := "inet "
    suchbis := "/"
    ergebnis := s[find(suchvon, s)+*suchvon:find(suchbis, s)]

    die reine IP-Adresse liefert.


    Aber da Du Icon's String-Scanning angesprochen hast - damit geht es natürlich auch:


    Code
    s := piper("ip -4 a s wlan0 | grep inet")
    suchvon := "inet "
    suchbis := "/"
    ergebnis := (s ? { tab(find(suchvon) + *suchvon) & tab(find(suchbis))})


    Oder kürzer, hübscher und mehr Icon-Style:

    Code
    write(s ? {tab(many(&letters ++ ' ')) & tab(many(&digits ++ "."))})

    Code-Deutung:

    In der Variablen s befindet sich das Ergebnis der Pipe


    Code
    ip -4 a s wlan0 | grep inet

    Die Funktion piper() liefert entweder

    • das Ergebnis &fail (wenn die Pipe kein Ergebnis geliefert hat; nachfolgende Funktionen, die ein solches Ergebnis verwenden, werden ohne weitere Prüfung nicht aufgerufen)
    • eine Zeichenkette (wenn die Pipe nur eine einzige Zeil geliefert hat)
    • eine Liste (wenn die Pipe mehrere Zeilen geliefert hat)


    Also etwas wie "inet 192.168.2.119/24 brd 192.168.2.255 scope global wlan0".


    Mit dem (binären) Operator Scanning-Operator ? wird das String-Scanning losgetreten. Links davon befindet sich die Zeichenkette, die in das String-Scanning eingekippt wird. Rechts davon befindet sich die sog. Matching Function. Die ersten Zeichen der Zeichenkette, die aus Elementen der Menge der Buchstaben (Schlüsselwort &letters) bestehen, vereinigt (mittels Operator ++) mit der Menge der Zeichen "Leerzeichen", werden übersprungen (Funktion many()) und an diese Stelle gesprungen (Funktion tab()).

    Ab dort sollen so viele Zeichen wie möglich (ausgedrückt durch die Funktion many() genommen werden, solange diese in der Menge der Ziffern (Schlüsselwort &digits) vereinigt mit der Menge der Zeichen "Punkt" enthalten sind. Ab der Stelle (ausgedrückt durch die Funktion tab()), an der das erste Zeichen außerhalb dieser Vereinigungsmenge enthalten ist, wird der Rest der Zeichenkette verworfen.

    Übrig bleibt somit eine Zeichenkette übrig, die mit der ersten Ziffer (oder Punkt) beginnt, und mit der letzten Ziffer (oder Punkt) endet, ohne dass Zeichen enthalten sind, die weder Ziffern noch Punkte sind.


    Beste Grüße


    Andreas

    Hallo hyle,


    hostname knallt Dir nur eine Liste von IP-Adressen im IP4v und IP6v-Format vor den Latz. Es bleibt vollkommen offen, was jetzt WLAN oder LAN oder WWAN oder ... ist.


    Beste Grüße


    Andreas

    Hallo Lutz,


    was sagt ip -Vbzw. apt-cache policy iproute2


    dieses:

    Code
    $ip -V
    ip utility, iproute2-ss131122


    und dieses:

    Code
    $apt-cache policy iproute2
    iproute2:
      Installiert:           3.12.0-2ubuntu1.2
      Installationskandidat: 3.12.0-2ubuntu1.2
      Versionstabelle:
     *** 3.12.0-2ubuntu1.2 0
            500 http://de.archive.ubuntu.com/ubuntu/ trusty-updates/main amd64 Packages
            100 /var/lib/dpkg/status
         3.12.0-2 0
            500 http://de.archive.ubuntu.com/ubuntu/ trusty/main amd64 Packages



    Beste Grüße


    Andreas

    Hallo Ihr Unermüdlichen,


    bei mir kommt bei bei Verwendung von ip -br ...  eine Fehlermeldung...

    Code
    Option "-br" is unknown, try "ip -help".


    Mir gefällt die Regex-Sache(*) von framp irgendwie ganz gut... und habe mal versucht das moderne "ip" mit dem Regex-Ansatz zu kreuzen:


    Code
    ip -4 a s wlan0 | grep inet | grep -o -E "([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}" | head -n 1

    liefert exakt die gewünschte IP-Adresse.

    Das hier auch

    Code
    ip a s dev wlan0 | grep inet | grep -o -E "([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}" | head -n 1

    Beste Grüße


    Andreas



    P.S.: Sollte ich mich auf meine alten Tage wirklich noch damit auseinandersetzen? Mein letzter Versuch mit Regex stammt aus dem Jahr 2013. Ich brauchte schlappe 2 Wochen, um die Fehlermeldung einer Programmiersprache auszuwerten, um daraus die Zeilennummer und Spalte zu erhalten, damit der Editor auf diese Textposition seinen Cursor setzen kann. Und dies nur, weil der Editor extra für diesen Zweck Regex-kompatibel war und weiterhin ist.