Eine einfache FIFO-Klasse

Hier werden einzelne Projekte mit MicroPython vorgestellt
Antworten
Heinrichs
Beiträge: 187
Registriert: Do 21. Okt 2010, 18:31

Eine einfache FIFO-Klasse

Beitrag von Heinrichs » Mi 22. Jan 2025, 21:42

FIFO steht für First-In First-Out. Unter FIFO-Registern versteht man eine Verkettung von Speicherzellen (z. B. für Bits oder Bytes) mit den folgenden Eigenschaften:
  1. Daten können in die erste Zelle "geschoben" werden; solche Daten können z. B. von Sensoren stammen.
  2. Jedesmal wenn ein Datum in die erste Zelle geschoben wird, werden die sich bereits im FIFO-Register befindlichen Daten um eine Position nach rechts geschoben.
  3. Wenn das Register aus einer festen Anzahl von Speicherzellen besteht, wird dasjenige Byte, welches als erstes in das Register geschoben wurde, in die letzte Speicherzelle geschoben. Bei einem weiteren Schiebevorgang verlässt es als erstes das Register; es kann dann weiter verarbeitet werden.
Schematisch kann das z. B. so aussehen:

Code: Alles auswählen

7  -> [0, 0, 0, 0]
19 -> [7, 0, 0, 0]
26 -> [19, 7, 0, 0]
4  -> [26, 19, 7, 0]
12 -> [4, 26, 19, 7]
33 -> [12, 4, 26, 19] -> 7
1  -> [33, 12, 4, 26] -> 19
Für die einzelnen vom Sensor stammenden Bytes bildet das FIFO-Register einen (Zwischen-)Puffer; im Englischen spricht man deswegen auch häufig von einem FIFO buffer.

Tatsächlich arbeiten inzwischen zahlreiche Sensoren (wie z. B. APDS9960 und MAX30102) mit solchen Puffern.

Einen solchen Puffer für einzelne Zahlen kann man mit Micropython leicht realisieren, indem man diese als Elemente in einer Liste ablegt. Das folgende Programm beinhaltet
  1. eine FIFO-Klasse
  2. drei mögliche Anwendungen dieser FIFO-Klasse (u. A. ein Schiebe- und ein Ringregister).
Dabei

Code: Alles auswählen

# Einfache FIFO-Klasse
# Das Register wird durch eine Liste dargestellt.


# Neue Elemente können mit der Methode in_ VON LINKS
# in das Register befördert werden; dabei wird das Register
# um einen Eintrag erweitert.

# Elemente können mit der Methode out_ VON RECHTS
# aus dem Register entnommen werden; d. h. das Register wird
# um den rechten Eintrag gemindert. Der entnommene Eintrag ist der
# Rückgabewert von out_ .

# Mit der Methode in_out wird ein Element von links in das Register
# geschoben; gleichzeitig wird ein Element aus dem Register entnommen
# und steht als Rückgabewert zur Verfügung. Die Anzahl der Elemente des
# Registers bleibt konstant.


from time import sleep
from sys import exit

class FIFO(): # erzeugt eine FIFO-Instanz mit der Liste reg
    def __init__(self, reg):
        self.reg = reg
        self.max_count = len(reg)
        print('Anzahl der Elemente:', self.max_count)

        
    def in_out(self, input): 
        output = self.reg[self.max_count-1]
        self.reg = [input] + self.reg[:-1]
        return output
    
    def in_(self, input): 
        self.reg = [input] + self.reg
        self.max_count += 1
        
    def out_(self):
        if self.max_count > 0:
            right_element = self.reg[self.max_count-1]
            self.reg = self.reg[0:-1]
            self.max_count -= 1
            return right_element
        else:
            print('Error: FIFO leer')
            exit()


# Drei Testprogramme:


# 1. FIFO nach rechts leeren   
fifo = FIFO([0,1,2,3,4,5,6,7,8,9])
print('Register:', fifo.reg)
print()

while True:
    out = fifo.out_()
    print(fifo.reg, '->', out)
    sleep(1)


'''
# 2. Schieberegister (A -> [...] -> B):  
fifo = FIFO([1,2,3,4,5])
print(fifo.reg)
print()

zaehler = 10
while True:
    print(zaehler, '->', fifo.reg)
    out = fifo.in_out(zaehler)
    print(fifo.reg, '->', out)
    print()
    zaehler +=1
    sleep(1)
'''    

'''
# 3. Ringregister
fifo = FIFO([1,2,3,4,5])
print(fifo.reg)

while True:
    out = fifo.out_()
    fifo.in_(out)
    print(fifo.reg)
    sleep(1)
'''   

Antworten