[Fortsetzung] Versuchen Sie den Zugriff auf das SPS-Register mit Python

In "Zugriff auf SPS-Register in Python versuchen" habe ich versucht, einen einfachen Wortzugriff über SLMP in Python durchzuführen. Dieses Mal werde ich die Datenmanipulation beim Lesen und Schreiben eines Bitgeräts mit Binärcode in Python implementieren.

Bit-Gerätezugriffsmethode

SLMP bietet zwei kontinuierliche Zugriffsmethoden auf Bit-Geräte.

Beim Zugriff in 1-Punkt-Einheiten handelt es sich um eine 4-Bit-BCD-Codedarstellung, wie unten gezeigt. Das Folgende ist ein Beispiel für die Kommunikation zum Zeitpunkt des Lesens.

image.png

Für den Zugriff in Einheiten von 16 Punkten ist 1 Bit eine binäre Darstellung von 1 Punkt. Das Folgende ist ein Beispiel für die Kommunikation zum Zeitpunkt des Lesens.

image.png

Natürlich sind 16-Punkte-Einheiten für das kontinuierliche Lesen und Schreiben von Massen vorteilhafter.

Der verwendete Kommunikationsbefehl ist der gleiche wie beim Zugriff auf Wörter, aber da Bitdaten wie oben beschrieben gepackt werden, ist eine Datenkonvertierung erforderlich, um sie als Array-Daten wie eine Liste in Python zu behandeln.

Dies ist ziemlich ärgerlich, und insbesondere bei 16-Punkte-Einheiten besteht die Sorge, dass sich dies auf die Verarbeitungsgeschwindigkeit in Python auswirkt, wenn Sie versuchen, Stück für Stück normal zu extrahieren. Hier implementieren wir es mit der Bitoperation von numpy.

Zugang in 1-Punkt-Einheiten

lesen

Lesen Sie mit dem Befehl Lesen (0401h) wie beim Wortzugriff. Der Unterbefehl unterscheidet sich jedoch von "0001h".

Wenn das empfangene Datenarray als "[0x00, 0x01, 0x00, 0x11, ...]" extrahiert wird, dann "[0, 0, 0, 1, 0, 0, 1, 1, ...] Muss wie `erweitert werden.

Der folgende Beispielcode erweitert die BDC-Codesequenz. Das Argument data und der Rückgabewert sind beide ndarray von numpy (dtype = uint8).

Da Array-Daten mithilfe von Numpy in einem Stapel berechnet werden können, ist keine Schleifenverarbeitung mit Python-Syntax erforderlich, und eine schnelle Verarbeitung ist insbesondere bei großen Datenmengen zu erwarten.

import numpy as np

# ex. data = np.array([0x12, 0x34, 0x56], 'u1')

def decode_bcd(data):
    """
    Decode 4bit BCD array
      [0x12,0x34,...] --> [1,2,3,4,...]
    """
    binArrayH = (data >> 4) & 0x0F
    binArrayL = data & 0x0F

    binArray = np.empty(data.size * 2, 'u1')
    binArray[::2] = binArrayH
    binArray[1::2] = binArrayL

    return binArray

Schreiben

Das Muster ist die Umkehrung des Lesens. Packen Sie den BCD-Code ein. Wenn die Originaldaten eine ungerade Zahl sind, werden die letzten 4 Bits nicht verwendet. Füllen Sie sie daher mit 0.

def encode_bcd(data):
    """
    Encode 4bit BCD array
      [1,2,3,4,...] --> [0x12,0x34,...]
Wenn die Anzahl der Eingänge ungerade ist, füllen Sie die letzten 4 Bits mit 0
    """
    binArrayH = (data[::2] & 0x0F) << 4
    binArrayL = data[1::2] & 0x0F
    binArray = np.zeros_like(binArrayH)

    if data.size % 2 == 0:
        binArray = binArrayH | binArrayL
    else:
        binArray[:-1] = binArrayH[:-1] | binArrayL
        binArray[-1] = binArrayH[-1]

    return binArray

Zugang in Einheiten von 16 Punkten

lesen

Wie beim Wortzugriff liest der Lesebefehl (0401h) und die Unterbefehle sind dieselben. Da es sich bei dem Inhalt um Wortdaten handelt, entspricht dies einem Kommunikationsbefehl.

Wie im obigen Kommunikationsbeispiel gezeigt, sind die empfangenen 4-Byte-Daten "[34h, 12h, 02h, 00h]"

[<M107>, ..., <M100>, <M115>, ..., <M108>, <M123>, ..., <M116>, <M131>, ..., <M124>]
                    ^                    ^                    ^

Es wird durch Biterweiterung zu einem Datenarray von 16 * 4 = 32 Punkten erweitert.

Das Verwirrende dabei ist, dass ** die Adressen in umgekehrter Reihenfolge pro Byte gespeichert werden **. Mit anderen Worten, im obigen Beispiel ist das LSB des ersten 1-Bytes "34h" der Wert der Startadresse, wenn der Lesebefehl gesendet wird, und der Wert der Daten, deren Adresse in Richtung des MSB inkrementiert wird. Und für das 2. Byte "12h" ist das LSB diesmal der Wert von "Startadresse +8" ...

Der folgende Beispielcode verwendet das Entpackbit von numpy, um die einzelnen Bitdaten zu einem eindimensionalen Array zu erweitern. numpy.packbits, numpy.unpackbits /reference/generated/numpy.unpackbits.html) ist eine Funktion, die ein Dezimalzahl-Binärzahl-Array konvertiert.

Wenn die Reihenfolge von LSB und MSB umgekehrt werden muss, besteht das Miso darin, dass die Reihenfolge in Spaltenrichtung umgekehrt wird, indem die Schicht angegeben wird, nachdem sie einmal in zwei Dimensionen angeordnet und die Bits erweitert wurden.

def unpack_bits(data):
    """
Erweitern Sie die in der Reihenfolge vom LSB gespeicherten Bitfolgen zu einem Array
    [<M107 ... M100>, <M115 ... M108>] --> [<M100>, ... ,<M107>, <M108>, ... ,<M115>]
    """

    #Um die Datenreihenfolge nach dem Entpacken als pseudo-zweidimensionales Array umzukehren,
    #Stellen Sie sicher, dass für jedes Byte Bitdaten gespeichert sind
    #   ex. [1,2,3] --> [[1],[2],[3]]
    byteArray2D = data.reshape((data.size, 1))

    #Bitdaten erweitern
    #   ex. [[1],[2],[3]] --> [[0,0,0,0,0,0,0,1],[0,0,0,0,0,0,1,0],[0,0,0,0,0,0,1,1]]
    byteArray2D_bin = np.unpackbits(byteArray2D, axis=1)
            
    #Kehren Sie nach dem Umkehren der Reihenfolge in Spaltenrichtung zum eindimensionalen Array zurück
    return byteArray2D_bin[:, ::-1].flatten()

Schreiben

Das Muster ist die Umkehrung des Lesens. Packt 0/1 eindimensionale Array-Daten in eine Byte-Zeichenfolge.

def pack_bits(data):
    """
Packen Sie ein Array von Bitdaten in eine Byte-Zeichenfolge, die in der Reihenfolge vom LSB gespeichert ist
    [<M100>, ... ,<M107>, <M108>, ... ,<M115>]  --> [<M107 ... M100>, <M115 ... M108>]
    """
    #Stellen Sie sicher, dass die Anzahl der Daten ein Vielfaches von 8 ist
    size8 = -(-data.size // 8) * 8

    #Geben Sie 0 ein, wenn die letzte Größe nicht ausreicht
    byteArray_bin = np.zeros(size8, 'u1')
    byteArray_bin[:size8] = data

    #In ein zweidimensionales Array konvertiert, um die Datenreihenfolge alle 8 Bits zu invertieren
    byteArray2D_bin = byteArray_bin.reshape((size8//8, 8))

    #Bitdaten packen
    return np.packbits(byteArray2D_bin[:, ::-1])

Verweise

--Mitsubishi Electric SLMP Referenzhandbuch

Recommended Posts

[Fortsetzung] Versuchen Sie den Zugriff auf das SPS-Register mit Python
Versuchen Sie den Zugriff auf das SPS-Register in Python
Versuchen Sie es mit Python.
Probieren Sie die Python-Ausgabe mit Haxe 3.2 aus
Versuchen Sie, Python mit Try Jupyter auszuführen
Versuchen Sie es mit Python + Beautiful Soup
Versuchen Sie, Facebook mit Python zu betreiben
Versuchen Sie die Singularwertzerlegung mit Python
Versuchen Sie es mit einer http-Eingabeaufforderung mit interaktivem http-Zugriff
Versuchen Sie die Gesichtserkennung mit Python + OpenCV
Versuchen Sie die Frequenzsteuerungssimulation mit Python
Versuchen Sie Python
Versuchen Sie, Farbfilme mit Python zu reproduzieren
Versuchen Sie, sich mit Python bei qiita anzumelden
Versuchen Sie eine Formel mit Σ mit Python
Versuchen Sie, Python mit Google Cloud-Funktionen zu verwenden
Versuchen Sie HTML-Scraping mit der Python-Bibliothek
Versuchen Sie, Python von Ruby aus mit Sparsamkeit aufzurufen
Versuchen Sie, eine Karte mit Python + Cartopy 0.18.0 zu zeichnen
Versuchen Sie, Python: Lambda zuzuweisen oder zu wechseln
[Für Anfänger] Versuchen Sie Web Scraping mit Python
Greifen Sie mit Python auf die Web-API zu, um IoT-Daten zu registrieren / zu erfassen (dweet.io, Requests, HTTPie).
FizzBuzz in Python3
Greifen Sie mit Python auf die Lightweight HPS-to-FPGA Bridge von Cyclone V zu
Scraping mit Python
Probieren Sie es mit Word Cloud Japanese Python JupyterLab.
Scraping mit Python
Python mit Go
Versuchen Sie, Google Chrome mit Python und Selenium auszuführen
Versuchen Sie, das Mensch-Maschine-Diagramm mit Python zu lösen
Versuchen Sie, mit Python eine Lebenskurve zu zeichnen
Twilio mit Python
In Python integrieren
Spielen Sie mit 2016-Python
Python> try: / außer:
Versuchen Sie, in Python einen "Entschlüsselungs" -Code zu erstellen
AES256 mit Python
Getestet mit Python
Versuchen Sie, Python-Dokumente automatisch mit Sphinx zu generieren
Python beginnt mit ()
mit Syntax (Python)
Versuchen Sie, mit Mongo in Python auf dem Mac zu arbeiten
[Python3] [Ubuntu16] [Docker] Versuchen Sie die Gesichtserkennung mit OpenFace
Bingo mit Python
Versuchen Sie, mit Python eine Diedergruppe zu bilden
Zundokokiyoshi mit Python
Excel mit Python
Versuchen Sie, Fische mit Python + OpenCV2.4 (unvollendet) zu erkennen.
Mikrocomputer mit Python
Mit Python besetzen
Versuchen Sie, das Programmier-Herausforderungsbuch mit Python3 zu lösen
Lassen Sie uns ein Befehls-Standby-Tool mit Python erstellen
Versuchen Sie, mit Python zu übersetzen, während Sie das PDF-Layout beibehalten
Probieren Sie einfach Amazon EMR / Cloud Dataproc mit Python aus [mrjob]
Versuchen Sie, das Problem der Zuweisung von Schulungsärzten mit Python zu lösen
Installieren Sie Selenium auf Ihrem Mac und probieren Sie es mit Python aus
Versuchen Sie, Python auf Raspberry Pi mit Visual Studio zu debuggen.
Versuchen Sie, assoziativen Speicher durch Hop-Field-Netzwerk in Python zu implementieren