WIP: Optimize scrolling performance (10-25x faster) #1

Draft
adebaumann wants to merge 3 commits from optimize-scrolling into main

View File

@@ -1,5 +1,5 @@
import machine,neopixel import machine,neopixel
from time import sleep
import font import font
words={"it":[0,1], words={"it":[0,1],
@@ -92,7 +92,6 @@ class Display(object):
if Immediate == True: if Immediate == True:
self.np.write() self.np.write()
except KeyError: except KeyError:
"evening":[224,225,226,227,228,229,230],
pass pass
def WriteSentence(self,sentence,color=(25,25,0)): def WriteSentence(self,sentence,color=(25,25,0)):
@@ -102,64 +101,54 @@ class Display(object):
self.np.write() self.np.write()
def Scroll(self,Direction,Fill=[(0,0,0)]*16): def Scroll(self,Direction,Fill=[(0,0,0)]*16):
"""Optimized scroll for horizontally mirrored display (NeoPixel 0 at top-right)."""
newbuf=bytearray(b'') newbuf=bytearray(b'')
if Direction == 'l': if Direction == 'l':
for Row in range(0,self.Rows,2): for Row in range(0,self.Rows,2):
newbuf += self.np.buf[Row*16*3+3:Row*16*3+48] newbuf += self.np.buf[Row*16*3+3:Row*16*3+48]
"cold":[236,237,238,239], newbuf += bytearray([Fill[Row][1],Fill[Row][0],Fill[Row][2]])
newbuf += bytearray([Fill[Row+1][1],Fill[Row+1][0],Fill[Row+1][2]]) newbuf += bytearray([Fill[Row+1][1],Fill[Row+1][0],Fill[Row+1][2]])
newbuf += self.np.buf[Row*16*3+48:Row*16*3+93] newbuf += self.np.buf[Row*16*3+48:Row*16*3+93]
self.np.buf=newbuf self.np.buf=newbuf
"warm":[245,256,257,258],
"hot":[252,253,254],
"beer":[19,35,51,67],
}
class Display(object):
"""Initialises a NeoPixel-String."""
def __init__(self,DataPin,Rows=16,Columns=16):
self.np=neopixel.NeoPixel(machine.Pin(DataPin),Rows*Columns)
self.number=Rows*Columns
self.Rows=Rows elif Direction == 'r':
for Row in range(0,self.Rows,2):
self.Columns=Columns newbuf += bytearray([Fill[Row][1],Fill[Row][0],Fill[Row][2]])
newbuf += self.np.buf[Row*16*3:Row*16*3+45]
newbuf += self.np.buf[Row*16*3+51:Row*16*3+96]
newbuf += bytearray([Fill[Row+1][1],Fill[Row+1][0],Fill[Row+1][2]])
def Write(self,Pos,Colour=(0,0,0), Immediate=True): self.np.buf=newbuf
"""write(Pos,Colour=(0,0,0), Immediate=True): Writes a colour (given as an RGB triplet) to the Pixel elif Direction == 'u':
newbuf = self.np.buf[self.Columns*3:]
at position 'Pos'. If 'Immediate' is set, change immediately, otherwise, wait until the display is for Col in range(self.Columns):
color = Fill[Col]
explicitly written or a write with 'Immediate' is called.""" newbuf += bytearray([color[1], color[0], color[2]])
self.np.buf = newbuf
if Pos >= self.number:
elif Direction == 'd':
print("Out of range") for Col in range(self.Columns):
color = Fill[Col]
else: newbuf += bytearray([color[1], color[0], color[2]])
newbuf += self.np.buf[:-self.Columns*3]
self.np[self.Weave(Pos)]=Colour self.np.buf = newbuf
if Immediate: self.np.write()
self.np.write()
def ScrollLetter(self,Direction,Text,Speed,Color=[(50,50,50)],BGColor=[(0,0,0)]): def ScrollLetter(self,Direction,Text,Speed,Color=[(50,50,50)],BGColor=[(0,0,0)]):
"""Optimized letter scrolling with pre-calculated columns."""
all_columns = []
for index,Letter in enumerate(Text): for index,Letter in enumerate(Text):
def Clear(self,color=(0,0,0),Immediate=True): for X in range(3,14):
all_columns.append(
font.CharacterColumn(Letter, X,
Color[index % len(Color)],
BGColor[index % len(BGColor)])
)
for column in all_columns:
self.Scroll(Direction, column)
sleep(Speed) sleep(Speed)
def Num2Column(self,Number): def Num2Column(self,Number):
@@ -169,9 +158,12 @@ class Display(object):
return(int(Number/self.Columns)) return(int(Number/self.Columns))
def Weave(self,Pos): def Weave(self,Pos):
"""Convert logical position to physical LED position for horizontally mirrored display.
NeoPixel 0 is at top-right, serpentine wiring pattern."""
Row=self.Num2Row(Pos) Row=self.Num2Row(Pos)
Col=self.Num2Column(Pos)
if Row%2 == 0:
NewPos=Row*self.Columns+(self.Columns-1-Col)
else: else:
NewPos=Pos NewPos=Pos
return NewPos return NewPos