From 100a139d01698815c4ff53776e516c5ae5f732f6 Mon Sep 17 00:00:00 2001 From: Noe Ruiz Date: Tue, 10 Dec 2024 09:00:59 -0500 Subject: [PATCH 1/4] adding code for motorized pov display project adding files for motorized pov display project --- Motorized_POV_Display/blinka.bmp | Bin 0 -> 3866 bytes Motorized_POV_Display/code.py | 135 ++++++++++++++++++++++++++++ Motorized_POV_Display/dreidel.bmp | Bin 0 -> 3128 bytes Motorized_POV_Display/nyan-xmas.bmp | Bin 0 -> 6968 bytes Motorized_POV_Display/pipesky.bmp | Bin 0 -> 9272 bytes Motorized_POV_Display/xmas.bmp | Bin 0 -> 6968 bytes Motorized_POV_Display/xmastree.bmp | Bin 0 -> 3128 bytes 7 files changed, 135 insertions(+) create mode 100755 Motorized_POV_Display/blinka.bmp create mode 100755 Motorized_POV_Display/code.py create mode 100644 Motorized_POV_Display/dreidel.bmp create mode 100755 Motorized_POV_Display/nyan-xmas.bmp create mode 100755 Motorized_POV_Display/pipesky.bmp create mode 100755 Motorized_POV_Display/xmas.bmp create mode 100755 Motorized_POV_Display/xmastree.bmp diff --git a/Motorized_POV_Display/blinka.bmp b/Motorized_POV_Display/blinka.bmp new file mode 100755 index 0000000000000000000000000000000000000000..34a0631f409abeb8d87543dc4c86ccc97cbd2ea3 GIT binary patch literal 3866 zcmc(gF;2rk5Je3VA{DfV3L!*^I71pL8tyf`I08MlqT~|h%U}Nb?93*+wiF_J zGoJnP-^@BvwvU(R!}NK>`hxo!_YLl&;R5S0e4Y)%)gA9Cfo1#f^g73_-^Y!@&FKlQ z_sx%AOu9qN`0l>g2_N^*#YJ!OzrSw15yU&m+>Ax2bBOb69OUT(vCTsQi?F(r6A)vo z$fS?rF!+li2YsyP0IqYP;f(S|YaG|4W28v}GY$vi>ZRb+E|;Y-3MZ8JTH|=0u?|Q4 z6oTZ;0gPH6Cstlww}azb^zp*Lp&UZh74q66n&OrUVdCQX{cs+ruvz02rEXKi@DUkR z24N^CwIw;2{eR13Xc~onw2VaWsOwn4^I$5hTivZ1tB5=SDu*QY_xw{(z^9KyJvzXg*2l%N0r literal 0 HcmV?d00001 diff --git a/Motorized_POV_Display/code.py b/Motorized_POV_Display/code.py new file mode 100755 index 000000000..ff87ad0d9 --- /dev/null +++ b/Motorized_POV_Display/code.py @@ -0,0 +1,135 @@ +# SPDX-FileCopyrightText: 2017 Limor Fried for Adafruit Industries +# +# SPDX-License-Identifier: MIT +# Dotstar POV Display! Can handle up to ~2300 pixel size image (e.g. 36 x 64) + +import gc +import time +from adafruit_motorkit import MotorKit +import board +import busio +import digitalio + +kit = MotorKit(i2c=board.I2C()) + +FILENAME = "nyan-xmas.bmp" +IMAGE_DELAY = 0.001 +REPEAT = True +BRIGHTNESS = 0.3 +PIXEL_DELAY = 0.003 + +dotstar = busio.SPI(board.SCK, board.MOSI) +while not dotstar.try_lock(): + pass +dotstar.configure(baudrate=44000000) + +# we'll resize this later +databuf = bytearray(0) + +led = digitalio.DigitalInOut(board.D13) +led.switch_to_output() + +def read_le(s): + # as of this writting, int.from_bytes does not have LE support, DIY! + result = 0 + shift = 0 + for byte in bytearray(s): + result += byte << shift + shift += 8 + return result + +class BMPError(Exception): + pass + +try: + with open("/" + FILENAME, "rb") as f: + print("File opened") + if f.read(2) != b'BM': # check signature + raise BMPError("Not BitMap file") + + bmpFileSize = read_le(f.read(4)) + f.read(4) # Read & ignore creator bytes + + bmpImageoffset = read_le(f.read(4)) # Start of image data + headerSize = read_le(f.read(4)) + bmpWidth = read_le(f.read(4)) + bmpHeight = read_le(f.read(4)) + flip = True + + print("Size: %d\nImage offset: %d\nHeader size: %d" % + (bmpFileSize, bmpImageoffset, headerSize)) + print("Width: %d\nHeight: %d" % (bmpWidth, bmpHeight)) + + if read_le(f.read(2)) != 1: + raise BMPError("Not singleplane") + bmpDepth = read_le(f.read(2)) # bits per pixel + print("Bit depth: %d" % (bmpDepth)) + if bmpDepth != 24: + raise BMPError("Not 24-bit") + if read_le(f.read(2)) != 0: + raise BMPError("Compressed file") + + print("Image OK!") + + rowSize = (bmpWidth * 3 + 3) & ~3 # 32-bit line boundary + + # its huge! but its also fast :) + databuf = bytearray(bmpWidth * bmpHeight * 4) + + for row in range(bmpHeight): # For each scanline... + if flip: # Bitmap is stored bottom-to-top order (normal BMP) + pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize + else: # Bitmap is stored top-to-bottom + pos = bmpImageoffset + row * rowSize + + # print ("seek to %d" % pos) + f.seek(pos) + for col in range(bmpWidth): + b, g, r = bytearray(f.read(3)) # BMP files store RGB in BGR + # front load brightness, gamma and reordering here! + order = [b, g, r] + idx = (col * bmpHeight + (bmpHeight - row - 1)) * 4 + databuf[idx] = 0xFF # first byte is 'brightness' + idx += 1 + for color in order: + databuf[idx] = int( + pow((color * BRIGHTNESS) / 255, 2.7) * 255 + 0.5) + idx += 1 + +except OSError as e: + if e.args[0] == 28: + raise OSError("OS Error 28 0.25") + else: + raise OSError("OS Error 0.5") +except BMPError as e: + print("Failed to parse BMP: " + e.args[0]) + +gc.collect() +print(gc.mem_free()) +print("Ready to go!") + +kit.motor1.throttle = 1 + +while True: + print("Draw!") + index = 0 + + for col in range(bmpWidth): + row = databuf[index:index + bmpHeight * 4] + dotstar.write(bytearray([0x00, 0x00, 0x00, 0x00])) + dotstar.write(row) + dotstar.write(bytearray([0x00, 0x00, 0x00, 0x00])) + index += bmpHeight * 4 + time.sleep(PIXEL_DELAY) + + # clear it out + dotstar.write(bytearray([0x00, 0x00, 0x00, 0x00])) + for r in range(bmpHeight * 5): + dotstar.write(bytearray([0xFF, 0x00, 0x00, 0x00])) + dotstar.write(bytearray([0xff, 0xff, 0xff, 0xff])) + gc.collect() + + if not REPEAT: + break + + time.sleep(IMAGE_DELAY) diff --git a/Motorized_POV_Display/dreidel.bmp b/Motorized_POV_Display/dreidel.bmp new file mode 100644 index 0000000000000000000000000000000000000000..6748758082cfed890165ba4d341eecdefa1c37e7 GIT binary patch literal 3128 zcmdUxu@b^C2!^BA(Fbt!&c(^mb9VPNeEz;crKP361ZYwRYc9eQYTgL3aG!YUPVYlOz+972&7Y%^gH z@_MFt4>t>ujJBEFHlBpRN1A6Vl|sHp^Wvi7@IRXOAaOjDnE43l!iAY^vxM~%41UNS zFO|e1AM;o6shlK&{ulY2fYMkJ^HrumD2|KMB%-Rw_4-$tiV(Y4TgxXhmlsMD@`)+y z-}zM|DxVLIh$UoVrpsg84nOWz-E#AEmiMm+vAdcth0OO{iI?{;B~`|+_|rd){w?@! tn@@btls7InP%*!ih&3FMb0rYYwgAxx;jHq_WTekpBNweD#Q7WMzX2Au_>TYp literal 0 HcmV?d00001 diff --git a/Motorized_POV_Display/nyan-xmas.bmp b/Motorized_POV_Display/nyan-xmas.bmp new file mode 100755 index 0000000000000000000000000000000000000000..cb0a9422ade1265e2c66081b6916d57d47a060d3 GIT binary patch literal 6968 zcmd6r!B!ka6o$KT>CTnsxKV=VxFsQqGvLCNCkZa1TLU4-cTjhP*KlT72<%A6Ly&|d z?(z^}1|%*`0KZ#*_nqpV?j{UG=~GkOx^-{W|JS`;UB$Nxv!5j4`I7nze&6x?lwX>B zOr0bX^ndiBenIiyR1-V!H+>4#qFgaA;lb$X&U?2V)}VGWWrW6fWC^8QSaCer8q#lH>MiiQ=f24CxH zFF$B6ZO`2+(oA<(9zVPPWVA2=E?Z%pw_Dk2qqH^Y^nUlH$pw#Bt|&zF6m0d;9K#Wi zqjc`gzNDZxUd8Fq@QmVzNUU@@4&wgC&AL*WWwcr6C_VOCe0K!o^VO$CYC93H)GZM( z_CQE5k~NQ8dVd|Zzcy~hvsB7;zUXnc-pw1T57uuWGigq0=h;diNWJn@nMv=%xkY6! zGElEv+f#8~2%U~?AcRIrnlh&8_Gs#`4eI0QE(e>pTrLT?5B|7yu<`x=W~do$eSzuV zal^uI7Pwn({!06bUEhr!<%0#%a3n=D?yE$go9G)D5cyFA-=v~ z?7}Jmz<*c<@V(C|5{EA%Q}4_ffb zwgn+SIXQ`uO9_4+BO69tnIra;!mSsINMQv)$LN&THyY8M3Pi2LZ)?)LjcpEf{NE z+m?Cst^wOh9yO)h@$oThPK}rHP`S_%wzge+hF!Cc4^GbHI z;|Y^jU#Uz@_a~?O)ILQ_$HNgTv2SqyEFc7DW;Wd?%_hRV5~vcmZb|S-CujN;Z;l~o z9V#6G!y-3_Lx3CH<1W!>Moxpft9EdDv0_&+Kk>>~OA$McA)gxG=5R3MsUwsP(p2Ze zpJ!i|j#9E@th&}obKI~O%uQ8KBJ(USK(g) zmYHGZ^i1(0y))KV2MF&Od(-d=4KJ7Hp@$E*t@%a!#|?oCI7x}-V98*-%n9>cSS4P6 z-XH!qAm+tkBR_;B+8CSnM)h78xbqFP%QomG?2R;)hkU91+^djTyh7|M1E)MZADj#J z)?rmy*F1D3BPp95|Ce4rN@;d)BIso0nj$>A&Rou?2-vP5cBX1^DKkbEM`2IxnyJ^# z4Ca@mNA^4Qr6M@w1^!Ub*rhDLQ7T2l**?3`z?vc!Tu6OyxtzRg*~5P`6fdP8OouOB zo^%=OwsC*-jm0Z7zEs2l7-FQm*t;ygLK)YWk5Golvr$4bPO}M-^=oOfedzrcBl*6n literal 0 HcmV?d00001 diff --git a/Motorized_POV_Display/pipesky.bmp b/Motorized_POV_Display/pipesky.bmp new file mode 100755 index 0000000000000000000000000000000000000000..de986ff9cfcdfd3709092f4626618599dc4fa519 GIT binary patch literal 9272 zcmeH}J$4i^5QGO(B8VJrK)?xjkdku(C*)j(s}K_U8eD-R5SmY0p4zsg(Q0P34?mCR zY4uvIQgwCBkNxHAr}xwG`pEo&-#2~-ey^q*=4pD({<}B&9TQA%Z~rg|e*ONdSs5)2 zV5!U!-ly8IwX_@XV+FWh0=p5DZk&M9aVx_c(1yiRLJq_aC!{F^TeE_4=@uGzPW8aV zpm{icI3Z1Oxoa)Y&Yk#9n9B{vUrs2)Ws%sJJ$yT|pcCH-queMN+jKSrL}A44NJqRB zjJbh#l{SpsRkW+{k~dZWeMzv$S!%coXB<@V-gQugt)*RycXfix1;F4NM6Amtw2Zfd zOck%Z9QG*!iBx6-t&W(m&EKPQ6`{ndUz02F42D=U0a883d?$<}8e{QRa#rVB0XO$| zJ>&kzcbtjH>1SFpbFq89;kv0-7*sD+MTI?a$&mHcLsC^D9=4vPKe4aOBJ~@S%J@EN zEA#n(JwK|8Hs3GFBOhBJRu?g;4D+L8@m?695~}DUB(1?o0_#x~VXiSpc@*_PLo6q4 zQYA_8puvJMgY54MDzU|i$}l&0lG+&%&kl?wLmk;1`H)o+GA5I_!us}_~WzT7B~1K`6=%1%Q{bIXSG9gmdcfJ-O`_=q+9=4{tNrE&XQ+I=izWj z4a^ryF6ktg)030c7J%W5MlAi1xu!o$eN}ambVp^79iipab?vHdCGhfp;AJ^y8mIcV z%vJ{dB>l)GXKHSpa&3$Ht3Pq%HgmA)#h=r&Qj2!t505u*am|2MZa?Pe_3wYn^htc; zAB}6sqw%vY?d`ECeXd({_nDV1y@tzw(|59!`-3w_bMWWo;n6ctey(4f$=(hONuC_9 V6zu-BsyeXSKUGyXo=tL^{sAp^apnL3 literal 0 HcmV?d00001 diff --git a/Motorized_POV_Display/xmas.bmp b/Motorized_POV_Display/xmas.bmp new file mode 100755 index 0000000000000000000000000000000000000000..fdc22fc8f693ddee7e560b4de817983a78a7f82c GIT binary patch literal 6968 zcmeH|u}TCn5QbM4sN=;ZloC}QAhZV&MlU%Sf_H)6o@5uQ05Ib)zvXH`LiriFO#D!IgW>|En&i=rF z@X&8!l%-r)E@%qEfid?FnMGs&@=#g9B_^P2LZl@rjs%*o4g^iV%i%{k>TL8;jWcP8 zc<6M9$|mPRRm`GswA!L1&~*PL$SzmCoNrd26)27bS-oH2Bof2sT(DI%f6X4{dh?3r zQHn;<{7bS*pf&$haG?g!HLs+tVG$SOaNM?}CT@qyRk}H2ykDg?Ec#^!4q^xX0XMNq AegFUf literal 0 HcmV?d00001 diff --git a/Motorized_POV_Display/xmastree.bmp b/Motorized_POV_Display/xmastree.bmp new file mode 100755 index 0000000000000000000000000000000000000000..a10f439e295ed43257e9e0f88f7df605c7ccc3d3 GIT binary patch literal 3128 zcmcJR%T7~K6o%2Mjtor%T4{UQ({lH?y`gokX`aHH?bzsiPyf{5)0aI1&*M+#dj}^2MqCRG(+%aL5|53lQM`h6x0XGw z&!uibR=yCq2!7VC4D44PK~eQT2<09EWm~`)4(bZOE#=dR=X&vFPwP@g>u#|NVlz$9$VGe^lSq5grzYg1 zw27Pf$a&e8G9r}hGZY(vb0PsJU2;Lj=)#L<6l3V*U`bd`4$DLYUxdQ{J3*KJRy9w& zI?kfNiB-pKBE^+4Sp~46g~&O}jNX>i+SC5mZWoga9j;4ojXSYgimE!ZruT)RFmt`| zj?~hRt4cR9)QfEp0n?ie4sWD^g-8H{W}LWaqDU>pU}0(XQ5r-^WQ3~7 zrEOXTOZ)c$i&7Mf3KwlA({2FPFs$dhWkV?sp`>8w)R~#l=~@~V{WI#VaPXmEe>RL! z>QFT)1*_syfzYDb0w~yVHpKxrDWoGl8!GyP95fTKU~MU{>;em9Eza;kwl$$zpu8C! zQ@j?7JLzkGrqOkV&$haaA0QhGJ)#B?#6LbP%N2$tv7zpr1AK7E0+8*)3i%v&ml6UCU2s7>4y`Qm)Ur})ICdMo(-qAmJB!HK;% z(^(r$xMg69_$P-&X~;%9!@QCuFPl0)8IvQ5$rfCh=C~_0YZ-H-HsR)FupS4_m1Dpw ziR!diZ;{fd7QckfN%Xg-8%Ze6gRK`FSIkH!vFvP literal 0 HcmV?d00001 From e4b7ff5e0e38dce802f165dda16b8178008e6053 Mon Sep 17 00:00:00 2001 From: Noe Ruiz Date: Tue, 10 Dec 2024 09:08:32 -0500 Subject: [PATCH 2/4] code pylint update attempting to fix the pylint error --- Motorized_POV_Display/code.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Motorized_POV_Display/code.py b/Motorized_POV_Display/code.py index ff87ad0d9..47908dbcf 100755 --- a/Motorized_POV_Display/code.py +++ b/Motorized_POV_Display/code.py @@ -99,8 +99,6 @@ class BMPError(Exception): except OSError as e: if e.args[0] == 28: raise OSError("OS Error 28 0.25") - else: - raise OSError("OS Error 0.5") except BMPError as e: print("Failed to parse BMP: " + e.args[0]) From 122daa320c3ede6f37c0c68a5d6ebd8153f56040 Mon Sep 17 00:00:00 2001 From: Noe Ruiz Date: Tue, 10 Dec 2024 09:12:49 -0500 Subject: [PATCH 3/4] second pylint fix second attempt at fixing pylint error --- Motorized_POV_Display/code.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Motorized_POV_Display/code.py b/Motorized_POV_Display/code.py index 47908dbcf..98ef74703 100755 --- a/Motorized_POV_Display/code.py +++ b/Motorized_POV_Display/code.py @@ -96,12 +96,6 @@ class BMPError(Exception): pow((color * BRIGHTNESS) / 255, 2.7) * 255 + 0.5) idx += 1 -except OSError as e: - if e.args[0] == 28: - raise OSError("OS Error 28 0.25") -except BMPError as e: - print("Failed to parse BMP: " + e.args[0]) - gc.collect() print(gc.mem_free()) print("Ready to go!") From a27d5f2e5d2d2d9cf6e0259d118a3c29de9724b8 Mon Sep 17 00:00:00 2001 From: Noe Ruiz Date: Tue, 10 Dec 2024 09:18:24 -0500 Subject: [PATCH 4/4] third pylint fix third attempt at fixing pylint error --- Motorized_POV_Display/code.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Motorized_POV_Display/code.py b/Motorized_POV_Display/code.py index 98ef74703..49e113b74 100755 --- a/Motorized_POV_Display/code.py +++ b/Motorized_POV_Display/code.py @@ -96,6 +96,9 @@ class BMPError(Exception): pow((color * BRIGHTNESS) / 255, 2.7) * 255 + 0.5) idx += 1 +except BMPError as e: + print("Failed to parse BMP: " + e.args[0]) + gc.collect() print(gc.mem_free()) print("Ready to go!")